Make bp2build-generated selects() based on product config build settings
...instead of based on constraint settings.
Bug: 269577299
Test: m nothing and ./build/bazel/ci/bp2build.sh
Change-Id: Ib9caec79c92b8fd304e46be841de5612bd1637e3
diff --git a/android/config.go b/android/config.go
index 72ff224..eb89493 100644
--- a/android/config.go
+++ b/android/config.go
@@ -414,6 +414,12 @@
return nil
}
+type productVariableStarlarkRepresentation struct {
+ soongType string
+ selectable bool
+ archVariant bool
+}
+
func saveToBazelConfigFile(config *ProductVariables, outDir string) error {
dir := filepath.Join(outDir, bazel.SoongInjectionDirName, "product_config")
err := createDirIfNonexistent(dir, os.ModePerm)
@@ -421,32 +427,43 @@
return fmt.Errorf("Could not create dir %s: %s", dir, err)
}
- nonArchVariantProductVariables := []string{}
- archVariantProductVariables := []string{}
+ allProductVariablesType := reflect.TypeOf((*ProductVariables)(nil)).Elem()
+ productVariablesInfo := make(map[string]productVariableStarlarkRepresentation)
p := variableProperties{}
t := reflect.TypeOf(p.Product_variables)
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
- nonArchVariantProductVariables = append(nonArchVariantProductVariables, strings.ToLower(f.Name))
- if proptools.HasTag(f, "android", "arch_variant") {
- archVariantProductVariables = append(archVariantProductVariables, strings.ToLower(f.Name))
+ if f.Name == "Pdk" {
+ // Pdk is deprecated and has no effect as of aosp/1319667
+ continue
+ }
+ archVariant := proptools.HasTag(f, "android", "arch_variant")
+ if mainProductVariablesStructField, ok := allProductVariablesType.FieldByName(f.Name); ok {
+ productVariablesInfo[f.Name] = productVariableStarlarkRepresentation{
+ soongType: stringRepresentationOfSimpleType(mainProductVariablesStructField.Type),
+ selectable: true,
+ archVariant: archVariant,
+ }
+ } else {
+ panic("Unknown variable " + f.Name)
}
}
- nonArchVariantProductVariablesJson := starlark_fmt.PrintStringList(nonArchVariantProductVariables, 0)
- if err != nil {
- return fmt.Errorf("cannot marshal product variable data: %s", err.Error())
- }
-
- archVariantProductVariablesJson := starlark_fmt.PrintStringList(archVariantProductVariables, 0)
- if err != nil {
- return fmt.Errorf("cannot marshal arch variant product variable data: %s", err.Error())
- }
-
err = pathtools.WriteFileIfChanged(filepath.Join(dir, "product_variable_constants.bzl"), []byte(fmt.Sprintf(`
-product_var_constraints = %s
-arch_variant_product_var_constraints = %s
-`, nonArchVariantProductVariablesJson, archVariantProductVariablesJson)), 0644)
+# product_var_constant_info is a map of product variables to information about them. The fields are:
+# - soongType: The type of the product variable as it appears in soong's ProductVariables struct.
+# examples are string, bool, int, *bool, *string, []string, etc. This may be an overly
+# conservative estimation of the type, for example a *bool could oftentimes just be a
+# bool that defaults to false.
+# - selectable: if this product variable can be selected on in Android.bp/build files. This means
+# it's listed in the "variableProperties" soong struct. Currently all variables in
+# this list are selectable because we only need the selectable ones at the moment,
+# but the list may be expanded later.
+# - archVariant: If the variable is tagged as arch variant in the "variableProperties" struct.
+product_var_constant_info = %s
+product_var_constraints = [k for k, v in product_var_constant_info.items() if v.selectable]
+arch_variant_product_var_constraints = [k for k, v in product_var_constant_info.items() if v.selectable and v.archVariant]
+`, starlark_fmt.PrintAny(productVariablesInfo, 0))), 0644)
if err != nil {
return fmt.Errorf("Could not write .bzl config file %s", err)
}
@@ -459,6 +476,23 @@
return nil
}
+func stringRepresentationOfSimpleType(ty reflect.Type) string {
+ switch ty.Kind() {
+ case reflect.String:
+ return "string"
+ case reflect.Bool:
+ return "bool"
+ case reflect.Int:
+ return "int"
+ case reflect.Slice:
+ return "[]" + stringRepresentationOfSimpleType(ty.Elem())
+ case reflect.Pointer:
+ return "*" + stringRepresentationOfSimpleType(ty.Elem())
+ default:
+ panic("unimplemented type: " + ty.Kind().String())
+ }
+}
+
// NullConfig returns a mostly empty Config for use by standalone tools like dexpreopt_gen that
// use the android package.
func NullConfig(outDir, soongOutDir string) Config {
diff --git a/android/module.go b/android/module.go
index 4c781f6..b982019 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1373,15 +1373,15 @@
}
}
- productConfigEnabledLabels := []bazel.Label{}
+ productConfigEnabledAttribute := bazel.LabelListAttribute{}
// TODO(b/234497586): Soong config variables and product variables have different overriding behavior, we
// should handle it correctly
if !proptools.BoolDefault(enabledProperty.Value, true) && !neitherHostNorDevice {
// If the module is not enabled by default, then we can check if a
// product variable enables it
- productConfigEnabledLabels = productVariableConfigEnableLabels(ctx)
+ productConfigEnabledAttribute = productVariableConfigEnableAttribute(ctx)
- if len(productConfigEnabledLabels) > 0 {
+ if len(productConfigEnabledAttribute.ConfigurableValues) > 0 {
// In this case, an existing product variable configuration overrides any
// module-level `enable: false` definition
newValue := true
@@ -1389,10 +1389,6 @@
}
}
- productConfigEnabledAttribute := bazel.MakeLabelListAttribute(bazel.LabelList{
- productConfigEnabledLabels, nil,
- })
-
platformEnabledAttribute, err := enabledProperty.ToLabelListAttribute(
bazel.LabelList{[]bazel.Label{{Label: "@platforms//:incompatible"}}, nil},
bazel.LabelList{[]bazel.Label{}, nil})
@@ -1423,31 +1419,28 @@
// Check product variables for `enabled: true` flag override.
// Returns a list of the constraint_value targets who enable this override.
-func productVariableConfigEnableLabels(ctx *topDownMutatorContext) []bazel.Label {
+func productVariableConfigEnableAttribute(ctx *topDownMutatorContext) bazel.LabelListAttribute {
+ result := bazel.LabelListAttribute{}
productVariableProps := ProductVariableProperties(ctx, ctx.Module())
- productConfigEnablingTargets := []bazel.Label{}
- const propName = "Enabled"
- if productConfigProps, exists := productVariableProps[propName]; exists {
+ if productConfigProps, exists := productVariableProps["Enabled"]; exists {
for productConfigProp, prop := range productConfigProps {
flag, ok := prop.(*bool)
if !ok {
- ctx.ModuleErrorf("Could not convert product variable %s property", proptools.PropertyNameForField(propName))
+ ctx.ModuleErrorf("Could not convert product variable enabled property")
}
if *flag {
axis := productConfigProp.ConfigurationAxis()
- targetLabel := axis.SelectKey(productConfigProp.SelectKey())
- productConfigEnablingTargets = append(productConfigEnablingTargets, bazel.Label{
- Label: targetLabel,
- })
+ result.SetSelectValue(axis, bazel.ConditionsDefaultConfigKey, bazel.MakeLabelList([]bazel.Label{{Label: "@platforms//:incompatible"}}))
+ result.SetSelectValue(axis, productConfigProp.SelectKey(), bazel.LabelList{Includes: []bazel.Label{}})
} else {
// TODO(b/210546943): handle negative case where `enabled: false`
- ctx.ModuleErrorf("`enabled: false` is not currently supported for configuration variables. See b/210546943", proptools.PropertyNameForField(propName))
+ ctx.ModuleErrorf("`enabled: false` is not currently supported for configuration variables. See b/210546943")
}
}
}
- return productConfigEnablingTargets
+ return result
}
// A ModuleBase object contains the properties that are common to all Android
diff --git a/android/variable.go b/android/variable.go
index 7fb81b9..03a80c1 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -160,6 +160,7 @@
}
}
+ // Deprecated, has no effect as of aosp/1319667
Pdk struct {
Enabled *bool `android:"arch_variant"`
} `android:"arch_variant"`