Loading android/config.go +52 −18 Original line number Original line Diff line number Diff line Loading @@ -414,6 +414,12 @@ func saveToConfigFile(config *ProductVariables, filename string) error { return nil return nil } } type productVariableStarlarkRepresentation struct { soongType string selectable bool archVariant bool } func saveToBazelConfigFile(config *ProductVariables, outDir string) error { func saveToBazelConfigFile(config *ProductVariables, outDir string) error { dir := filepath.Join(outDir, bazel.SoongInjectionDirName, "product_config") dir := filepath.Join(outDir, bazel.SoongInjectionDirName, "product_config") err := createDirIfNonexistent(dir, os.ModePerm) err := createDirIfNonexistent(dir, os.ModePerm) Loading @@ -421,32 +427,43 @@ func saveToBazelConfigFile(config *ProductVariables, outDir string) error { return fmt.Errorf("Could not create dir %s: %s", dir, err) return fmt.Errorf("Could not create dir %s: %s", dir, err) } } nonArchVariantProductVariables := []string{} allProductVariablesType := reflect.TypeOf((*ProductVariables)(nil)).Elem() archVariantProductVariables := []string{} productVariablesInfo := make(map[string]productVariableStarlarkRepresentation) p := variableProperties{} p := variableProperties{} t := reflect.TypeOf(p.Product_variables) t := reflect.TypeOf(p.Product_variables) for i := 0; i < t.NumField(); i++ { for i := 0; i < t.NumField(); i++ { f := t.Field(i) f := t.Field(i) nonArchVariantProductVariables = append(nonArchVariantProductVariables, strings.ToLower(f.Name)) if f.Name == "Pdk" { if proptools.HasTag(f, "android", "arch_variant") { // Pdk is deprecated and has no effect as of aosp/1319667 archVariantProductVariables = append(archVariantProductVariables, strings.ToLower(f.Name)) 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 { nonArchVariantProductVariablesJson := starlark_fmt.PrintStringList(nonArchVariantProductVariables, 0) panic("Unknown variable " + f.Name) 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(` err = pathtools.WriteFileIfChanged(filepath.Join(dir, "product_variable_constants.bzl"), []byte(fmt.Sprintf(` product_var_constraints = %s # product_var_constant_info is a map of product variables to information about them. The fields are: arch_variant_product_var_constraints = %s # - soongType: The type of the product variable as it appears in soong's ProductVariables struct. `, nonArchVariantProductVariablesJson, archVariantProductVariablesJson)), 0644) # 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 { if err != nil { return fmt.Errorf("Could not write .bzl config file %s", err) return fmt.Errorf("Could not write .bzl config file %s", err) } } Loading @@ -459,6 +476,23 @@ arch_variant_product_var_constraints = %s return nil 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 // NullConfig returns a mostly empty Config for use by standalone tools like dexpreopt_gen that // use the android package. // use the android package. func NullConfig(outDir, soongOutDir string) Config { func NullConfig(outDir, soongOutDir string) Config { Loading android/module.go +11 −18 Original line number Original line Diff line number Diff line Loading @@ -1373,15 +1373,15 @@ func (attrs *CommonAttributes) fillCommonBp2BuildModuleAttrs(ctx *topDownMutator } } } } productConfigEnabledLabels := []bazel.Label{} productConfigEnabledAttribute := bazel.LabelListAttribute{} // TODO(b/234497586): Soong config variables and product variables have different overriding behavior, we // TODO(b/234497586): Soong config variables and product variables have different overriding behavior, we // should handle it correctly // should handle it correctly if !proptools.BoolDefault(enabledProperty.Value, true) && !neitherHostNorDevice { if !proptools.BoolDefault(enabledProperty.Value, true) && !neitherHostNorDevice { // If the module is not enabled by default, then we can check if a // If the module is not enabled by default, then we can check if a // product variable enables it // 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 // In this case, an existing product variable configuration overrides any // module-level `enable: false` definition // module-level `enable: false` definition newValue := true newValue := true Loading @@ -1389,10 +1389,6 @@ func (attrs *CommonAttributes) fillCommonBp2BuildModuleAttrs(ctx *topDownMutator } } } } productConfigEnabledAttribute := bazel.MakeLabelListAttribute(bazel.LabelList{ productConfigEnabledLabels, nil, }) platformEnabledAttribute, err := enabledProperty.ToLabelListAttribute( platformEnabledAttribute, err := enabledProperty.ToLabelListAttribute( bazel.LabelList{[]bazel.Label{{Label: "@platforms//:incompatible"}}, nil}, bazel.LabelList{[]bazel.Label{{Label: "@platforms//:incompatible"}}, nil}, bazel.LabelList{[]bazel.Label{}, nil}) bazel.LabelList{[]bazel.Label{}, nil}) Loading Loading @@ -1423,31 +1419,28 @@ func (attrs *CommonAttributes) fillCommonBp2BuildModuleAttrs(ctx *topDownMutator // Check product variables for `enabled: true` flag override. // Check product variables for `enabled: true` flag override. // Returns a list of the constraint_value targets who enable this 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()) productVariableProps := ProductVariableProperties(ctx, ctx.Module()) productConfigEnablingTargets := []bazel.Label{} if productConfigProps, exists := productVariableProps["Enabled"]; exists { const propName = "Enabled" if productConfigProps, exists := productVariableProps[propName]; exists { for productConfigProp, prop := range productConfigProps { for productConfigProp, prop := range productConfigProps { flag, ok := prop.(*bool) flag, ok := prop.(*bool) if !ok { 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 { if *flag { axis := productConfigProp.ConfigurationAxis() axis := productConfigProp.ConfigurationAxis() targetLabel := axis.SelectKey(productConfigProp.SelectKey()) result.SetSelectValue(axis, bazel.ConditionsDefaultConfigKey, bazel.MakeLabelList([]bazel.Label{{Label: "@platforms//:incompatible"}})) productConfigEnablingTargets = append(productConfigEnablingTargets, bazel.Label{ result.SetSelectValue(axis, productConfigProp.SelectKey(), bazel.LabelList{Includes: []bazel.Label{}}) Label: targetLabel, }) } else { } else { // TODO(b/210546943): handle negative case where `enabled: false` // 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 // A ModuleBase object contains the properties that are common to all Android Loading android/variable.go +1 −0 Original line number Original line Diff line number Diff line Loading @@ -160,6 +160,7 @@ type variableProperties struct { } } } } // Deprecated, has no effect as of aosp/1319667 Pdk struct { Pdk struct { Enabled *bool `android:"arch_variant"` Enabled *bool `android:"arch_variant"` } `android:"arch_variant"` } `android:"arch_variant"` Loading bazel/configurability.go +1 −1 Original line number Original line Diff line number Diff line Loading @@ -67,7 +67,7 @@ const ( ConditionsDefaultSelectKey = "//conditions:default" ConditionsDefaultSelectKey = "//conditions:default" productVariableBazelPackage = "//build/bazel/product_variables" productVariableBazelPackage = "//build/bazel/product_config/config_settings" AndroidAndInApex = "android-in_apex" AndroidAndInApex = "android-in_apex" AndroidPlatform = "system" AndroidPlatform = "system" Loading bp2build/apex_conversion_test.go +2 −2 Original line number Original line Diff line number Diff line Loading @@ -1555,7 +1555,7 @@ override_apex { "file_contexts": `":foo-file_contexts"`, "file_contexts": `":foo-file_contexts"`, "manifest": `"apex_manifest.json"`, "manifest": `"apex_manifest.json"`, "min_sdk_version": `select({ "min_sdk_version": `select({ "//build/bazel/product_variables:android__library_linking_strategy__prefer_static": "30", "//build/bazel/product_config/config_settings:android__library_linking_strategy__prefer_static": "30", "//conditions:default": "31", "//conditions:default": "31", })`, })`, "package_name": `"pkg_name"`, "package_name": `"pkg_name"`, Loading @@ -1564,7 +1564,7 @@ override_apex { "file_contexts": `":foo-file_contexts"`, "file_contexts": `":foo-file_contexts"`, "manifest": `"apex_manifest.json"`, "manifest": `"apex_manifest.json"`, "min_sdk_version": `select({ "min_sdk_version": `select({ "//build/bazel/product_variables:android__library_linking_strategy__prefer_static": "30", "//build/bazel/product_config/config_settings:android__library_linking_strategy__prefer_static": "30", "//conditions:default": "31", "//conditions:default": "31", })`, })`, "package_name": `"override_pkg_name"`, "package_name": `"override_pkg_name"`, Loading Loading
android/config.go +52 −18 Original line number Original line Diff line number Diff line Loading @@ -414,6 +414,12 @@ func saveToConfigFile(config *ProductVariables, filename string) error { return nil return nil } } type productVariableStarlarkRepresentation struct { soongType string selectable bool archVariant bool } func saveToBazelConfigFile(config *ProductVariables, outDir string) error { func saveToBazelConfigFile(config *ProductVariables, outDir string) error { dir := filepath.Join(outDir, bazel.SoongInjectionDirName, "product_config") dir := filepath.Join(outDir, bazel.SoongInjectionDirName, "product_config") err := createDirIfNonexistent(dir, os.ModePerm) err := createDirIfNonexistent(dir, os.ModePerm) Loading @@ -421,32 +427,43 @@ func saveToBazelConfigFile(config *ProductVariables, outDir string) error { return fmt.Errorf("Could not create dir %s: %s", dir, err) return fmt.Errorf("Could not create dir %s: %s", dir, err) } } nonArchVariantProductVariables := []string{} allProductVariablesType := reflect.TypeOf((*ProductVariables)(nil)).Elem() archVariantProductVariables := []string{} productVariablesInfo := make(map[string]productVariableStarlarkRepresentation) p := variableProperties{} p := variableProperties{} t := reflect.TypeOf(p.Product_variables) t := reflect.TypeOf(p.Product_variables) for i := 0; i < t.NumField(); i++ { for i := 0; i < t.NumField(); i++ { f := t.Field(i) f := t.Field(i) nonArchVariantProductVariables = append(nonArchVariantProductVariables, strings.ToLower(f.Name)) if f.Name == "Pdk" { if proptools.HasTag(f, "android", "arch_variant") { // Pdk is deprecated and has no effect as of aosp/1319667 archVariantProductVariables = append(archVariantProductVariables, strings.ToLower(f.Name)) 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 { nonArchVariantProductVariablesJson := starlark_fmt.PrintStringList(nonArchVariantProductVariables, 0) panic("Unknown variable " + f.Name) 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(` err = pathtools.WriteFileIfChanged(filepath.Join(dir, "product_variable_constants.bzl"), []byte(fmt.Sprintf(` product_var_constraints = %s # product_var_constant_info is a map of product variables to information about them. The fields are: arch_variant_product_var_constraints = %s # - soongType: The type of the product variable as it appears in soong's ProductVariables struct. `, nonArchVariantProductVariablesJson, archVariantProductVariablesJson)), 0644) # 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 { if err != nil { return fmt.Errorf("Could not write .bzl config file %s", err) return fmt.Errorf("Could not write .bzl config file %s", err) } } Loading @@ -459,6 +476,23 @@ arch_variant_product_var_constraints = %s return nil 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 // NullConfig returns a mostly empty Config for use by standalone tools like dexpreopt_gen that // use the android package. // use the android package. func NullConfig(outDir, soongOutDir string) Config { func NullConfig(outDir, soongOutDir string) Config { Loading
android/module.go +11 −18 Original line number Original line Diff line number Diff line Loading @@ -1373,15 +1373,15 @@ func (attrs *CommonAttributes) fillCommonBp2BuildModuleAttrs(ctx *topDownMutator } } } } productConfigEnabledLabels := []bazel.Label{} productConfigEnabledAttribute := bazel.LabelListAttribute{} // TODO(b/234497586): Soong config variables and product variables have different overriding behavior, we // TODO(b/234497586): Soong config variables and product variables have different overriding behavior, we // should handle it correctly // should handle it correctly if !proptools.BoolDefault(enabledProperty.Value, true) && !neitherHostNorDevice { if !proptools.BoolDefault(enabledProperty.Value, true) && !neitherHostNorDevice { // If the module is not enabled by default, then we can check if a // If the module is not enabled by default, then we can check if a // product variable enables it // 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 // In this case, an existing product variable configuration overrides any // module-level `enable: false` definition // module-level `enable: false` definition newValue := true newValue := true Loading @@ -1389,10 +1389,6 @@ func (attrs *CommonAttributes) fillCommonBp2BuildModuleAttrs(ctx *topDownMutator } } } } productConfigEnabledAttribute := bazel.MakeLabelListAttribute(bazel.LabelList{ productConfigEnabledLabels, nil, }) platformEnabledAttribute, err := enabledProperty.ToLabelListAttribute( platformEnabledAttribute, err := enabledProperty.ToLabelListAttribute( bazel.LabelList{[]bazel.Label{{Label: "@platforms//:incompatible"}}, nil}, bazel.LabelList{[]bazel.Label{{Label: "@platforms//:incompatible"}}, nil}, bazel.LabelList{[]bazel.Label{}, nil}) bazel.LabelList{[]bazel.Label{}, nil}) Loading Loading @@ -1423,31 +1419,28 @@ func (attrs *CommonAttributes) fillCommonBp2BuildModuleAttrs(ctx *topDownMutator // Check product variables for `enabled: true` flag override. // Check product variables for `enabled: true` flag override. // Returns a list of the constraint_value targets who enable this 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()) productVariableProps := ProductVariableProperties(ctx, ctx.Module()) productConfigEnablingTargets := []bazel.Label{} if productConfigProps, exists := productVariableProps["Enabled"]; exists { const propName = "Enabled" if productConfigProps, exists := productVariableProps[propName]; exists { for productConfigProp, prop := range productConfigProps { for productConfigProp, prop := range productConfigProps { flag, ok := prop.(*bool) flag, ok := prop.(*bool) if !ok { 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 { if *flag { axis := productConfigProp.ConfigurationAxis() axis := productConfigProp.ConfigurationAxis() targetLabel := axis.SelectKey(productConfigProp.SelectKey()) result.SetSelectValue(axis, bazel.ConditionsDefaultConfigKey, bazel.MakeLabelList([]bazel.Label{{Label: "@platforms//:incompatible"}})) productConfigEnablingTargets = append(productConfigEnablingTargets, bazel.Label{ result.SetSelectValue(axis, productConfigProp.SelectKey(), bazel.LabelList{Includes: []bazel.Label{}}) Label: targetLabel, }) } else { } else { // TODO(b/210546943): handle negative case where `enabled: false` // 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 // A ModuleBase object contains the properties that are common to all Android Loading
android/variable.go +1 −0 Original line number Original line Diff line number Diff line Loading @@ -160,6 +160,7 @@ type variableProperties struct { } } } } // Deprecated, has no effect as of aosp/1319667 Pdk struct { Pdk struct { Enabled *bool `android:"arch_variant"` Enabled *bool `android:"arch_variant"` } `android:"arch_variant"` } `android:"arch_variant"` Loading
bazel/configurability.go +1 −1 Original line number Original line Diff line number Diff line Loading @@ -67,7 +67,7 @@ const ( ConditionsDefaultSelectKey = "//conditions:default" ConditionsDefaultSelectKey = "//conditions:default" productVariableBazelPackage = "//build/bazel/product_variables" productVariableBazelPackage = "//build/bazel/product_config/config_settings" AndroidAndInApex = "android-in_apex" AndroidAndInApex = "android-in_apex" AndroidPlatform = "system" AndroidPlatform = "system" Loading
bp2build/apex_conversion_test.go +2 −2 Original line number Original line Diff line number Diff line Loading @@ -1555,7 +1555,7 @@ override_apex { "file_contexts": `":foo-file_contexts"`, "file_contexts": `":foo-file_contexts"`, "manifest": `"apex_manifest.json"`, "manifest": `"apex_manifest.json"`, "min_sdk_version": `select({ "min_sdk_version": `select({ "//build/bazel/product_variables:android__library_linking_strategy__prefer_static": "30", "//build/bazel/product_config/config_settings:android__library_linking_strategy__prefer_static": "30", "//conditions:default": "31", "//conditions:default": "31", })`, })`, "package_name": `"pkg_name"`, "package_name": `"pkg_name"`, Loading @@ -1564,7 +1564,7 @@ override_apex { "file_contexts": `":foo-file_contexts"`, "file_contexts": `":foo-file_contexts"`, "manifest": `"apex_manifest.json"`, "manifest": `"apex_manifest.json"`, "min_sdk_version": `select({ "min_sdk_version": `select({ "//build/bazel/product_variables:android__library_linking_strategy__prefer_static": "30", "//build/bazel/product_config/config_settings:android__library_linking_strategy__prefer_static": "30", "//conditions:default": "31", "//conditions:default": "31", })`, })`, "package_name": `"override_pkg_name"`, "package_name": `"override_pkg_name"`, Loading