Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8fbc42cf authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Create build settings for all product config variables" into main

parents 5dbed513 f055db60
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ bootstrap_go_package {
        "apex_conversion_test.go",
        "apex_key_conversion_test.go",
        "build_conversion_test.go",
        "bp2build_product_config_test.go",
        "bzl_conversion_test.go",
        "cc_binary_conversion_test.go",
        "cc_library_conversion_test.go",
+101 −34
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ import (
	"fmt"
	"os"
	"path/filepath"
	"reflect"
	"strings"

	"github.com/google/blueprint/proptools"
@@ -151,16 +152,17 @@ func platformMappingContent(mainProductLabel string, mainProductVariables *andro
	if err != nil {
		return "", err
	}
	result := "platforms:\n"
	result += platformMappingSingleProduct(mainProductLabel, mainProductVariables)
	var result strings.Builder
	result.WriteString("platforms:\n")
	platformMappingSingleProduct(mainProductLabel, mainProductVariables, &result)
	for product, productVariablesStarlark := range productsForTesting {
		productVariables, err := starlarkMapToProductVariables(productVariablesStarlark)
		if err != nil {
			return "", err
		}
		result += platformMappingSingleProduct("@//build/bazel/tests/products:"+product, &productVariables)
		platformMappingSingleProduct("@//build/bazel/tests/products:"+product, &productVariables, &result)
	}
	return result, nil
	return result.String(), nil
}

var bazelPlatformSuffixes = []string{
@@ -177,42 +179,107 @@ var bazelPlatformSuffixes = []string{
	"_windows_x86_64",
}

func platformMappingSingleProduct(label string, productVariables *android.ProductVariables) string {
	buildSettings := ""
	buildSettings += fmt.Sprintf("    --//build/bazel/product_config:apex_global_min_sdk_version_override=%s\n", proptools.String(productVariables.ApexGlobalMinSdkVersionOverride))
	buildSettings += fmt.Sprintf("    --//build/bazel/product_config:cfi_include_paths=%s\n", strings.Join(productVariables.CFIIncludePaths, ","))
	buildSettings += fmt.Sprintf("    --//build/bazel/product_config:cfi_exclude_paths=%s\n", strings.Join(productVariables.CFIExcludePaths, ","))
	buildSettings += fmt.Sprintf("    --//build/bazel/product_config:enable_cfi=%t\n", proptools.BoolDefault(productVariables.EnableCFI, true))
	buildSettings += fmt.Sprintf("    --//build/bazel/product_config:device_abi=%s\n", strings.Join(productVariables.DeviceAbi, ","))
	result := ""
func platformMappingSingleProduct(label string, productVariables *android.ProductVariables, result *strings.Builder) {
	targetBuildVariant := "user"
	if proptools.Bool(productVariables.Eng) {
		targetBuildVariant = "eng"
	} else if proptools.Bool(productVariables.Debuggable) {
		targetBuildVariant = "userdebug"
	}

	for _, suffix := range bazelPlatformSuffixes {
		result += "  " + label + suffix + "\n" + buildSettings
		result.WriteString("  ")
		result.WriteString(label)
		result.WriteString(suffix)
		result.WriteString("\n")
		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:always_use_prebuilt_sdks=%t\n", proptools.Bool(productVariables.Always_use_prebuilt_sdks)))
		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:apex_global_min_sdk_version_override=%s\n", proptools.String(productVariables.ApexGlobalMinSdkVersionOverride)))
		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:build_id=%s\n", proptools.String(productVariables.BuildId)))
		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:build_version_tags=%s\n", strings.Join(productVariables.BuildVersionTags, ",")))
		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:certificate_overrides=%s\n", strings.Join(productVariables.CertificateOverrides, ",")))
		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:cfi_exclude_paths=%s\n", strings.Join(productVariables.CFIExcludePaths, ",")))
		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:cfi_include_paths=%s\n", strings.Join(productVariables.CFIIncludePaths, ",")))
		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:compressed_apex=%t\n", proptools.Bool(productVariables.CompressedApex)))
		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:default_app_certificate=%s\n", proptools.String(productVariables.DefaultAppCertificate)))
		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:device_abi=%s\n", strings.Join(productVariables.DeviceAbi, ",")))
		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:device_max_page_size_supported=%s\n", proptools.String(productVariables.DeviceMaxPageSizeSupported)))
		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:device_name=%s\n", proptools.String(productVariables.DeviceName)))
		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:device_product=%s\n", proptools.String(productVariables.DeviceProduct)))
		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:enable_cfi=%t\n", proptools.BoolDefault(productVariables.EnableCFI, true)))
		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:manifest_package_name_overrides=%s\n", strings.Join(productVariables.ManifestPackageNameOverrides, ",")))
		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:platform_version_name=%s\n", proptools.String(productVariables.Platform_version_name)))
		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:product_brand=%s\n", productVariables.ProductBrand))
		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:product_manufacturer=%s\n", productVariables.ProductManufacturer))
		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:target_build_variant=%s\n", targetBuildVariant))
		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:tidy_checks=%s\n", proptools.String(productVariables.TidyChecks)))
		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:unbundled_build=%t\n", proptools.Bool(productVariables.Unbundled_build)))
		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:unbundled_build_apps=%s\n", strings.Join(productVariables.Unbundled_build_apps, ",")))
	}
	return result
}

func starlarkMapToProductVariables(in map[string]starlark.Value) (android.ProductVariables, error) {
	var err error
	result := android.ProductVariables{}
	result.ApexGlobalMinSdkVersionOverride, err = starlark_import.UnmarshalNoneable[string](in["ApexGlobalMinSdkVersionOverride"])
	productVarsReflect := reflect.ValueOf(&result).Elem()
	for i := 0; i < productVarsReflect.NumField(); i++ {
		field := productVarsReflect.Field(i)
		fieldType := productVarsReflect.Type().Field(i)
		name := fieldType.Name
		if name == "BootJars" || name == "ApexBootJars" || name == "VendorVars" ||
			name == "VendorSnapshotModules" || name == "RecoverySnapshotModules" {
			// These variables have more complicated types, and we don't need them right now
			continue
		}
		if _, ok := in[name]; ok {
			switch field.Type().Kind() {
			case reflect.Bool:
				val, err := starlark_import.Unmarshal[bool](in[name])
				if err != nil {
					return result, err
				}
				field.SetBool(val)
			case reflect.String:
				val, err := starlark_import.Unmarshal[string](in[name])
				if err != nil {
					return result, err
				}
	result.CFIIncludePaths, err = starlark_import.Unmarshal[[]string](in["CFIIncludePaths"])
				field.SetString(val)
			case reflect.Slice:
				if field.Type().Elem().Kind() != reflect.String {
					return result, fmt.Errorf("slices of types other than strings are unimplemented")
				}
				val, err := starlark_import.UnmarshalReflect(in[name], field.Type())
				if err != nil {
					return result, err
				}
	result.CFIExcludePaths, err = starlark_import.Unmarshal[[]string](in["CFIExcludePaths"])
				field.Set(val)
			case reflect.Pointer:
				switch field.Type().Elem().Kind() {
				case reflect.Bool:
					val, err := starlark_import.UnmarshalNoneable[bool](in[name])
					if err != nil {
						return result, err
					}
	result.EnableCFI, err = starlark_import.UnmarshalNoneable[bool](in["EnableCFI"])
					field.Set(reflect.ValueOf(val))
				case reflect.String:
					val, err := starlark_import.UnmarshalNoneable[string](in[name])
					if err != nil {
						return result, err
					}
	result.DeviceAbi, err = starlark_import.Unmarshal[[]string](in["DeviceAbi"])
					field.Set(reflect.ValueOf(val))
				case reflect.Int:
					val, err := starlark_import.UnmarshalNoneable[int](in[name])
					if err != nil {
						return result, err
					}
					field.Set(reflect.ValueOf(val))
				default:
					return result, fmt.Errorf("pointers of types other than strings/bools are unimplemented: %s", field.Type().Elem().Kind().String())
				}
			default:
				return result, fmt.Errorf("unimplemented type: %s", field.Type().String())
			}
		}
	}

	return result, nil
}
+88 −0
Original line number Diff line number Diff line
package bp2build

import (
	"android/soong/android"
	"android/soong/starlark_import"
	"encoding/json"
	"reflect"
	"testing"

	"github.com/google/blueprint/proptools"
	"go.starlark.net/starlark"
)

func createStarlarkValue(t *testing.T, code string) starlark.Value {
	t.Helper()
	result, err := starlark.ExecFile(&starlark.Thread{}, "main.bzl", "x = "+code, nil)
	if err != nil {
		t.Error(err)
	}
	return result["x"]
}

func createStarlarkProductVariablesMap(t *testing.T, code string) map[string]starlark.Value {
	t.Helper()
	rawValue := createStarlarkValue(t, code)
	value, err := starlark_import.Unmarshal[map[string]starlark.Value](rawValue)
	if err != nil {
		t.Error(err)
	}
	return value
}

func TestStarlarkMapToProductVariables(t *testing.T) {
	thirty := 30
	cases := []struct {
		starlark string
		result   android.ProductVariables
	}{
		{
			starlark: `{"CompressedApex": True}`,
			result:   android.ProductVariables{CompressedApex: proptools.BoolPtr(true)},
		},
		{
			starlark: `{"ApexGlobalMinSdkVersionOverride": "Tiramisu"}`,
			result:   android.ProductVariables{ApexGlobalMinSdkVersionOverride: proptools.StringPtr("Tiramisu")},
		},
		{
			starlark: `{"ProductManufacturer": "Google"}`,
			result:   android.ProductVariables{ProductManufacturer: "Google"},
		},
		{
			starlark: `{"Unbundled_build_apps": ["app1", "app2"]}`,
			result:   android.ProductVariables{Unbundled_build_apps: []string{"app1", "app2"}},
		},
		{
			starlark: `{"Platform_sdk_version": 30}`,
			result:   android.ProductVariables{Platform_sdk_version: &thirty},
		},
		{
			starlark: `{"HostFakeSnapshotEnabled": True}`,
			result:   android.ProductVariables{HostFakeSnapshotEnabled: true},
		},
	}

	for _, testCase := range cases {
		productVariables, err := starlarkMapToProductVariables(createStarlarkProductVariablesMap(t,
			testCase.starlark))
		if err != nil {
			t.Error(err)
			continue
		}
		if !reflect.DeepEqual(testCase.result, productVariables) {
			expected, err := json.Marshal(testCase.result)
			if err != nil {
				t.Error(err)
				continue
			}
			actual, err := json.Marshal(productVariables)
			if err != nil {
				t.Error(err)
				continue
			}
			expectedStr := string(expected)
			actualStr := string(actual)
			t.Errorf("expected %q, but got %q", expectedStr, actualStr)
		}
	}
}
+3 −0
Original line number Diff line number Diff line
@@ -34,6 +34,9 @@ func UnmarshalReflect(value starlark.Value, ty reflect.Type) (reflect.Value, err
		return reflect.ValueOf(value), nil
	}
	zero := reflect.Zero(ty)
	if value == nil {
		panic("nil value")
	}
	var result reflect.Value
	if ty.Kind() == reflect.Interface {
		var err error