Loading android/bazel.go +14 −6 Original line number Diff line number Diff line Loading @@ -367,13 +367,21 @@ var ( "libandroid_runtime_lazy", // depends on unconverted modules: libbinder_headers "libcmd", // depends on unconverted modules: libbinder "libdexfile_support_static", // Depends on unconverted module: libdexfile_external_headers "libunwindstack_local", "libunwindstack_utils", "libc_malloc_debug", "libfdtrack", // Depends on unconverted module: libunwindstack "libdexfile_support", // TODO(b/210546943): Enabled based on product variables. "libdexfile_external_headers", // TODO(b/210546943): Enabled based on product variables. "libunwindstack", // Depends on unconverted module libdexfile_support. "libnativehelper_compat_libc++", // Broken compile: implicit declaration of function 'strerror_r' is invalid in C99 "chkcon", "sefcontext_compile", // depends on unconverted modules: libsepol "libsepol", // TODO(b/207408632): Unsupported case of .l sources in cc library rules "gen-kotlin-build-file.py", // module has same name as source "libbinder", // TODO(b/188503688): Disabled for some archs, "libactivitymanager_aidl", // TODO(b/207426160): Depends on activity_manager_procstate_aidl, which is an aidl filegroup. "libnativehelper_lazy_mts_jni", "libnativehelper_mts_jni", // depends on unconverted modules: libgmock_ndk Loading Loading @@ -434,7 +442,6 @@ var ( "linkerconfig", // http://b/202876379 has arch-variant static_executable "mdnsd", // http://b/202876379 has arch-variant static_executable "acvp_modulewrapper", // disabled for android x86/x86_64 "CarHTMLViewer", // depends on unconverted modules android.car-stubs, car-ui-lib "libdexfile", // depends on unconverted modules: dexfile_operator_srcs, libartbase, libartpalette, Loading @@ -443,9 +450,7 @@ var ( // Per-module denylist of cc_library modules to only generate the static // variant if their shared variant isn't ready or buildable by Bazel. bp2buildCcLibraryStaticOnlyList = []string{ "libjemalloc5", // http://b/188503688, cc_library, `target: { android: { enabled: false } }` for android targets. } bp2buildCcLibraryStaticOnlyList = []string{} // Per-module denylist to opt modules out of mixed builds. Such modules will // still be generated via bp2build. Loading Loading @@ -513,6 +518,9 @@ func (b *BazelModuleBase) MixedBuildsEnabled(ctx ModuleContext) bool { // Windows toolchains are not currently supported. return false } if !ctx.Module().Enabled() { return false } if !ctx.Config().BazelContext.BazelEnabled() { return false } Loading android/module.go +46 −6 Original line number Diff line number Diff line Loading @@ -869,6 +869,13 @@ type CommonAttributes struct { Data bazel.LabelListAttribute } // constraintAttributes represents Bazel attributes pertaining to build constraints, // which make restrict building a Bazel target for some set of platforms. type constraintAttributes struct { // Constraint values this target can be built for. Target_compatible_with bazel.LabelListAttribute } type distProperties struct { // configuration to distribute output files from this module to the distribution // directory (default: $OUT/dist, configurable with $DIST_DIR) Loading Loading @@ -1089,7 +1096,8 @@ func InitCommonOSAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupport m.base().commonProperties.CreateCommonOSVariant = true } func (attrs *CommonAttributes) fillCommonBp2BuildModuleAttrs(ctx *topDownMutatorContext) { func (attrs *CommonAttributes) fillCommonBp2BuildModuleAttrs(ctx *topDownMutatorContext, enabledPropertyOverrides bazel.BoolAttribute) constraintAttributes { // Assert passed-in attributes include Name name := attrs.Name if len(name) == 0 { Loading @@ -1107,14 +1115,45 @@ func (attrs *CommonAttributes) fillCommonBp2BuildModuleAttrs(ctx *topDownMutator required := depsToLabelList(props.Required) archVariantProps := mod.GetArchVariantProperties(ctx, &commonProperties{}) var enabledProperty bazel.BoolAttribute if props.Enabled != nil { enabledProperty.Value = props.Enabled } for axis, configToProps := range archVariantProps { for config, _props := range configToProps { if archProps, ok := _props.(*commonProperties); ok { required.SetSelectValue(axis, config, depsToLabelList(archProps.Required).Value) if archProps.Enabled != nil { enabledProperty.SetSelectValue(axis, config, archProps.Enabled) } } } } if enabledPropertyOverrides.Value != nil { enabledProperty.Value = enabledPropertyOverrides.Value } for _, axis := range enabledPropertyOverrides.SortedConfigurationAxes() { configToBools := enabledPropertyOverrides.ConfigurableValues[axis] for cfg, val := range configToBools { enabledProperty.SetSelectValue(axis, cfg, &val) } } data.Append(required) var err error constraints := constraintAttributes{} constraints.Target_compatible_with, err = enabledProperty.ToLabelListAttribute( bazel.LabelList{[]bazel.Label{bazel.Label{Label: "@platforms//:incompatible"}}, nil}, bazel.LabelList{[]bazel.Label{}, nil}) if err != nil { ctx.ModuleErrorf("Error processing enabled attribute: %s", err) } return constraints } // A ModuleBase object contains the properties that are common to all Android Loading Loading @@ -1236,6 +1275,7 @@ type bp2buildInfo struct { Dir string BazelProps bazel.BazelTargetModuleProperties CommonAttrs CommonAttributes ConstraintAttrs constraintAttributes Attrs interface{} } Loading @@ -1262,7 +1302,7 @@ func (b bp2buildInfo) BazelRuleLoadLocation() string { // BazelAttributes returns the Bazel attributes of a bp2build converted target. func (b bp2buildInfo) BazelAttributes() []interface{} { return []interface{}{&b.CommonAttrs, b.Attrs} return []interface{}{&b.CommonAttrs, &b.ConstraintAttrs, b.Attrs} } func (m *ModuleBase) addBp2buildInfo(info bp2buildInfo) { Loading android/mutator.go +30 −5 Original line number Diff line number Diff line Loading @@ -254,6 +254,14 @@ type TopDownMutatorContext interface { // BazelTargetModuleProperties containing additional metadata for the // bp2build codegenerator. CreateBazelTargetModule(bazel.BazelTargetModuleProperties, CommonAttributes, interface{}) // CreateBazelTargetModuleWithRestrictions creates a BazelTargetModule by calling the // factory method, just like in CreateModule, but also requires // BazelTargetModuleProperties containing additional metadata for the // bp2build codegenerator. The generated target is restricted to only be buildable for certain // platforms, as dictated by a given bool attribute: the target will not be buildable in // any platform for which this bool attribute is false. CreateBazelTargetModuleWithRestrictions(bazel.BazelTargetModuleProperties, CommonAttributes, interface{}, bazel.BoolAttribute) } type topDownMutatorContext struct { Loading Loading @@ -502,12 +510,29 @@ func (t *topDownMutatorContext) CreateBazelTargetModule( bazelProps bazel.BazelTargetModuleProperties, commonAttrs CommonAttributes, attrs interface{}) { commonAttrs.fillCommonBp2BuildModuleAttrs(t) t.createBazelTargetModule(bazelProps, commonAttrs, attrs, bazel.BoolAttribute{}) } func (t *topDownMutatorContext) CreateBazelTargetModuleWithRestrictions( bazelProps bazel.BazelTargetModuleProperties, commonAttrs CommonAttributes, attrs interface{}, enabledProperty bazel.BoolAttribute) { t.createBazelTargetModule(bazelProps, commonAttrs, attrs, enabledProperty) } func (t *topDownMutatorContext) createBazelTargetModule( bazelProps bazel.BazelTargetModuleProperties, commonAttrs CommonAttributes, attrs interface{}, enabledProperty bazel.BoolAttribute) { constraintAttributes := commonAttrs.fillCommonBp2BuildModuleAttrs(t, enabledProperty) mod := t.Module() info := bp2buildInfo{ Dir: t.OtherModuleDir(mod), BazelProps: bazelProps, CommonAttrs: commonAttrs, ConstraintAttrs: constraintAttributes, Attrs: attrs, } mod.base().addBp2buildInfo(info) Loading bazel/configurability.go +19 −0 Original line number Diff line number Diff line Loading @@ -109,6 +109,21 @@ var ( osArchWindowsX86_64: "//build/bazel/platforms/os_arch:windows_x86_64", ConditionsDefaultConfigKey: ConditionsDefaultSelectKey, // The default condition of an os select map. } // Map where keys are OsType names, and values are slices containing the archs // that that OS supports. // These definitions copied from arch.go. // TODO(cparsons): Source from arch.go; this task is nontrivial, as it currently results // in a cyclic dependency. osToArchMap = map[string][]string{ osAndroid: {archArm, archArm64, archX86, archX86_64}, osLinux: {archX86, archX86_64}, osLinuxMusl: {archX86, archX86_64}, osDarwin: {archArm64, archX86_64}, osLinuxBionic: {archArm64, archX86_64}, // TODO(cparsons): According to arch.go, this should contain archArm, archArm64, as well. osWindows: {archX86, archX86_64}, } ) // basic configuration types Loading @@ -122,6 +137,10 @@ const ( productVariables ) func osArchString(os string, arch string) string { return fmt.Sprintf("%s_%s", os, arch) } func (ct configurationType) String() string { return map[configurationType]string{ noConfig: "no_config", Loading bazel/properties.go +182 −7 Original line number Diff line number Diff line Loading @@ -244,9 +244,69 @@ type LabelAttribute struct { ConfigurableValues configurableLabels } func (la *LabelAttribute) axisTypes() map[configurationType]bool { types := map[configurationType]bool{} for k := range la.ConfigurableValues { if len(la.ConfigurableValues[k]) > 0 { types[k.configurationType] = true } } return types } // Collapse reduces the configurable axes of the label attribute to a single axis. // This is necessary for final writing to bp2build, as a configurable label // attribute can only be comprised by a single select. func (la *LabelAttribute) Collapse() error { axisTypes := la.axisTypes() _, containsOs := axisTypes[os] _, containsArch := axisTypes[arch] _, containsOsArch := axisTypes[osArch] _, containsProductVariables := axisTypes[productVariables] if containsProductVariables { if containsOs || containsArch || containsOsArch { return fmt.Errorf("label attribute could not be collapsed as it has two or more unrelated axes") } } if (containsOs && containsArch) || (containsOsArch && (containsOs || containsArch)) { // If a bool attribute has both os and arch configuration axes, the only // way to successfully union their values is to increase the granularity // of the configuration criteria to os_arch. for osType, supportedArchs := range osToArchMap { for _, supportedArch := range supportedArchs { osArch := osArchString(osType, supportedArch) if archOsVal := la.SelectValue(OsArchConfigurationAxis, osArch); archOsVal != nil { // Do nothing, as the arch_os is explicitly defined already. } else { archVal := la.SelectValue(ArchConfigurationAxis, supportedArch) osVal := la.SelectValue(OsConfigurationAxis, osType) if osVal != nil && archVal != nil { // In this case, arch takes precedence. (This fits legacy Soong behavior, as arch mutator // runs after os mutator. la.SetSelectValue(OsArchConfigurationAxis, osArch, *archVal) } else if osVal != nil && archVal == nil { la.SetSelectValue(OsArchConfigurationAxis, osArch, *osVal) } else if osVal == nil && archVal != nil { la.SetSelectValue(OsArchConfigurationAxis, osArch, *archVal) } } } } // All os_arch values are now set. Clear os and arch axes. delete(la.ConfigurableValues, ArchConfigurationAxis) delete(la.ConfigurableValues, OsConfigurationAxis) } return nil } // HasConfigurableValues returns whether there are configurable values set for this label. func (la LabelAttribute) HasConfigurableValues() bool { return len(la.ConfigurableValues) > 0 for _, selectValues := range la.ConfigurableValues { if len(selectValues) > 0 { return true } } return false } // SetValue sets the base, non-configured value for the Label Loading @@ -271,13 +331,13 @@ func (la *LabelAttribute) SetSelectValue(axis ConfigurationAxis, config string, } // SelectValue gets a value for a bazel select for the given axis and config. func (la *LabelAttribute) SelectValue(axis ConfigurationAxis, config string) Label { func (la *LabelAttribute) SelectValue(axis ConfigurationAxis, config string) *Label { axis.validateConfig(config) switch axis.configurationType { case noConfig: return *la.Value return la.Value case arch, os, osArch, productVariables: return *la.ConfigurableValues[axis][config] return la.ConfigurableValues[axis][config] default: panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis)) } Loading Loading @@ -324,7 +384,12 @@ type BoolAttribute struct { // HasConfigurableValues returns whether there are configurable values for this attribute. func (ba BoolAttribute) HasConfigurableValues() bool { return len(ba.ConfigurableValues) > 0 for _, cfgToBools := range ba.ConfigurableValues { if len(cfgToBools) > 0 { return true } } return false } // SetSelectValue sets value for the given axis/config. Loading @@ -343,6 +408,106 @@ func (ba *BoolAttribute) SetSelectValue(axis ConfigurationAxis, config string, v } } // ToLabelListAttribute creates and returns a LabelListAttribute from this // bool attribute, where each bool in this attribute corresponds to a // label list value in the resultant attribute. func (ba *BoolAttribute) ToLabelListAttribute(falseVal LabelList, trueVal LabelList) (LabelListAttribute, error) { getLabelList := func(boolPtr *bool) LabelList { if boolPtr == nil { return LabelList{nil, nil} } else if *boolPtr { return trueVal } else { return falseVal } } mainVal := getLabelList(ba.Value) if !ba.HasConfigurableValues() { return MakeLabelListAttribute(mainVal), nil } result := LabelListAttribute{} if err := ba.Collapse(); err != nil { return result, err } for axis, configToBools := range ba.ConfigurableValues { if len(configToBools) < 1 { continue } for config, boolPtr := range configToBools { val := getLabelList(&boolPtr) if !val.Equals(mainVal) { result.SetSelectValue(axis, config, val) } } result.SetSelectValue(axis, ConditionsDefaultConfigKey, mainVal) } return result, nil } // Collapse reduces the configurable axes of the boolean attribute to a single axis. // This is necessary for final writing to bp2build, as a configurable boolean // attribute can only be comprised by a single select. func (ba *BoolAttribute) Collapse() error { axisTypes := ba.axisTypes() _, containsOs := axisTypes[os] _, containsArch := axisTypes[arch] _, containsOsArch := axisTypes[osArch] _, containsProductVariables := axisTypes[productVariables] if containsProductVariables { if containsOs || containsArch || containsOsArch { return fmt.Errorf("boolean attribute could not be collapsed as it has two or more unrelated axes") } } if (containsOs && containsArch) || (containsOsArch && (containsOs || containsArch)) { // If a bool attribute has both os and arch configuration axes, the only // way to successfully union their values is to increase the granularity // of the configuration criteria to os_arch. for osType, supportedArchs := range osToArchMap { for _, supportedArch := range supportedArchs { osArch := osArchString(osType, supportedArch) if archOsVal := ba.SelectValue(OsArchConfigurationAxis, osArch); archOsVal != nil { // Do nothing, as the arch_os is explicitly defined already. } else { archVal := ba.SelectValue(ArchConfigurationAxis, supportedArch) osVal := ba.SelectValue(OsConfigurationAxis, osType) if osVal != nil && archVal != nil { // In this case, arch takes precedence. (This fits legacy Soong behavior, as arch mutator // runs after os mutator. ba.SetSelectValue(OsArchConfigurationAxis, osArch, archVal) } else if osVal != nil && archVal == nil { ba.SetSelectValue(OsArchConfigurationAxis, osArch, osVal) } else if osVal == nil && archVal != nil { ba.SetSelectValue(OsArchConfigurationAxis, osArch, archVal) } } } } // All os_arch values are now set. Clear os and arch axes. delete(ba.ConfigurableValues, ArchConfigurationAxis) delete(ba.ConfigurableValues, OsConfigurationAxis) // Verify post-condition; this should never fail, provided no additional // axes are introduced. if len(ba.ConfigurableValues) > 1 { panic(fmt.Errorf("error in collapsing attribute: %s", ba)) } } return nil } func (ba *BoolAttribute) axisTypes() map[configurationType]bool { types := map[configurationType]bool{} for k := range ba.ConfigurableValues { if len(ba.ConfigurableValues[k]) > 0 { types[k.configurationType] = true } } return types } // SelectValue gets the value for the given axis/config. func (ba BoolAttribute) SelectValue(axis ConfigurationAxis, config string) *bool { axis.validateConfig(config) Loading Loading @@ -550,7 +715,12 @@ func (lla *LabelListAttribute) Add(label *LabelAttribute) { // HasConfigurableValues returns true if the attribute contains axis-specific label list values. func (lla LabelListAttribute) HasConfigurableValues() bool { return len(lla.ConfigurableValues) > 0 for _, selectValues := range lla.ConfigurableValues { if len(selectValues) > 0 { return true } } return false } // IsEmpty returns true if the attribute has no values under any configuration. Loading Loading @@ -800,7 +970,12 @@ func MakeStringListAttribute(value []string) StringListAttribute { // HasConfigurableValues returns true if the attribute contains axis-specific string_list values. func (sla StringListAttribute) HasConfigurableValues() bool { return len(sla.ConfigurableValues) > 0 for _, selectValues := range sla.ConfigurableValues { if len(selectValues) > 0 { return true } } return false } // Append appends all values, including os and arch specific ones, from another Loading Loading
android/bazel.go +14 −6 Original line number Diff line number Diff line Loading @@ -367,13 +367,21 @@ var ( "libandroid_runtime_lazy", // depends on unconverted modules: libbinder_headers "libcmd", // depends on unconverted modules: libbinder "libdexfile_support_static", // Depends on unconverted module: libdexfile_external_headers "libunwindstack_local", "libunwindstack_utils", "libc_malloc_debug", "libfdtrack", // Depends on unconverted module: libunwindstack "libdexfile_support", // TODO(b/210546943): Enabled based on product variables. "libdexfile_external_headers", // TODO(b/210546943): Enabled based on product variables. "libunwindstack", // Depends on unconverted module libdexfile_support. "libnativehelper_compat_libc++", // Broken compile: implicit declaration of function 'strerror_r' is invalid in C99 "chkcon", "sefcontext_compile", // depends on unconverted modules: libsepol "libsepol", // TODO(b/207408632): Unsupported case of .l sources in cc library rules "gen-kotlin-build-file.py", // module has same name as source "libbinder", // TODO(b/188503688): Disabled for some archs, "libactivitymanager_aidl", // TODO(b/207426160): Depends on activity_manager_procstate_aidl, which is an aidl filegroup. "libnativehelper_lazy_mts_jni", "libnativehelper_mts_jni", // depends on unconverted modules: libgmock_ndk Loading Loading @@ -434,7 +442,6 @@ var ( "linkerconfig", // http://b/202876379 has arch-variant static_executable "mdnsd", // http://b/202876379 has arch-variant static_executable "acvp_modulewrapper", // disabled for android x86/x86_64 "CarHTMLViewer", // depends on unconverted modules android.car-stubs, car-ui-lib "libdexfile", // depends on unconverted modules: dexfile_operator_srcs, libartbase, libartpalette, Loading @@ -443,9 +450,7 @@ var ( // Per-module denylist of cc_library modules to only generate the static // variant if their shared variant isn't ready or buildable by Bazel. bp2buildCcLibraryStaticOnlyList = []string{ "libjemalloc5", // http://b/188503688, cc_library, `target: { android: { enabled: false } }` for android targets. } bp2buildCcLibraryStaticOnlyList = []string{} // Per-module denylist to opt modules out of mixed builds. Such modules will // still be generated via bp2build. Loading Loading @@ -513,6 +518,9 @@ func (b *BazelModuleBase) MixedBuildsEnabled(ctx ModuleContext) bool { // Windows toolchains are not currently supported. return false } if !ctx.Module().Enabled() { return false } if !ctx.Config().BazelContext.BazelEnabled() { return false } Loading
android/module.go +46 −6 Original line number Diff line number Diff line Loading @@ -869,6 +869,13 @@ type CommonAttributes struct { Data bazel.LabelListAttribute } // constraintAttributes represents Bazel attributes pertaining to build constraints, // which make restrict building a Bazel target for some set of platforms. type constraintAttributes struct { // Constraint values this target can be built for. Target_compatible_with bazel.LabelListAttribute } type distProperties struct { // configuration to distribute output files from this module to the distribution // directory (default: $OUT/dist, configurable with $DIST_DIR) Loading Loading @@ -1089,7 +1096,8 @@ func InitCommonOSAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupport m.base().commonProperties.CreateCommonOSVariant = true } func (attrs *CommonAttributes) fillCommonBp2BuildModuleAttrs(ctx *topDownMutatorContext) { func (attrs *CommonAttributes) fillCommonBp2BuildModuleAttrs(ctx *topDownMutatorContext, enabledPropertyOverrides bazel.BoolAttribute) constraintAttributes { // Assert passed-in attributes include Name name := attrs.Name if len(name) == 0 { Loading @@ -1107,14 +1115,45 @@ func (attrs *CommonAttributes) fillCommonBp2BuildModuleAttrs(ctx *topDownMutator required := depsToLabelList(props.Required) archVariantProps := mod.GetArchVariantProperties(ctx, &commonProperties{}) var enabledProperty bazel.BoolAttribute if props.Enabled != nil { enabledProperty.Value = props.Enabled } for axis, configToProps := range archVariantProps { for config, _props := range configToProps { if archProps, ok := _props.(*commonProperties); ok { required.SetSelectValue(axis, config, depsToLabelList(archProps.Required).Value) if archProps.Enabled != nil { enabledProperty.SetSelectValue(axis, config, archProps.Enabled) } } } } if enabledPropertyOverrides.Value != nil { enabledProperty.Value = enabledPropertyOverrides.Value } for _, axis := range enabledPropertyOverrides.SortedConfigurationAxes() { configToBools := enabledPropertyOverrides.ConfigurableValues[axis] for cfg, val := range configToBools { enabledProperty.SetSelectValue(axis, cfg, &val) } } data.Append(required) var err error constraints := constraintAttributes{} constraints.Target_compatible_with, err = enabledProperty.ToLabelListAttribute( bazel.LabelList{[]bazel.Label{bazel.Label{Label: "@platforms//:incompatible"}}, nil}, bazel.LabelList{[]bazel.Label{}, nil}) if err != nil { ctx.ModuleErrorf("Error processing enabled attribute: %s", err) } return constraints } // A ModuleBase object contains the properties that are common to all Android Loading Loading @@ -1236,6 +1275,7 @@ type bp2buildInfo struct { Dir string BazelProps bazel.BazelTargetModuleProperties CommonAttrs CommonAttributes ConstraintAttrs constraintAttributes Attrs interface{} } Loading @@ -1262,7 +1302,7 @@ func (b bp2buildInfo) BazelRuleLoadLocation() string { // BazelAttributes returns the Bazel attributes of a bp2build converted target. func (b bp2buildInfo) BazelAttributes() []interface{} { return []interface{}{&b.CommonAttrs, b.Attrs} return []interface{}{&b.CommonAttrs, &b.ConstraintAttrs, b.Attrs} } func (m *ModuleBase) addBp2buildInfo(info bp2buildInfo) { Loading
android/mutator.go +30 −5 Original line number Diff line number Diff line Loading @@ -254,6 +254,14 @@ type TopDownMutatorContext interface { // BazelTargetModuleProperties containing additional metadata for the // bp2build codegenerator. CreateBazelTargetModule(bazel.BazelTargetModuleProperties, CommonAttributes, interface{}) // CreateBazelTargetModuleWithRestrictions creates a BazelTargetModule by calling the // factory method, just like in CreateModule, but also requires // BazelTargetModuleProperties containing additional metadata for the // bp2build codegenerator. The generated target is restricted to only be buildable for certain // platforms, as dictated by a given bool attribute: the target will not be buildable in // any platform for which this bool attribute is false. CreateBazelTargetModuleWithRestrictions(bazel.BazelTargetModuleProperties, CommonAttributes, interface{}, bazel.BoolAttribute) } type topDownMutatorContext struct { Loading Loading @@ -502,12 +510,29 @@ func (t *topDownMutatorContext) CreateBazelTargetModule( bazelProps bazel.BazelTargetModuleProperties, commonAttrs CommonAttributes, attrs interface{}) { commonAttrs.fillCommonBp2BuildModuleAttrs(t) t.createBazelTargetModule(bazelProps, commonAttrs, attrs, bazel.BoolAttribute{}) } func (t *topDownMutatorContext) CreateBazelTargetModuleWithRestrictions( bazelProps bazel.BazelTargetModuleProperties, commonAttrs CommonAttributes, attrs interface{}, enabledProperty bazel.BoolAttribute) { t.createBazelTargetModule(bazelProps, commonAttrs, attrs, enabledProperty) } func (t *topDownMutatorContext) createBazelTargetModule( bazelProps bazel.BazelTargetModuleProperties, commonAttrs CommonAttributes, attrs interface{}, enabledProperty bazel.BoolAttribute) { constraintAttributes := commonAttrs.fillCommonBp2BuildModuleAttrs(t, enabledProperty) mod := t.Module() info := bp2buildInfo{ Dir: t.OtherModuleDir(mod), BazelProps: bazelProps, CommonAttrs: commonAttrs, ConstraintAttrs: constraintAttributes, Attrs: attrs, } mod.base().addBp2buildInfo(info) Loading
bazel/configurability.go +19 −0 Original line number Diff line number Diff line Loading @@ -109,6 +109,21 @@ var ( osArchWindowsX86_64: "//build/bazel/platforms/os_arch:windows_x86_64", ConditionsDefaultConfigKey: ConditionsDefaultSelectKey, // The default condition of an os select map. } // Map where keys are OsType names, and values are slices containing the archs // that that OS supports. // These definitions copied from arch.go. // TODO(cparsons): Source from arch.go; this task is nontrivial, as it currently results // in a cyclic dependency. osToArchMap = map[string][]string{ osAndroid: {archArm, archArm64, archX86, archX86_64}, osLinux: {archX86, archX86_64}, osLinuxMusl: {archX86, archX86_64}, osDarwin: {archArm64, archX86_64}, osLinuxBionic: {archArm64, archX86_64}, // TODO(cparsons): According to arch.go, this should contain archArm, archArm64, as well. osWindows: {archX86, archX86_64}, } ) // basic configuration types Loading @@ -122,6 +137,10 @@ const ( productVariables ) func osArchString(os string, arch string) string { return fmt.Sprintf("%s_%s", os, arch) } func (ct configurationType) String() string { return map[configurationType]string{ noConfig: "no_config", Loading
bazel/properties.go +182 −7 Original line number Diff line number Diff line Loading @@ -244,9 +244,69 @@ type LabelAttribute struct { ConfigurableValues configurableLabels } func (la *LabelAttribute) axisTypes() map[configurationType]bool { types := map[configurationType]bool{} for k := range la.ConfigurableValues { if len(la.ConfigurableValues[k]) > 0 { types[k.configurationType] = true } } return types } // Collapse reduces the configurable axes of the label attribute to a single axis. // This is necessary for final writing to bp2build, as a configurable label // attribute can only be comprised by a single select. func (la *LabelAttribute) Collapse() error { axisTypes := la.axisTypes() _, containsOs := axisTypes[os] _, containsArch := axisTypes[arch] _, containsOsArch := axisTypes[osArch] _, containsProductVariables := axisTypes[productVariables] if containsProductVariables { if containsOs || containsArch || containsOsArch { return fmt.Errorf("label attribute could not be collapsed as it has two or more unrelated axes") } } if (containsOs && containsArch) || (containsOsArch && (containsOs || containsArch)) { // If a bool attribute has both os and arch configuration axes, the only // way to successfully union their values is to increase the granularity // of the configuration criteria to os_arch. for osType, supportedArchs := range osToArchMap { for _, supportedArch := range supportedArchs { osArch := osArchString(osType, supportedArch) if archOsVal := la.SelectValue(OsArchConfigurationAxis, osArch); archOsVal != nil { // Do nothing, as the arch_os is explicitly defined already. } else { archVal := la.SelectValue(ArchConfigurationAxis, supportedArch) osVal := la.SelectValue(OsConfigurationAxis, osType) if osVal != nil && archVal != nil { // In this case, arch takes precedence. (This fits legacy Soong behavior, as arch mutator // runs after os mutator. la.SetSelectValue(OsArchConfigurationAxis, osArch, *archVal) } else if osVal != nil && archVal == nil { la.SetSelectValue(OsArchConfigurationAxis, osArch, *osVal) } else if osVal == nil && archVal != nil { la.SetSelectValue(OsArchConfigurationAxis, osArch, *archVal) } } } } // All os_arch values are now set. Clear os and arch axes. delete(la.ConfigurableValues, ArchConfigurationAxis) delete(la.ConfigurableValues, OsConfigurationAxis) } return nil } // HasConfigurableValues returns whether there are configurable values set for this label. func (la LabelAttribute) HasConfigurableValues() bool { return len(la.ConfigurableValues) > 0 for _, selectValues := range la.ConfigurableValues { if len(selectValues) > 0 { return true } } return false } // SetValue sets the base, non-configured value for the Label Loading @@ -271,13 +331,13 @@ func (la *LabelAttribute) SetSelectValue(axis ConfigurationAxis, config string, } // SelectValue gets a value for a bazel select for the given axis and config. func (la *LabelAttribute) SelectValue(axis ConfigurationAxis, config string) Label { func (la *LabelAttribute) SelectValue(axis ConfigurationAxis, config string) *Label { axis.validateConfig(config) switch axis.configurationType { case noConfig: return *la.Value return la.Value case arch, os, osArch, productVariables: return *la.ConfigurableValues[axis][config] return la.ConfigurableValues[axis][config] default: panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis)) } Loading Loading @@ -324,7 +384,12 @@ type BoolAttribute struct { // HasConfigurableValues returns whether there are configurable values for this attribute. func (ba BoolAttribute) HasConfigurableValues() bool { return len(ba.ConfigurableValues) > 0 for _, cfgToBools := range ba.ConfigurableValues { if len(cfgToBools) > 0 { return true } } return false } // SetSelectValue sets value for the given axis/config. Loading @@ -343,6 +408,106 @@ func (ba *BoolAttribute) SetSelectValue(axis ConfigurationAxis, config string, v } } // ToLabelListAttribute creates and returns a LabelListAttribute from this // bool attribute, where each bool in this attribute corresponds to a // label list value in the resultant attribute. func (ba *BoolAttribute) ToLabelListAttribute(falseVal LabelList, trueVal LabelList) (LabelListAttribute, error) { getLabelList := func(boolPtr *bool) LabelList { if boolPtr == nil { return LabelList{nil, nil} } else if *boolPtr { return trueVal } else { return falseVal } } mainVal := getLabelList(ba.Value) if !ba.HasConfigurableValues() { return MakeLabelListAttribute(mainVal), nil } result := LabelListAttribute{} if err := ba.Collapse(); err != nil { return result, err } for axis, configToBools := range ba.ConfigurableValues { if len(configToBools) < 1 { continue } for config, boolPtr := range configToBools { val := getLabelList(&boolPtr) if !val.Equals(mainVal) { result.SetSelectValue(axis, config, val) } } result.SetSelectValue(axis, ConditionsDefaultConfigKey, mainVal) } return result, nil } // Collapse reduces the configurable axes of the boolean attribute to a single axis. // This is necessary for final writing to bp2build, as a configurable boolean // attribute can only be comprised by a single select. func (ba *BoolAttribute) Collapse() error { axisTypes := ba.axisTypes() _, containsOs := axisTypes[os] _, containsArch := axisTypes[arch] _, containsOsArch := axisTypes[osArch] _, containsProductVariables := axisTypes[productVariables] if containsProductVariables { if containsOs || containsArch || containsOsArch { return fmt.Errorf("boolean attribute could not be collapsed as it has two or more unrelated axes") } } if (containsOs && containsArch) || (containsOsArch && (containsOs || containsArch)) { // If a bool attribute has both os and arch configuration axes, the only // way to successfully union their values is to increase the granularity // of the configuration criteria to os_arch. for osType, supportedArchs := range osToArchMap { for _, supportedArch := range supportedArchs { osArch := osArchString(osType, supportedArch) if archOsVal := ba.SelectValue(OsArchConfigurationAxis, osArch); archOsVal != nil { // Do nothing, as the arch_os is explicitly defined already. } else { archVal := ba.SelectValue(ArchConfigurationAxis, supportedArch) osVal := ba.SelectValue(OsConfigurationAxis, osType) if osVal != nil && archVal != nil { // In this case, arch takes precedence. (This fits legacy Soong behavior, as arch mutator // runs after os mutator. ba.SetSelectValue(OsArchConfigurationAxis, osArch, archVal) } else if osVal != nil && archVal == nil { ba.SetSelectValue(OsArchConfigurationAxis, osArch, osVal) } else if osVal == nil && archVal != nil { ba.SetSelectValue(OsArchConfigurationAxis, osArch, archVal) } } } } // All os_arch values are now set. Clear os and arch axes. delete(ba.ConfigurableValues, ArchConfigurationAxis) delete(ba.ConfigurableValues, OsConfigurationAxis) // Verify post-condition; this should never fail, provided no additional // axes are introduced. if len(ba.ConfigurableValues) > 1 { panic(fmt.Errorf("error in collapsing attribute: %s", ba)) } } return nil } func (ba *BoolAttribute) axisTypes() map[configurationType]bool { types := map[configurationType]bool{} for k := range ba.ConfigurableValues { if len(ba.ConfigurableValues[k]) > 0 { types[k.configurationType] = true } } return types } // SelectValue gets the value for the given axis/config. func (ba BoolAttribute) SelectValue(axis ConfigurationAxis, config string) *bool { axis.validateConfig(config) Loading Loading @@ -550,7 +715,12 @@ func (lla *LabelListAttribute) Add(label *LabelAttribute) { // HasConfigurableValues returns true if the attribute contains axis-specific label list values. func (lla LabelListAttribute) HasConfigurableValues() bool { return len(lla.ConfigurableValues) > 0 for _, selectValues := range lla.ConfigurableValues { if len(selectValues) > 0 { return true } } return false } // IsEmpty returns true if the attribute has no values under any configuration. Loading Loading @@ -800,7 +970,12 @@ func MakeStringListAttribute(value []string) StringListAttribute { // HasConfigurableValues returns true if the attribute contains axis-specific string_list values. func (sla StringListAttribute) HasConfigurableValues() bool { return len(sla.ConfigurableValues) > 0 for _, selectValues := range sla.ConfigurableValues { if len(selectValues) > 0 { return true } } return false } // Append appends all values, including os and arch specific ones, from another Loading