diff options
Diffstat (limited to 'android/module.go')
-rw-r--r-- | android/module.go | 313 |
1 files changed, 234 insertions, 79 deletions
diff --git a/android/module.go b/android/module.go index 9e620fb5b..996c64e52 100644 --- a/android/module.go +++ b/android/module.go @@ -94,7 +94,6 @@ type Module interface { ReplacedByPrebuilt() IsReplacedByPrebuilt() bool ExportedToMake() bool - EffectiveLicenseKinds() []string EffectiveLicenseFiles() Paths AddProperties(props ...interface{}) @@ -257,6 +256,8 @@ type nameProperties struct { Name *string } +// Properties common to all modules inheriting from ModuleBase. These properties are automatically +// inherited by sub-modules created with ctx.CreateModule() type commonProperties struct { // emit build rules for this module // @@ -315,8 +316,6 @@ type commonProperties struct { // Describes the licenses applicable to this module. Must reference license modules. Licenses []string - // Flattened from direct license dependencies. Equal to Licenses unless particular module adds more. - Effective_licenses []string `blueprint:"mutated"` // Override of module name when reporting licenses Effective_package_name *string `blueprint:"mutated"` // Notice files @@ -409,15 +408,6 @@ type commonProperties struct { // VINTF manifest fragments to be installed if this module is installed Vintf_fragments proptools.Configurable[[]string] `android:"path"` - // names of other modules to install if this module is installed - Required proptools.Configurable[[]string] `android:"arch_variant"` - - // names of other modules to install on host if this module is installed - Host_required []string `android:"arch_variant"` - - // names of other modules to install on target if this module is installed - Target_required []string `android:"arch_variant"` - // The OsType of artifacts that this module variant is responsible for creating. // // Set by osMutator @@ -518,6 +508,19 @@ type commonProperties struct { Overrides []string } +// Properties common to all modules inheriting from ModuleBase. Unlike commonProperties, these +// properties are NOT automatically inherited by sub-modules created with ctx.CreateModule() +type baseProperties struct { + // names of other modules to install if this module is installed + Required proptools.Configurable[[]string] `android:"arch_variant"` + + // names of other modules to install on host if this module is installed + Host_required []string `android:"arch_variant"` + + // names of other modules to install on target if this module is installed + Target_required []string `android:"arch_variant"` +} + type distProperties struct { // configuration to distribute output files from this module to the distribution // directory (default: $OUT/dist, configurable with $DIST_DIR) @@ -716,6 +719,7 @@ func InitAndroidModule(m Module) { m.AddProperties( &base.nameProperties, &base.commonProperties, + &base.baseProperties, &base.distProperties) initProductVariableModule(m) @@ -834,6 +838,7 @@ type ModuleBase struct { nameProperties nameProperties commonProperties commonProperties + baseProperties baseProperties distProperties distProperties variableProperties interface{} hostAndDeviceProperties hostAndDeviceProperties @@ -990,8 +995,9 @@ func (m *ModuleBase) baseDepsMutator(ctx BottomUpMutatorContext) { // 2. `boot_signer` is `required` by modules like `build_image` which is explicitly list as // the top-level build goal (in the shell file that invokes Soong). // 3. `boot_signer` depends on `bouncycastle-unbundled` which is in the missing git project. - // 4. aosp_kernel-build-tools invokes soong with `--skip-make`. Therefore, the absence of - // ALLOW_MISSING_DEPENDENCIES didn't cause a problem. + // 4. aosp_kernel-build-tools invokes soong with `--soong-only`. Therefore, the absence of + // ALLOW_MISSING_DEPENDENCIES didn't cause a problem, as previously only make processed required + // dependencies. // 5. Now, since Soong understands `required` deps, it tries to build `boot_signer` and the // absence of external/bouncycastle fails the build. // @@ -1085,6 +1091,10 @@ var vintfDepTag = struct { InstallAlwaysNeededDependencyTag }{} +func IsVintfDepTag(depTag blueprint.DependencyTag) bool { + return depTag == vintfDepTag +} + func addVintfFragmentDeps(ctx BottomUpMutatorContext) { // Vintf manifests in the recovery partition will be ignored. if !ctx.Device() || ctx.Module().InstallInRecovery() { @@ -1103,7 +1113,7 @@ func addVintfFragmentDeps(ctx BottomUpMutatorContext) { // of nil pointer dereference errors, but we should resolve the missing dependencies. continue } - if vintfModule, ok := vintf.(*vintfFragmentModule); ok { + if vintfModule, ok := vintf.(*VintfFragmentModule); ok { vintfPartition := vintfModule.PartitionTag(deviceConfig) if modPartition != vintfPartition { ctx.ModuleErrorf("Module %q(%q) and Vintf_fragment %q(%q) are installed to different partitions.", @@ -1458,10 +1468,6 @@ func (m *ModuleBase) ExportedToMake() bool { return m.commonProperties.NamespaceExportedToMake } -func (m *ModuleBase) EffectiveLicenseKinds() []string { - return m.commonProperties.Effective_license_kinds -} - func (m *ModuleBase) EffectiveLicenseFiles() Paths { result := make(Paths, 0, len(m.commonProperties.Effective_license_text)) for _, p := range m.commonProperties.Effective_license_text { @@ -1618,15 +1624,15 @@ func (m *ModuleBase) InRecovery() bool { } func (m *ModuleBase) RequiredModuleNames(ctx ConfigurableEvaluatorContext) []string { - return m.base().commonProperties.Required.GetOrDefault(m.ConfigurableEvaluator(ctx), nil) + return m.base().baseProperties.Required.GetOrDefault(m.ConfigurableEvaluator(ctx), nil) } func (m *ModuleBase) HostRequiredModuleNames() []string { - return m.base().commonProperties.Host_required + return m.base().baseProperties.Host_required } func (m *ModuleBase) TargetRequiredModuleNames() []string { - return m.base().commonProperties.Target_required + return m.base().baseProperties.Target_required } func (m *ModuleBase) VintfFragmentModuleNames(ctx ConfigurableEvaluatorContext) []string { @@ -1654,6 +1660,7 @@ func (m *ModuleBase) generateVariantTarget(ctx *moduleContext) { func (m *ModuleBase) generateModuleTarget(ctx *moduleContext) { var allInstalledFiles InstallPaths var allCheckbuildTargets Paths + var alloutputFiles Paths ctx.VisitAllModuleVariantProxies(func(module ModuleProxy) { var checkbuildTarget Path var uncheckedModule bool @@ -1670,6 +1677,9 @@ func (m *ModuleBase) generateModuleTarget(ctx *moduleContext) { uncheckedModule = info.UncheckedModule skipAndroidMkProcessing = OtherModuleProviderOrDefault(ctx, module, CommonModuleInfoKey).SkipAndroidMkProcessing } + if outputFiles, err := outputFilesForModule(ctx, module, ""); err == nil { + alloutputFiles = append(alloutputFiles, outputFiles...) + } // A module's -checkbuild phony targets should // not be created if the module is not exported to make. // Those could depend on the build target and fail to compile @@ -1701,6 +1711,12 @@ func (m *ModuleBase) generateModuleTarget(ctx *moduleContext) { deps = append(deps, PathForPhony(ctx, name)) } + if len(alloutputFiles) > 0 { + name := namespacePrefix + ctx.ModuleName() + "-outputs" + ctx.Phony(name, alloutputFiles...) + deps = append(deps, PathForPhony(ctx, name)) + } + if len(deps) > 0 { suffix := "" if ctx.Config().KatiEnabled() { @@ -1708,6 +1724,17 @@ func (m *ModuleBase) generateModuleTarget(ctx *moduleContext) { } ctx.Phony(namespacePrefix+ctx.ModuleName()+suffix, deps...) + if ctx.Device() { + // Generate a target suffix for use in atest etc. + ctx.Phony(namespacePrefix+ctx.ModuleName()+"-target"+suffix, deps...) + } else { + // Generate a host suffix for use in atest etc. + ctx.Phony(namespacePrefix+ctx.ModuleName()+"-host"+suffix, deps...) + if ctx.Target().HostCross { + // Generate a host-cross suffix for use in atest etc. + ctx.Phony(namespacePrefix+ctx.ModuleName()+"-host-cross"+suffix, deps...) + } + } info.BlueprintDir = ctx.ModuleDir() SetProvider(ctx, FinalModuleBuildTargetsProvider, info) @@ -1850,7 +1877,7 @@ type SourceFilesInfo struct { Srcs Paths } -var SourceFilesInfoKey = blueprint.NewProvider[SourceFilesInfo]() +var SourceFilesInfoProvider = blueprint.NewProvider[SourceFilesInfo]() // FinalModuleBuildTargetsInfo is used by buildTargetSingleton to create checkbuild and // per-directory build targets. Only set on the final variant of each module @@ -1871,7 +1898,8 @@ type CommonModuleInfo struct { SkipAndroidMkProcessing bool BaseModuleName string CanHaveApexVariants bool - MinSdkVersion string + MinSdkVersion ApiLevelOrPlatform + SdkVersion string NotAvailableForPlatform bool // There some subtle differences between this one and the one above. NotInPlatform bool @@ -1880,25 +1908,64 @@ type CommonModuleInfo struct { // is used to avoid adding install or packaging dependencies into libraries provided // by apexes. UninstallableApexPlatformVariant bool - HideFromMake bool - SkipInstall bool - IsStubsModule bool - Host bool + MinSdkVersionSupported ApiLevel + ModuleWithMinSdkVersionCheck bool + // Tests if this module can be installed to APEX as a file. For example, this would return + // true for shared libs while return false for static libs because static libs are not + // installable module (but it can still be mutated for APEX) + IsInstallableToApex bool + HideFromMake bool + SkipInstall bool + IsStubsModule bool + Host bool + IsApexModule bool + // The primary licenses property, may be nil, records license metadata for the module. + PrimaryLicensesProperty applicableLicensesProperty + Owner string + Vendor bool + Proprietary bool + SocSpecific bool + ProductSpecific bool + SystemExtSpecific bool + DeviceSpecific bool + // When set to true, this module is not installed to the full install path (ex: under + // out/target/product/<name>/<partition>). It can be installed only to the packaging + // modules like android_filesystem. + NoFullInstall bool + InVendorRamdisk bool + ExemptFromRequiredApplicableLicensesProperty bool + RequiredModuleNames []string + HostRequiredModuleNames []string + TargetRequiredModuleNames []string + VintfFragmentModuleNames []string + Dists []Dist +} + +type ApiLevelOrPlatform struct { + ApiLevel *ApiLevel + IsPlatform bool } var CommonModuleInfoKey = blueprint.NewProvider[CommonModuleInfo]() type PrebuiltModuleInfo struct { SourceExists bool + UsePrebuilt bool } var PrebuiltModuleInfoProvider = blueprint.NewProvider[PrebuiltModuleInfo]() -type HostToolProviderData struct { +type HostToolProviderInfo struct { HostToolPath OptionalPath } -var HostToolProviderKey = blueprint.NewProvider[HostToolProviderData]() +var HostToolProviderInfoProvider = blueprint.NewProvider[HostToolProviderInfo]() + +type DistInfo struct { + Dists []dist +} + +var DistProvider = blueprint.NewProvider[DistInfo]() type SourceFileGenerator interface { GeneratedSourceFiles() Paths @@ -2085,7 +2152,7 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) } if sourceFileProducer, ok := m.module.(SourceFileProducer); ok { - SetProvider(ctx, SourceFilesInfoKey, SourceFilesInfo{Srcs: sourceFileProducer.Srcs()}) + SetProvider(ctx, SourceFilesInfoProvider, SourceFilesInfo{Srcs: sourceFileProducer.Srcs()}) } if ctx.IsFinalModule(m.module) { @@ -2102,47 +2169,84 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) SetProvider(ctx, InstallFilesProvider, installFiles) buildLicenseMetadata(ctx, ctx.licenseMetadataFile) - if ctx.moduleInfoJSON != nil { - var installed InstallPaths - installed = append(installed, ctx.katiInstalls.InstallPaths()...) - installed = append(installed, ctx.katiSymlinks.InstallPaths()...) - installed = append(installed, ctx.katiInitRcInstalls.InstallPaths()...) - installed = append(installed, ctx.katiVintfInstalls.InstallPaths()...) - installedStrings := installed.Strings() - - var targetRequired, hostRequired []string - if ctx.Host() { - targetRequired = m.commonProperties.Target_required - } else { - hostRequired = m.commonProperties.Host_required - } + if len(ctx.moduleInfoJSON) > 0 { + for _, moduleInfoJSON := range ctx.moduleInfoJSON { + if moduleInfoJSON.Disabled { + continue + } + var installed InstallPaths + installed = append(installed, ctx.katiInstalls.InstallPaths()...) + installed = append(installed, ctx.katiSymlinks.InstallPaths()...) + installed = append(installed, ctx.katiInitRcInstalls.InstallPaths()...) + installed = append(installed, ctx.katiVintfInstalls.InstallPaths()...) + installedStrings := installed.Strings() + + var targetRequired, hostRequired []string + if ctx.Host() { + targetRequired = m.baseProperties.Target_required + } else { + hostRequired = m.baseProperties.Host_required + } - var data []string - for _, d := range ctx.testData { - data = append(data, d.ToRelativeInstallPath()) - } + var data []string + for _, d := range ctx.testData { + data = append(data, d.ToRelativeInstallPath()) + } - if ctx.moduleInfoJSON.Uninstallable { - installedStrings = nil - if len(ctx.moduleInfoJSON.CompatibilitySuites) == 1 && ctx.moduleInfoJSON.CompatibilitySuites[0] == "null-suite" { - ctx.moduleInfoJSON.CompatibilitySuites = nil - ctx.moduleInfoJSON.TestConfig = nil - ctx.moduleInfoJSON.AutoTestConfig = nil - data = nil + if moduleInfoJSON.Uninstallable { + installedStrings = nil + if len(moduleInfoJSON.CompatibilitySuites) == 1 && moduleInfoJSON.CompatibilitySuites[0] == "null-suite" { + moduleInfoJSON.CompatibilitySuites = nil + moduleInfoJSON.TestConfig = nil + moduleInfoJSON.AutoTestConfig = nil + data = nil + } + } + + // M(C)TS supports a full test suite and partial per-module MTS test suites, with naming mts-${MODULE}. + // To reduce repetition, if we find a partial M(C)TS test suite without an full M(C)TS test suite, + // we add the full test suite to our list. This was inherited from + // AndroidMkEntries.AddCompatibilityTestSuites. + suites := moduleInfoJSON.CompatibilitySuites + if PrefixInList(suites, "mts-") && !InList("mts", suites) { + suites = append(suites, "mts") + } + if PrefixInList(suites, "mcts-") && !InList("mcts", suites) { + suites = append(suites, "mcts") + } + moduleInfoJSON.CompatibilitySuites = suites + + required := append(m.RequiredModuleNames(ctx), m.VintfFragmentModuleNames(ctx)...) + required = append(required, moduleInfoJSON.ExtraRequired...) + + registerName := moduleInfoJSON.RegisterNameOverride + if len(registerName) == 0 { + registerName = m.moduleInfoRegisterName(ctx, moduleInfoJSON.SubName) + } + + moduleName := moduleInfoJSON.ModuleNameOverride + if len(moduleName) == 0 { + moduleName = m.BaseModuleName() + moduleInfoJSON.SubName + } + + supportedVariants := moduleInfoJSON.SupportedVariantsOverride + if moduleInfoJSON.SupportedVariantsOverride == nil { + supportedVariants = []string{m.moduleInfoVariant(ctx)} } - } - ctx.moduleInfoJSON.core = CoreModuleInfoJSON{ - RegisterName: m.moduleInfoRegisterName(ctx, ctx.moduleInfoJSON.SubName), - Path: []string{ctx.ModuleDir()}, - Installed: installedStrings, - ModuleName: m.BaseModuleName() + ctx.moduleInfoJSON.SubName, - SupportedVariants: []string{m.moduleInfoVariant(ctx)}, - TargetDependencies: targetRequired, - HostDependencies: hostRequired, - Data: data, - Required: append(m.RequiredModuleNames(ctx), m.VintfFragmentModuleNames(ctx)...), + moduleInfoJSON.core = CoreModuleInfoJSON{ + RegisterName: registerName, + Path: []string{ctx.ModuleDir()}, + Installed: installedStrings, + ModuleName: moduleName, + SupportedVariants: supportedVariants, + TargetDependencies: targetRequired, + HostDependencies: hostRequired, + Data: data, + Required: required, + } } + SetProvider(ctx, ModuleInfoJSONProvider, ctx.moduleInfoJSON) } @@ -2160,50 +2264,96 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) Phonies: ctx.phonies, }) } + + if len(ctx.dists) > 0 { + SetProvider(ctx, DistProvider, DistInfo{ + Dists: ctx.dists, + }) + } + buildComplianceMetadataProvider(ctx, m) commonData := CommonModuleInfo{ + Enabled: m.Enabled(ctx), ReplacedByPrebuilt: m.commonProperties.ReplacedByPrebuilt, Target: m.commonProperties.CompileTarget, SkipAndroidMkProcessing: shouldSkipAndroidMkProcessing(ctx, m), - BaseModuleName: m.BaseModuleName(), UninstallableApexPlatformVariant: m.commonProperties.UninstallableApexPlatformVariant, HideFromMake: m.commonProperties.HideFromMake, SkipInstall: m.commonProperties.SkipInstall, Host: m.Host(), + PrimaryLicensesProperty: m.primaryLicensesProperty, + Owner: m.module.Owner(), + SocSpecific: Bool(m.commonProperties.Soc_specific), + Vendor: Bool(m.commonProperties.Vendor), + Proprietary: Bool(m.commonProperties.Proprietary), + ProductSpecific: Bool(m.commonProperties.Product_specific), + SystemExtSpecific: Bool(m.commonProperties.System_ext_specific), + DeviceSpecific: Bool(m.commonProperties.Device_specific), + NoFullInstall: proptools.Bool(m.commonProperties.No_full_install), + InVendorRamdisk: m.InVendorRamdisk(), + ExemptFromRequiredApplicableLicensesProperty: exemptFromRequiredApplicableLicensesProperty(m.module), + RequiredModuleNames: m.module.RequiredModuleNames(ctx), + HostRequiredModuleNames: m.module.HostRequiredModuleNames(), + TargetRequiredModuleNames: m.module.TargetRequiredModuleNames(), + VintfFragmentModuleNames: m.module.VintfFragmentModuleNames(ctx), + Dists: m.Dists(), } if mm, ok := m.module.(interface { MinSdkVersion(ctx EarlyModuleContext) ApiLevel }); ok { ver := mm.MinSdkVersion(ctx) - if !ver.IsNone() { - commonData.MinSdkVersion = ver.String() - } + commonData.MinSdkVersion.ApiLevel = &ver } else if mm, ok := m.module.(interface{ MinSdkVersion() string }); ok { - commonData.MinSdkVersion = mm.MinSdkVersion() + ver := mm.MinSdkVersion() + // Compile against the current platform + if ver == "" { + commonData.MinSdkVersion.IsPlatform = true + } else { + api := ApiLevelFrom(ctx, ver) + commonData.MinSdkVersion.ApiLevel = &api + } } - if m.commonProperties.ForcedDisabled { - commonData.Enabled = false - } else { - commonData.Enabled = m.commonProperties.Enabled.GetOrDefault(m.ConfigurableEvaluator(ctx), !m.Os().DefaultDisabled) + if mm, ok := m.module.(interface { + SdkVersion(ctx EarlyModuleContext) ApiLevel + }); ok { + ver := mm.SdkVersion(ctx) + if !ver.IsNone() { + commonData.SdkVersion = ver.String() + } + } else if mm, ok := m.module.(interface{ SdkVersion() string }); ok { + commonData.SdkVersion = mm.SdkVersion() } + if am, ok := m.module.(ApexModule); ok { commonData.CanHaveApexVariants = am.CanHaveApexVariants() commonData.NotAvailableForPlatform = am.NotAvailableForPlatform() commonData.NotInPlatform = am.NotInPlatform() + commonData.MinSdkVersionSupported = am.MinSdkVersionSupported(ctx) + commonData.IsInstallableToApex = am.IsInstallableToApex() + commonData.IsApexModule = true } + + if _, ok := m.module.(ModuleWithMinSdkVersionCheck); ok { + commonData.ModuleWithMinSdkVersionCheck = true + } + if st, ok := m.module.(StubsAvailableModule); ok { commonData.IsStubsModule = st.IsStubsModule() } + if mm, ok := m.module.(interface{ BaseModuleName() string }); ok { + commonData.BaseModuleName = mm.BaseModuleName() + } SetProvider(ctx, CommonModuleInfoKey, commonData) if p, ok := m.module.(PrebuiltInterface); ok && p.Prebuilt() != nil { SetProvider(ctx, PrebuiltModuleInfoProvider, PrebuiltModuleInfo{ SourceExists: p.Prebuilt().SourceExists(), + UsePrebuilt: p.Prebuilt().UsePrebuilt(), }) } if h, ok := m.module.(HostToolProvider); ok { - SetProvider(ctx, HostToolProviderKey, HostToolProviderData{ + SetProvider(ctx, HostToolProviderInfoProvider, HostToolProviderInfo{ HostToolPath: h.HostToolPath()}) } @@ -2241,7 +2391,7 @@ func (m *ModuleBase) moduleInfoRegisterName(ctx ModuleContext, subName string) s arches = slices.DeleteFunc(arches, func(target Target) bool { return target.NativeBridge != ctx.Target().NativeBridge }) - if len(arches) > 0 && ctx.Arch().ArchType != arches[0].Arch.ArchType { + if len(arches) > 0 && ctx.Arch().ArchType != arches[0].Arch.ArchType && ctx.Arch().ArchType != Common { if ctx.Arch().ArchType.Multilib == "lib32" { suffix = "_32" } else { @@ -2494,6 +2644,8 @@ func (e configurationEvalutor) EvaluateConfiguration(condition proptools.Configu return proptools.ConfigurableValueBool(ctx.Config().BuildFromTextStub()) case "debuggable": return proptools.ConfigurableValueBool(ctx.Config().Debuggable()) + case "eng": + return proptools.ConfigurableValueBool(ctx.Config().Eng()) case "use_debug_art": // TODO(b/234351700): Remove once ART does not have separated debug APEX return proptools.ConfigurableValueBool(ctx.Config().UseDebugArt()) @@ -2784,7 +2936,7 @@ func outputFilesForModule(ctx PathContext, module Module, tag string) (Paths, er if sourceFileProducer, ok := module.(SourceFileProducer); ok { return sourceFileProducer.Srcs(), nil } - } else if sourceFiles, ok := OtherModuleProvider(octx, module, SourceFilesInfoKey); ok { + } else if sourceFiles, ok := OtherModuleProvider(octx, module, SourceFilesInfoProvider); ok { if tag != "" { return nil, fmt.Errorf("module %q is a SourceFileProducer, which does not support tag %q", pathContextName(ctx, module), tag) } @@ -2908,6 +3060,9 @@ func AddAncestors(ctx SingletonContext, dirMap map[string]Paths, mmName func(str func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) { var checkbuildDeps Paths + // Create a top level partialcompileclean target for modules to add dependencies to. + ctx.Phony("partialcompileclean") + mmTarget := func(dir string) string { return "MODULES-IN-" + strings.Replace(filepath.Clean(dir), "/", "-", -1) } |