diff options
Diffstat (limited to 'android/module.go')
-rw-r--r-- | android/module.go | 181 |
1 files changed, 106 insertions, 75 deletions
diff --git a/android/module.go b/android/module.go index d387c2cf3..a3fe837a5 100644 --- a/android/module.go +++ b/android/module.go @@ -15,6 +15,7 @@ package android import ( + "errors" "fmt" "net/url" "path/filepath" @@ -519,6 +520,11 @@ type baseProperties struct { // names of other modules to install on target if this module is installed Target_required []string `android:"arch_variant"` + + // If this is a soong config module, this property will be set to the name of the original + // module type. This is used by neverallow to ensure you can't bypass a ModuleType() matcher + // just by creating a soong config module type. + Soong_config_base_module_type *string `blueprint:"mutated"` } type distProperties struct { @@ -996,11 +1002,19 @@ func (m *ModuleBase) baseDepsMutator(ctx BottomUpMutatorContext) { pv := ctx.Config().productVariables fullManifest := pv.DeviceArch != nil && pv.DeviceName != nil if fullManifest { - addRequiredDeps(ctx) addVintfFragmentDeps(ctx) } } +// required property can be overridden too; handle it separately +func (m *ModuleBase) baseOverridablePropertiesDepsMutator(ctx BottomUpMutatorContext) { + pv := ctx.Config().productVariables + fullManifest := pv.DeviceArch != nil && pv.DeviceName != nil + if fullManifest { + addRequiredDeps(ctx) + } +} + // addRequiredDeps adds required, target_required, and host_required as dependencies. func addRequiredDeps(ctx BottomUpMutatorContext) { addDep := func(target Target, depName string) { @@ -1219,6 +1233,13 @@ func (m *ModuleBase) GenerateTaggedDistFiles(ctx BaseModuleContext) TaggedDistFi tag := proptools.StringDefault(dist.Tag, DefaultDistTag) distFileForTagFromProvider, err := outputFilesForModuleFromProvider(ctx, m.module, tag) + + // If the module doesn't define output files for the DefaultDistTag, try the files under + // the "" tag. + if tag == DefaultDistTag && errors.Is(err, ErrUnsupportedOutputTag) { + distFileForTagFromProvider, err = outputFilesForModuleFromProvider(ctx, m.module, "") + } + if err != OutputFilesProviderNotSet { if err != nil && tag != DefaultDistTag { ctx.PropertyErrorf("dist.tag", "%s", err.Error()) @@ -1475,7 +1496,7 @@ func (m *ModuleBase) computeInstallDeps(ctx ModuleContext) ([]depset.DepSet[Inst // Installation is still handled by Make, so anything hidden from Make is not // installable. info := OtherModuleProviderOrDefault(ctx, dep, InstallFilesProvider) - commonInfo := OtherModuleProviderOrDefault(ctx, dep, CommonModuleInfoKey) + commonInfo := OtherModulePointerProviderOrDefault(ctx, dep, CommonModuleInfoProvider) if !commonInfo.HideFromMake && !commonInfo.SkipInstall { installDeps = append(installDeps, info.TransitiveInstallFiles) } @@ -1492,7 +1513,7 @@ func (m *ModuleBase) computeInstallDeps(ctx ModuleContext) ([]depset.DepSet[Inst // should also install the output files of the given dependency and dependency tag. func isInstallDepNeeded(ctx ModuleContext, dep ModuleProxy) bool { // Don't add a dependency from the platform to a library provided by an apex. - if OtherModuleProviderOrDefault(ctx, dep, CommonModuleInfoKey).UninstallableApexPlatformVariant { + if OtherModulePointerProviderOrDefault(ctx, dep, CommonModuleInfoProvider).UninstallableApexPlatformVariant { return false } // Only install modules if the dependency tag is an InstallDepNeeded tag. @@ -1646,38 +1667,10 @@ func (m *ModuleBase) generateVariantTarget(ctx *moduleContext) { } +// generateModuleTarget generates phony targets so that you can do `m <module-name>`. +// It will be run on every variant of the module, so it relies on the fact that phony targets +// are deduped to merge all the deps from different variants together. 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 - var skipAndroidMkProcessing bool - if ctx.EqualModules(m.module, module) { - allInstalledFiles = append(allInstalledFiles, ctx.installFiles...) - checkbuildTarget = ctx.checkbuildTarget - uncheckedModule = ctx.uncheckedModule - skipAndroidMkProcessing = shouldSkipAndroidMkProcessing(ctx, m) - } else { - info := OtherModuleProviderOrDefault(ctx, module, InstallFilesProvider) - allInstalledFiles = append(allInstalledFiles, info.InstallFiles...) - checkbuildTarget = info.CheckbuildTarget - 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 - // for the current build target. - if (!ctx.Config().KatiEnabled() || !skipAndroidMkProcessing) && !uncheckedModule && checkbuildTarget != nil { - allCheckbuildTargets = append(allCheckbuildTargets, checkbuildTarget) - } - }) - var namespacePrefix string nameSpace := ctx.Namespace().Path if nameSpace != "." { @@ -1685,25 +1678,30 @@ func (m *ModuleBase) generateModuleTarget(ctx *moduleContext) { } var deps Paths - var info FinalModuleBuildTargetsInfo + var info ModuleBuildTargetsInfo - if len(allInstalledFiles) > 0 { + if len(ctx.installFiles) > 0 { name := namespacePrefix + ctx.ModuleName() + "-install" - ctx.Phony(name, allInstalledFiles.Paths()...) + installFiles := ctx.installFiles.Paths() + ctx.Phony(name, installFiles...) info.InstallTarget = PathForPhony(ctx, name) - deps = append(deps, info.InstallTarget) + deps = append(deps, installFiles...) } - if len(allCheckbuildTargets) > 0 { + // 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 + // for the current build target. + if (!ctx.Config().KatiEnabled() || !shouldSkipAndroidMkProcessing(ctx, m)) && !ctx.uncheckedModule && ctx.checkbuildTarget != nil { name := namespacePrefix + ctx.ModuleName() + "-checkbuild" - ctx.Phony(name, allCheckbuildTargets...) - deps = append(deps, PathForPhony(ctx, name)) + ctx.Phony(name, ctx.checkbuildTarget) + deps = append(deps, ctx.checkbuildTarget) } - if len(alloutputFiles) > 0 { + if outputFiles, err := outputFilesForModule(ctx, ctx.Module(), ""); err == nil && len(outputFiles) > 0 { name := namespacePrefix + ctx.ModuleName() + "-outputs" - ctx.Phony(name, alloutputFiles...) - deps = append(deps, PathForPhony(ctx, name)) + ctx.Phony(name, outputFiles...) + deps = append(deps, outputFiles...) } if len(deps) > 0 { @@ -1726,7 +1724,7 @@ func (m *ModuleBase) generateModuleTarget(ctx *moduleContext) { } info.BlueprintDir = ctx.ModuleDir() - SetProvider(ctx, FinalModuleBuildTargetsProvider, info) + SetProvider(ctx, ModuleBuildTargetsProvider, info) } } @@ -1868,15 +1866,15 @@ type SourceFilesInfo struct { 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 -type FinalModuleBuildTargetsInfo struct { +// ModuleBuildTargetsInfo is used by buildTargetSingleton to create checkbuild and +// per-directory build targets. +type ModuleBuildTargetsInfo struct { InstallTarget WritablePath CheckbuildTarget WritablePath BlueprintDir string } -var FinalModuleBuildTargetsProvider = blueprint.NewProvider[FinalModuleBuildTargetsInfo]() +var ModuleBuildTargetsProvider = blueprint.NewProvider[ModuleBuildTargetsInfo]() type CommonModuleInfo struct { Enabled bool @@ -1928,6 +1926,9 @@ type CommonModuleInfo struct { TargetRequiredModuleNames []string VintfFragmentModuleNames []string Dists []Dist + ExportedToMake bool + Team string + PartitionTag string } type ApiLevelOrPlatform struct { @@ -1935,7 +1936,7 @@ type ApiLevelOrPlatform struct { IsPlatform bool } -var CommonModuleInfoKey = blueprint.NewProvider[CommonModuleInfo]() +var CommonModuleInfoProvider = blueprint.NewProvider[*CommonModuleInfo]() type PrebuiltModuleInfo struct { SourceExists bool @@ -2141,14 +2142,19 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) } if sourceFileProducer, ok := m.module.(SourceFileProducer); ok { + srcs := sourceFileProducer.Srcs() + for _, src := range srcs { + if src == nil { + ctx.ModuleErrorf("SourceFileProducer cannot return nil srcs") + return + } + } SetProvider(ctx, SourceFilesInfoProvider, SourceFilesInfo{Srcs: sourceFileProducer.Srcs()}) } - if ctx.IsFinalModule(m.module) { - m.generateModuleTarget(ctx) - if ctx.Failed() { - return - } + m.generateModuleTarget(ctx) + if ctx.Failed() { + return } ctx.TransitiveInstallFiles = depset.New[InstallPath](depset.TOPOLOGICAL, ctx.installFiles, dependencyInstallFiles) @@ -2176,6 +2182,7 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) } else { hostRequired = m.baseProperties.Host_required } + hostRequired = append(hostRequired, moduleInfoJSON.ExtraHostRequired...) var data []string for _, d := range ctx.testData { @@ -2287,6 +2294,9 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) TargetRequiredModuleNames: m.module.TargetRequiredModuleNames(), VintfFragmentModuleNames: m.module.VintfFragmentModuleNames(ctx), Dists: m.Dists(), + ExportedToMake: m.ExportedToMake(), + Team: m.Team(), + PartitionTag: m.PartitionTag(ctx.DeviceConfig()), } if mm, ok := m.module.(interface { MinSdkVersion(ctx EarlyModuleContext) ApiLevel @@ -2334,7 +2344,7 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) if mm, ok := m.module.(interface{ BaseModuleName() string }); ok { commonData.BaseModuleName = mm.BaseModuleName() } - SetProvider(ctx, CommonModuleInfoKey, commonData) + SetProvider(ctx, CommonModuleInfoProvider, &commonData) if p, ok := m.module.(PrebuiltInterface); ok && p.Prebuilt() != nil { SetProvider(ctx, PrebuiltModuleInfoProvider, PrebuiltModuleInfo{ SourceExists: p.Prebuilt().SourceExists(), @@ -2357,6 +2367,18 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) GeneratedDeps: s.GeneratedDeps(), }) } + + if m.Enabled(ctx) { + if v, ok := m.module.(ModuleMakeVarsProvider); ok { + SetProvider(ctx, ModuleMakeVarsInfoProvider, v.MakeVars(ctx)) + } + + if am, ok := m.module.(AndroidMkDataProvider); ok { + SetProvider(ctx, AndroidMkDataInfoProvider, AndroidMkDataInfo{ + Class: am.AndroidMk().Class, + }) + } + } } func SetJarJarPrefixHandler(handler func(ModuleContext)) { @@ -2640,6 +2662,8 @@ func (e configurationEvalutor) EvaluateConfiguration(condition proptools.Configu return proptools.ConfigurableValueBool(ctx.Config().UseDebugArt()) case "selinux_ignore_neverallows": return proptools.ConfigurableValueBool(ctx.Config().SelinuxIgnoreNeverallows()) + case "always_use_prebuilt_sdks": + return proptools.ConfigurableValueBool(ctx.Config().AlwaysUsePrebuiltSdks()) default: // TODO(b/323382414): Might add these on a case-by-case basis ctx.OtherModulePropertyErrorf(m, property, fmt.Sprintf("TODO(b/323382414): Product variable %q is not yet supported in selects", variable)) @@ -2873,6 +2897,8 @@ func OutputFilesForModule(ctx PathContext, module Module, tag string) Paths { // OutputFileForModule returns the output file paths with the given tag. On error, including if the // module produced zero or multiple paths, it reports errors to the ctx and returns nil. +// TODO(b/397766191): Change the signature to take ModuleProxy +// Please only access the module's internal data through providers. func OutputFileForModule(ctx PathContext, module Module, tag string) Path { paths, err := outputFilesForModule(ctx, module, tag) if err != nil { @@ -2910,9 +2936,10 @@ type OutputFilesProviderModuleContext interface { OtherModuleProviderContext Module() Module GetOutputFiles() OutputFilesInfo - EqualModules(m1, m2 Module) bool } +// TODO(b/397766191): Change the signature to take ModuleProxy +// Please only access the module's internal data through providers. func outputFilesForModule(ctx PathContext, module Module, tag string) (Paths, error) { outputFilesFromProvider, err := outputFilesForModuleFromProvider(ctx, module, tag) if outputFilesFromProvider != nil || err != OutputFilesProviderNotSet { @@ -2920,7 +2947,7 @@ func outputFilesForModule(ctx PathContext, module Module, tag string) (Paths, er } if octx, ok := ctx.(OutputFilesProviderModuleContext); ok { - if octx.EqualModules(octx.Module(), module) { + if EqualModules(octx.Module(), module) { // It is the current module, we can access the srcs through interface if sourceFileProducer, ok := module.(SourceFileProducer); ok { return sourceFileProducer.Srcs(), nil @@ -2945,14 +2972,12 @@ func outputFilesForModule(ctx PathContext, module Module, tag string) (Paths, er // If a module doesn't have the OutputFilesProvider, nil is returned. func outputFilesForModuleFromProvider(ctx PathContext, module Module, tag string) (Paths, error) { var outputFiles OutputFilesInfo - fromProperty := false if mctx, isMctx := ctx.(OutputFilesProviderModuleContext); isMctx { - if !mctx.EqualModules(mctx.Module(), module) { + if !EqualModules(mctx.Module(), module) { outputFiles, _ = OtherModuleProvider(mctx, module, OutputFilesProvider) } else { outputFiles = mctx.GetOutputFiles() - fromProperty = true } } else if cta, isCta := ctx.(*singletonContextAdaptor); isCta { outputFiles, _ = OtherModuleProvider(cta, module, OutputFilesProvider) @@ -2969,10 +2994,8 @@ func outputFilesForModuleFromProvider(ctx PathContext, module Module, tag string } else if taggedOutputFiles, hasTag := outputFiles.TaggedOutputFiles[tag]; hasTag { return taggedOutputFiles, nil } else { - if fromProperty { - return nil, fmt.Errorf("unsupported tag %q for module getting its own output files", tag) - } else { - return nil, fmt.Errorf("unsupported module reference tag %q", tag) + return nil, UnsupportedOutputTagError{ + tag: tag, } } } @@ -2991,8 +3014,24 @@ type OutputFilesInfo struct { var OutputFilesProvider = blueprint.NewProvider[OutputFilesInfo]() +type UnsupportedOutputTagError struct { + tag string +} + +func (u UnsupportedOutputTagError) Error() string { + return fmt.Sprintf("unsupported output tag %q", u.tag) +} + +func (u UnsupportedOutputTagError) Is(e error) bool { + _, ok := e.(UnsupportedOutputTagError) + return ok +} + +var _ error = UnsupportedOutputTagError{} + // This is used to mark the case where OutputFilesProvider is not set on some modules. var OutputFilesProviderNotSet = fmt.Errorf("No output files from provider") +var ErrUnsupportedOutputTag = UnsupportedOutputTagError{} // Modules can implement HostToolProvider and return a valid OptionalPath from HostToolPath() to // specify that they can be used as a tool by a genrule module. @@ -3058,8 +3097,8 @@ func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) { modulesInDir := make(map[string]Paths) - ctx.VisitAllModules(func(module Module) { - info := OtherModuleProviderOrDefault(ctx, module, FinalModuleBuildTargetsProvider) + ctx.VisitAllModuleProxies(func(module ModuleProxy) { + info := OtherModuleProviderOrDefault(ctx, module, ModuleBuildTargetsProvider) if info.CheckbuildTarget != nil { checkbuildDeps = append(checkbuildDeps, info.CheckbuildTarget) @@ -3141,14 +3180,6 @@ type IDEInfo interface { BaseModuleName() string } -// Extract the base module name from the Import name. -// Often the Import name has a prefix "prebuilt_". -// Remove the prefix explicitly if needed -// until we find a better solution to get the Import name. -type IDECustomizedModuleName interface { - IDECustomizedModuleName() string -} - // Collect information for opening IDE project files in java/jdeps.go. type IdeInfo struct { BaseModuleName string `json:"-"` |