diff options
Diffstat (limited to 'android/module.go')
-rw-r--r-- | android/module.go | 412 |
1 files changed, 13 insertions, 399 deletions
diff --git a/android/module.go b/android/module.go index 9d746426f..f57115799 100644 --- a/android/module.go +++ b/android/module.go @@ -16,7 +16,6 @@ package android import ( "android/soong/bazel" - "android/soong/ui/metrics/bp2build_metrics_proto" "crypto/md5" "encoding/hex" "encoding/json" @@ -96,16 +95,6 @@ type Module interface { AddProperties(props ...interface{}) GetProperties() []interface{} - // If this module should not have bazel BUILD definitions generated by bp2build, - // GetUnconvertedReason returns a reason this is the case. - GetUnconvertedReason() *UnconvertedReason - - // Bp2buildTargets returns the target(s) generated for Bazel via bp2build for this module - Bp2buildTargets() []bp2buildInfo - GetUnconvertedBp2buildDeps() []string - GetMissingBp2buildDeps() []string - GetPartitionForBp2build() string - BuildParamsForTests() []BuildParams RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams VariablesForTests() map[string]string @@ -520,9 +509,6 @@ type commonProperties struct { // constants in image.go, but can also be set to a custom value by individual module types. ImageVariation string `blueprint:"mutated"` - // Bazel conversion status - BazelConversionStatus BazelConversionStatus `blueprint:"mutated"` - // SoongConfigTrace records accesses to VendorVars (soong_config). The trace will be hashed // and used as a subdir of PathForModuleOut. Note that we mainly focus on incremental // builds among similar products (e.g. aosp_cf_x86_64_phone and aosp_cf_x86_64_foldable), @@ -532,41 +518,6 @@ type commonProperties struct { SoongConfigTraceHash string `blueprint:"mutated"` } -// CommonAttributes represents the common Bazel attributes from which properties -// in `commonProperties` are translated/mapped; such properties are annotated in -// a list their corresponding attribute. It is embedded within `bp2buildInfo`. -type CommonAttributes struct { - // Soong nameProperties -> Bazel name - Name string - - // Data mapped from: Required - Data bazel.LabelListAttribute - - // SkipData is neither a Soong nor Bazel target attribute - // If true, this will not fill the data attribute automatically - // This is useful for Soong modules that have 1:many Bazel targets - // Some of the generated Bazel targets might not have a data attribute - SkipData *bool - - Tags bazel.StringListAttribute - - Applicable_licenses bazel.LabelListAttribute - - Testonly *bool - - // Dir is neither a Soong nor Bazel target attribute - // If set, the bazel target will be created in this directory - // If unset, the bazel target will default to be created in the directory of the visited soong module - Dir *string -} - -// 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) @@ -804,234 +755,6 @@ func InitCommonOSAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupport m.base().commonProperties.CreateCommonOSVariant = true } -func (attrs *CommonAttributes) getRequiredWithoutCycles(ctx *bottomUpMutatorContext, props *commonProperties) []string { - // Treat `required` as if it's empty if data should be skipped for this target, - // as `required` is only used for the `data` attribute at this time, and we want - // to avoid lookups of labels that won't actually be dependencies of this target. - // TODO: b/202299295 - Refactor this to use `required` dependencies, once they - // are handled other than passing to `data`. - if proptools.Bool(attrs.SkipData) { - return []string{} - } - // The required property can contain the module itself. This causes a cycle - // when generated as the 'data' label list attribute in Bazel. Remove it if - // it exists. See b/247985196. - _, requiredWithoutCycles := RemoveFromList(ctx.ModuleName(), props.Required) - return FirstUniqueStrings(requiredWithoutCycles) -} - -func (attrs *CommonAttributes) fillCommonBp2BuildModuleAttrs(ctx *bottomUpMutatorContext, - enabledPropertyOverrides bazel.BoolAttribute) constraintAttributes { - - mod := ctx.Module().base() - // Assert passed-in attributes include Name - if len(attrs.Name) == 0 { - if ctx.ModuleType() != "package" { - ctx.ModuleErrorf("CommonAttributes in fillCommonBp2BuildModuleAttrs expects a `.Name`!") - } - } - - depsToLabelList := func(deps []string) bazel.LabelListAttribute { - return bazel.MakeLabelListAttribute(BazelLabelForModuleDeps(ctx, deps)) - } - - var enabledProperty bazel.BoolAttribute - - onlyAndroid := false - neitherHostNorDevice := false - - osSupport := map[string]bool{} - - // if the target is enabled and supports arch variance, determine the defaults based on the module - // type's host or device property and host_supported/device_supported properties - if mod.commonProperties.ArchSpecific { - moduleSupportsDevice := mod.DeviceSupported() - moduleSupportsHost := mod.HostSupported() - if moduleSupportsHost && !moduleSupportsDevice { - // for host only, we specify as unsupported on android rather than listing all host osSupport - // TODO(b/220874839): consider replacing this with a constraint that covers all host osSupport - // instead - enabledProperty.SetSelectValue(bazel.OsConfigurationAxis, Android.Name, proptools.BoolPtr(false)) - } else if moduleSupportsDevice && !moduleSupportsHost { - enabledProperty.SetSelectValue(bazel.OsConfigurationAxis, Android.Name, proptools.BoolPtr(true)) - // specify as a positive to ensure any target-specific enabled can be resolved - // also save that a target is only android, as if there is only the positive restriction on - // android, it'll be dropped, so we may need to add it back later - onlyAndroid = true - } else if !moduleSupportsHost && !moduleSupportsDevice { - neitherHostNorDevice = true - } - - for _, osType := range OsTypeList() { - if osType.Class == Host { - osSupport[osType.Name] = moduleSupportsHost - } else if osType.Class == Device { - osSupport[osType.Name] = moduleSupportsDevice - } - } - } - - if neitherHostNorDevice { - // we can't build this, disable - enabledProperty.Value = proptools.BoolPtr(false) - } else if mod.commonProperties.Enabled != nil { - enabledProperty.SetValue(mod.commonProperties.Enabled) - if !*mod.commonProperties.Enabled { - for oss, enabled := range osSupport { - if val := enabledProperty.SelectValue(bazel.OsConfigurationAxis, oss); enabled && val != nil && *val { - // if this should be disabled by default, clear out any enabling we've done - enabledProperty.SetSelectValue(bazel.OsConfigurationAxis, oss, nil) - } - } - } - } - - attrs.Applicable_licenses = bazel.MakeLabelListAttribute(BazelLabelForModuleDeps(ctx, mod.commonProperties.Licenses)) - - requiredWithoutCycles := attrs.getRequiredWithoutCycles(ctx, &mod.commonProperties) - required := depsToLabelList(requiredWithoutCycles) - archVariantProps := mod.GetArchVariantProperties(ctx, &commonProperties{}) - for axis, configToProps := range archVariantProps { - for config, _props := range configToProps { - if archProps, ok := _props.(*commonProperties); ok { - requiredWithoutCycles := attrs.getRequiredWithoutCycles(ctx, archProps) - required.SetSelectValue(axis, config, depsToLabelList(requiredWithoutCycles).Value) - if !neitherHostNorDevice { - if archProps.Enabled != nil { - if axis != bazel.OsConfigurationAxis || osSupport[config] { - enabledProperty.SetSelectValue(axis, config, archProps.Enabled) - } - } - } - } - } - } - - if !neitherHostNorDevice { - if enabledPropertyOverrides.Value != nil { - enabledProperty.Value = enabledPropertyOverrides.Value - } - for _, axis := range enabledPropertyOverrides.SortedConfigurationAxes() { - configToBools := enabledPropertyOverrides.ConfigurableValues[axis] - for cfg, val := range configToBools { - if axis != bazel.OsConfigurationAxis || osSupport[cfg] || val /*If enabled is explicitly requested via overrides */ { - enabledProperty.SetSelectValue(axis, cfg, &val) - } - } - } - } - - 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 - productConfigEnabledAttribute = productVariableConfigEnableAttribute(ctx) - - if len(productConfigEnabledAttribute.ConfigurableValues) > 0 { - // In this case, an existing product variable configuration overrides any - // module-level `enable: false` definition - newValue := true - enabledProperty.Value = &newValue - } - } - - platformEnabledAttribute, err := enabledProperty.ToLabelListAttribute( - bazel.LabelList{[]bazel.Label{{Label: "@platforms//:incompatible"}}, nil}, - bazel.LabelList{[]bazel.Label{}, nil}) - if err != nil { - ctx.ModuleErrorf("Error processing platform enabled attribute: %s", err) - } - - // if android is the only arch/os enabled, then add a restriction to only be compatible with android - if platformEnabledAttribute.IsNil() && onlyAndroid { - l := bazel.LabelAttribute{} - l.SetValue(bazel.Label{Label: bazel.OsConfigurationAxis.SelectKey(Android.Name)}) - platformEnabledAttribute.Add(&l) - } - - attrs.Data.Append(required) - - // SkipData is not an attribute of any Bazel target - // Set this to nil so that it does not appear in the generated build file - attrs.SkipData = nil - - moduleEnableConstraints := bazel.LabelListAttribute{} - moduleEnableConstraints.Append(platformEnabledAttribute) - moduleEnableConstraints.Append(productConfigEnabledAttribute) - addCompatibilityConstraintForCompileMultilib(ctx, &moduleEnableConstraints) - - return constraintAttributes{Target_compatible_with: moduleEnableConstraints} -} - -var ( - incompatible = bazel.LabelList{[]bazel.Label{{Label: "@platforms//:incompatible"}}, nil} -) - -// If compile_mulitilib is set to -// 1. 32: Add an incompatibility constraint for non-32 arches -// 1. 64: Add an incompatibility constraint for non-64 arches -func addCompatibilityConstraintForCompileMultilib(ctx *bottomUpMutatorContext, enabled *bazel.LabelListAttribute) { - mod := ctx.Module().base() - multilib, _ := decodeMultilib(mod, mod.commonProperties.CompileOS, ctx.Config().IgnorePrefer32OnDevice()) - - switch multilib { - case "32": - // Add an incompatibility constraint for all known 64-bit arches - enabled.SetSelectValue(bazel.ArchConfigurationAxis, "arm64", incompatible) - enabled.SetSelectValue(bazel.ArchConfigurationAxis, "x86_64", incompatible) - enabled.SetSelectValue(bazel.ArchConfigurationAxis, "riscv64", incompatible) - case "64": - // Add an incompatibility constraint for all known 32-bit arches - enabled.SetSelectValue(bazel.ArchConfigurationAxis, "arm", incompatible) - enabled.SetSelectValue(bazel.ArchConfigurationAxis, "x86", incompatible) - case "both": - // Do nothing: "both" is trivially compatible with 32-bit and 64-bit - // The top level rule (e.g. apex/partition) will be responsible for building this module in both variants via an - // outgoing_transition. - default: // e.g. first, common - // TODO - b/299135307: Add bp2build support for these properties. - } - -} - -// Check product variables for `enabled: true` flag override. -// Returns a list of the constraint_value targets who enable this override. -func productVariableConfigEnableAttribute(ctx *bottomUpMutatorContext) bazel.LabelListAttribute { - result := bazel.LabelListAttribute{} - productVariableProps, errs := ProductVariableProperties(ctx, ctx.Module()) - for _, err := range errs { - ctx.ModuleErrorf("ProductVariableProperties error: %s", err) - } - if productConfigProps, exists := productVariableProps["Enabled"]; exists { - for productConfigProp, prop := range productConfigProps { - flag, ok := prop.(*bool) - if !ok { - ctx.ModuleErrorf("Could not convert product variable enabled property") - } - - if flag == nil { - // soong config var is not used to set `enabled`. nothing to do. - continue - } else if *flag { - axis := productConfigProp.ConfigurationAxis() - result.SetSelectValue(axis, bazel.ConditionsDefaultConfigKey, bazel.MakeLabelList([]bazel.Label{{Label: "@platforms//:incompatible"}})) - result.SetSelectValue(axis, productConfigProp.SelectKey(), bazel.LabelList{Includes: []bazel.Label{}}) - } else if scp, isSoongConfigProperty := productConfigProp.(SoongConfigProperty); isSoongConfigProperty && scp.value == bazel.ConditionsDefaultConfigKey { - // productVariableConfigEnableAttribute runs only if `enabled: false` is set at the top-level outside soong_config_variables - // conditions_default { enabled: false} is a no-op in this case - continue - } else { - // TODO(b/210546943): handle negative case where `enabled: false` - ctx.ModuleErrorf("`enabled: false` is not currently supported for configuration variables. See b/210546943") - } - } - } - - return result -} - // A ModuleBase object contains the properties that are common to all Android // modules. It should be included as an anonymous field in every module // struct definition. InitAndroidModule should then be called from the module's @@ -1146,81 +869,6 @@ type ModuleBase struct { licenseMetadataFile WritablePath } -// A struct containing all relevant information about a Bazel target converted via bp2build. -type bp2buildInfo struct { - Dir string - BazelProps bazel.BazelTargetModuleProperties - CommonAttrs CommonAttributes - ConstraintAttrs constraintAttributes - Attrs interface{} -} - -// TargetName returns the Bazel target name of a bp2build converted target. -func (b bp2buildInfo) TargetName() string { - return b.CommonAttrs.Name -} - -// TargetPackage returns the Bazel package of a bp2build converted target. -func (b bp2buildInfo) TargetPackage() string { - return b.Dir -} - -// BazelRuleClass returns the Bazel rule class of a bp2build converted target. -func (b bp2buildInfo) BazelRuleClass() string { - return b.BazelProps.Rule_class -} - -// BazelRuleLoadLocation returns the location of the Bazel rule of a bp2build converted target. -// This may be empty as native Bazel rules do not need to be loaded. -func (b bp2buildInfo) BazelRuleLoadLocation() string { - return b.BazelProps.Bzl_load_location -} - -// BazelAttributes returns the Bazel attributes of a bp2build converted target. -func (b bp2buildInfo) BazelAttributes() []interface{} { - return []interface{}{&b.CommonAttrs, &b.ConstraintAttrs, b.Attrs} -} - -func (m *ModuleBase) addBp2buildInfo(info bp2buildInfo) { - m.commonProperties.BazelConversionStatus.Bp2buildInfo = append(m.commonProperties.BazelConversionStatus.Bp2buildInfo, info) -} - -func (m *ModuleBase) setPartitionForBp2build(partition string) { - m.commonProperties.BazelConversionStatus.Partition = partition -} - -func (m *ModuleBase) setBp2buildUnconvertible(reasonType bp2build_metrics_proto.UnconvertedReasonType, detail string) { - m.commonProperties.BazelConversionStatus.UnconvertedReason = &UnconvertedReason{ - ReasonType: int(reasonType), - Detail: detail, - } -} - -func (m *ModuleBase) GetUnconvertedReason() *UnconvertedReason { - return m.commonProperties.BazelConversionStatus.UnconvertedReason -} - -// Bp2buildTargets returns the Bazel targets bp2build generated for this module. -func (m *ModuleBase) Bp2buildTargets() []bp2buildInfo { - return m.commonProperties.BazelConversionStatus.Bp2buildInfo -} - -// Bp2buildTargets returns the Bazel targets bp2build generated for this module. -func (m *ModuleBase) GetPartitionForBp2build() string { - return m.commonProperties.BazelConversionStatus.Partition -} - -// GetUnconvertedBp2buildDeps returns the list of module names of this module's direct dependencies that -// were not converted to Bazel. -func (m *ModuleBase) GetUnconvertedBp2buildDeps() []string { - return FirstUniqueStrings(m.commonProperties.BazelConversionStatus.UnconvertedDeps) -} - -// GetMissingBp2buildDeps returns the list of module names that were not found in Android.bp files. -func (m *ModuleBase) GetMissingBp2buildDeps() []string { - return FirstUniqueStrings(m.commonProperties.BazelConversionStatus.MissingDeps) -} - func (m *ModuleBase) AddJSONData(d *map[string]interface{}) { (*d)["Android"] = map[string]interface{}{ // Properties set in Blueprint or in blueprint of a defaults modules @@ -2031,11 +1679,7 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) return } - if mixedBuildMod, handled := m.isHandledByBazel(ctx); handled { - mixedBuildMod.ProcessBazelQueryResponse(ctx) - } else { - m.module.GenerateAndroidBuildActions(ctx) - } + m.module.GenerateAndroidBuildActions(ctx) if ctx.Failed() { return } @@ -2092,15 +1736,6 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) m.variables = ctx.variables } -func (m *ModuleBase) isHandledByBazel(ctx ModuleContext) (MixedBuildBuildable, bool) { - if mixedBuildMod, ok := m.module.(MixedBuildBuildable); ok { - if mixedBuildMod.IsMixedBuildSupported(ctx) && (MixedBuildsEnabled(ctx) == MixedBuildEnabled) { - return mixedBuildMod, true - } - } - return nil, false -} - // Check the supplied dist structure to make sure that it is valid. // // property - the base property, e.g. dist or dists[1], which is combined with the @@ -2193,6 +1828,18 @@ func (m *ModuleBase) IsNativeBridgeSupported() bool { return proptools.Bool(m.commonProperties.Native_bridge_supported) } +// ModuleNameWithPossibleOverride returns the name of the OverrideModule that overrides the current +// variant of this OverridableModule, or ctx.ModuleName() if this module is not an OverridableModule +// or if this variant is not overridden. +func ModuleNameWithPossibleOverride(ctx BaseModuleContext) string { + if overridable, ok := ctx.Module().(OverridableModule); ok { + if o := overridable.GetOverriddenBy(); o != "" { + return o + } + } + return ctx.ModuleName() +} + // SrcIsModule decodes module references in the format ":unqualified-name" or "//namespace:name" // into the module name, or empty string if the input was not a module reference. func SrcIsModule(s string) (module string) { @@ -2615,36 +2262,3 @@ func (s *soongConfigTraceSingleton) GenerateBuildActions(ctx SingletonContext) { WriteFileRule(ctx, outFile, string(j)) ctx.Phony("soong_config_trace", outFile) } - -// Interface implemented by xsd_config which has 1:many mappings in bp2build workspace -// This interface exists because we want to -// 1. Determine the name of the additional targets generated by the primary soong module -// 2. Enable distinguishing an xsd_config module from other Soong modules using type assertion -type XsdConfigBp2buildTargets interface { - CppBp2buildTargetName() string - JavaBp2buildTargetName() string -} - -// XsdModuleToTargetName is a function that takes an XsdConfigBp2buildTarget -type XsdModuleToTargetName func(xsd XsdConfigBp2buildTargets) string - -// XsdLabelMapper returns a bazel.LabelMapper for partitioning XSD sources/headers given an -// XsdModuleToTargetName function. -func XsdLabelMapper(targetName XsdModuleToTargetName) bazel.LabelMapper { - return func(ctx bazel.OtherModuleContext, label bazel.Label) (string, bool) { - mod, exists := ctx.ModuleFromName(label.OriginalModuleName) - if !exists { - return label.Label, false - } - xsdMod, isXsd := mod.(XsdConfigBp2buildTargets) - if !isXsd { - return label.Label, false - } - - // Remove the base module name - ret := strings.TrimSuffix(label.Label, mod.Name()) - // Append the language specific target name - ret += targetName(xsdMod) - return ret, true - } -} |