summaryrefslogtreecommitdiff
path: root/android/module.go
diff options
context:
space:
mode:
Diffstat (limited to 'android/module.go')
-rw-r--r--android/module.go181
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:"-"`