summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Colin Cross <ccross@android.com> 2024-09-17 14:25:45 -0700
committer Colin Cross <ccross@android.com> 2024-09-18 10:14:19 -0700
commitda279cfba47a813407ccd33d07b42dcfc5581882 (patch)
tree34b805e8e329919b74991d7dbe619d4f9ffa39b6
parent167230037c312acbdef1994702f39091dcffbe0a (diff)
Convert trivial TopDown mutators to BottomUp
Many TopDown mutators can be easily converted to BottomUp mutators, which are easier to handle for incremental and partial analysis. Bug: 367784740 Test: all soong tests pass Test: no change to build.ninja Flag: EXEMPT refactor Change-Id: I82955e844ed0eb6680854678c0744ac5398eb7ba
-rw-r--r--android/defaults.go16
-rw-r--r--android/mutator.go16
-rw-r--r--android/visibility.go4
-rw-r--r--apex/apex.go3
-rw-r--r--apex/prebuilt.go14
-rw-r--r--apex/vndk.go45
-rw-r--r--cc/cc.go8
-rw-r--r--cc/fuzz.go2
-rw-r--r--cc/sanitize.go6
9 files changed, 60 insertions, 54 deletions
diff --git a/android/defaults.go b/android/defaults.go
index 0d51d9d7c..d3dbaedcd 100644
--- a/android/defaults.go
+++ b/android/defaults.go
@@ -69,7 +69,7 @@ type Defaultable interface {
// Apply defaults from the supplied Defaults to the property structures supplied to
// setProperties(...).
- applyDefaults(TopDownMutatorContext, []Defaults)
+ applyDefaults(BottomUpMutatorContext, []Defaults)
// Set the hook to be called after any defaults have been applied.
//
@@ -209,7 +209,7 @@ func InitDefaultsModule(module DefaultsModule) {
var _ Defaults = (*DefaultsModuleBase)(nil)
-func (defaultable *DefaultableModuleBase) applyDefaults(ctx TopDownMutatorContext,
+func (defaultable *DefaultableModuleBase) applyDefaults(ctx BottomUpMutatorContext,
defaultsList []Defaults) {
for _, defaults := range defaultsList {
@@ -226,7 +226,7 @@ func (defaultable *DefaultableModuleBase) applyDefaults(ctx TopDownMutatorContex
// Product variable properties need special handling, the type of the filtered product variable
// property struct may not be identical between the defaults module and the defaultable module.
// Use PrependMatchingProperties to apply whichever properties match.
-func (defaultable *DefaultableModuleBase) applyDefaultVariableProperties(ctx TopDownMutatorContext,
+func (defaultable *DefaultableModuleBase) applyDefaultVariableProperties(ctx BottomUpMutatorContext,
defaults Defaults, defaultableProp interface{}) {
if defaultableProp == nil {
return
@@ -254,7 +254,7 @@ func (defaultable *DefaultableModuleBase) applyDefaultVariableProperties(ctx Top
}
}
-func (defaultable *DefaultableModuleBase) applyDefaultProperties(ctx TopDownMutatorContext,
+func (defaultable *DefaultableModuleBase) applyDefaultProperties(ctx BottomUpMutatorContext,
defaults Defaults, defaultableProp interface{}) {
for _, def := range defaults.properties() {
@@ -273,7 +273,7 @@ func (defaultable *DefaultableModuleBase) applyDefaultProperties(ctx TopDownMuta
func RegisterDefaultsPreArchMutators(ctx RegisterMutatorsContext) {
ctx.BottomUp("defaults_deps", defaultsDepsMutator).Parallel()
- ctx.TopDown("defaults", defaultsMutator).Parallel()
+ ctx.BottomUp("defaults", defaultsMutator).Parallel()
}
func defaultsDepsMutator(ctx BottomUpMutatorContext) {
@@ -282,8 +282,12 @@ func defaultsDepsMutator(ctx BottomUpMutatorContext) {
}
}
-func defaultsMutator(ctx TopDownMutatorContext) {
+func defaultsMutator(ctx BottomUpMutatorContext) {
if defaultable, ok := ctx.Module().(Defaultable); ok {
+ if _, isDefaultsModule := ctx.Module().(Defaults); isDefaultsModule {
+ // Don't squash transitive defaults into defaults modules
+ return
+ }
defaults := defaultable.defaults().Defaults
if len(defaults) > 0 {
var defaultsList []Defaults
diff --git a/android/mutator.go b/android/mutator.go
index 2ef4d7fef..6f8990d0e 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -193,16 +193,16 @@ type BaseMutatorContext interface {
// Rename all variants of a module. The new name is not visible to calls to ModuleName,
// AddDependency or OtherModuleName until after this mutator pass is complete.
Rename(name string)
+
+ // CreateModule creates a new module by calling the factory method for the specified moduleType, and applies
+ // the specified property structs to it as if the properties were set in a blueprint file.
+ CreateModule(ModuleFactory, ...interface{}) Module
}
type TopDownMutator func(TopDownMutatorContext)
type TopDownMutatorContext interface {
BaseMutatorContext
-
- // CreateModule creates a new module by calling the factory method for the specified moduleType, and applies
- // the specified property structs to it as if the properties were set in a blueprint file.
- CreateModule(ModuleFactory, ...interface{}) Module
}
type topDownMutatorContext struct {
@@ -739,6 +739,14 @@ func (b *bottomUpMutatorContext) Rename(name string) {
b.Module().base().commonProperties.DebugName = name
}
+func (b *bottomUpMutatorContext) createModule(factory blueprint.ModuleFactory, name string, props ...interface{}) blueprint.Module {
+ return b.bp.CreateModule(factory, name, props...)
+}
+
+func (b *bottomUpMutatorContext) CreateModule(factory ModuleFactory, props ...interface{}) Module {
+ return createModule(b, factory, "_bottomUpMutatorModule", props...)
+}
+
func (b *bottomUpMutatorContext) AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) []blueprint.Module {
if b.baseModuleContext.checkedMissingDeps() {
panic("Adding deps not allowed after checking for missing deps")
diff --git a/android/visibility.go b/android/visibility.go
index 89c0adc15..61f220026 100644
--- a/android/visibility.go
+++ b/android/visibility.go
@@ -283,7 +283,7 @@ func RegisterVisibilityRuleGatherer(ctx RegisterMutatorsContext) {
// This must be registered after the deps have been resolved.
func RegisterVisibilityRuleEnforcer(ctx RegisterMutatorsContext) {
- ctx.TopDown("visibilityRuleEnforcer", visibilityRuleEnforcer).Parallel()
+ ctx.BottomUp("visibilityRuleEnforcer", visibilityRuleEnforcer).Parallel()
}
// Checks the per-module visibility rule lists before defaults expansion.
@@ -507,7 +507,7 @@ func splitRule(ctx BaseModuleContext, ruleExpression string, currentPkg, propert
return true, pkg, name
}
-func visibilityRuleEnforcer(ctx TopDownMutatorContext) {
+func visibilityRuleEnforcer(ctx BottomUpMutatorContext) {
qualified := createVisibilityModuleReference(ctx.ModuleName(), ctx.ModuleDir(), ctx.Module())
// Visit all the dependencies making sure that this module has access to them all.
diff --git a/apex/apex.go b/apex/apex.go
index c12d1e473..9e3f288ce 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -55,11 +55,10 @@ func registerApexBuildComponents(ctx android.RegistrationContext) {
}
func registerPreArchMutators(ctx android.RegisterMutatorsContext) {
- ctx.TopDown("prebuilt_apex_module_creator", prebuiltApexModuleCreatorMutator).Parallel()
+ ctx.BottomUp("prebuilt_apex_module_creator", prebuiltApexModuleCreatorMutator).Parallel()
}
func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) {
- ctx.TopDown("apex_vndk", apexVndkMutator).Parallel()
ctx.BottomUp("apex_vndk_deps", apexVndkDepsMutator).Parallel()
}
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index f1a134eea..792b57188 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -265,7 +265,7 @@ func (p *prebuiltCommon) AndroidMkEntries() []android.AndroidMkEntries {
// prebuiltApexModuleCreator defines the methods that need to be implemented by prebuilt_apex and
// apex_set in order to create the modules needed to provide access to the prebuilt .apex file.
type prebuiltApexModuleCreator interface {
- createPrebuiltApexModules(ctx android.TopDownMutatorContext)
+ createPrebuiltApexModules(ctx android.BottomUpMutatorContext)
}
// prebuiltApexModuleCreatorMutator is the mutator responsible for invoking the
@@ -275,7 +275,7 @@ type prebuiltApexModuleCreator interface {
// will need to access dependencies added by that (exported modules) but must run before the
// DepsMutator so that the deapexer module it creates can add dependencies onto itself from the
// exported modules.
-func prebuiltApexModuleCreatorMutator(ctx android.TopDownMutatorContext) {
+func prebuiltApexModuleCreatorMutator(ctx android.BottomUpMutatorContext) {
module := ctx.Module()
if creator, ok := module.(prebuiltApexModuleCreator); ok {
creator.createPrebuiltApexModules(ctx)
@@ -543,7 +543,7 @@ func PrebuiltFactory() android.Module {
return module
}
-func createApexSelectorModule(ctx android.TopDownMutatorContext, name string, apexFileProperties *ApexFileProperties) {
+func createApexSelectorModule(ctx android.BottomUpMutatorContext, name string, apexFileProperties *ApexFileProperties) {
props := struct {
Name *string
}{
@@ -561,7 +561,7 @@ func createApexSelectorModule(ctx android.TopDownMutatorContext, name string, ap
// A deapexer module is only needed when the prebuilt apex specifies one or more modules in either
// the `exported_java_libs` or `exported_bootclasspath_fragments` properties as that indicates that
// the listed modules need access to files from within the prebuilt .apex file.
-func (p *prebuiltCommon) createDeapexerModuleIfNeeded(ctx android.TopDownMutatorContext, deapexerName string, apexFileSource string) {
+func (p *prebuiltCommon) createDeapexerModuleIfNeeded(ctx android.BottomUpMutatorContext, deapexerName string, apexFileSource string) {
// Only create the deapexer module if it is needed.
if !p.hasExportedDeps() {
return
@@ -703,7 +703,7 @@ var _ prebuiltApexModuleCreator = (*Prebuilt)(nil)
// / | \
// V V V
// selector <--- deapexer <--- exported java lib
-func (p *Prebuilt) createPrebuiltApexModules(ctx android.TopDownMutatorContext) {
+func (p *Prebuilt) createPrebuiltApexModules(ctx android.BottomUpMutatorContext) {
apexSelectorModuleName := apexSelectorModuleName(p.Name())
createApexSelectorModule(ctx, apexSelectorModuleName, &p.properties.ApexFileProperties)
@@ -958,7 +958,7 @@ func apexSetFactory() android.Module {
return module
}
-func createApexExtractorModule(ctx android.TopDownMutatorContext, name string, apexExtractorProperties *ApexExtractorProperties) {
+func createApexExtractorModule(ctx android.BottomUpMutatorContext, name string, apexExtractorProperties *ApexExtractorProperties) {
props := struct {
Name *string
}{
@@ -984,7 +984,7 @@ var _ prebuiltApexModuleCreator = (*ApexSet)(nil)
// prebuilt_apex except that instead of creating a selector module which selects one .apex file
// from those provided this creates an extractor module which extracts the appropriate .apex file
// from the zip file containing them.
-func (a *ApexSet) createPrebuiltApexModules(ctx android.TopDownMutatorContext) {
+func (a *ApexSet) createPrebuiltApexModules(ctx android.BottomUpMutatorContext) {
apexExtractorModuleName := apexExtractorModuleName(a.Name())
createApexExtractorModule(ctx, apexExtractorModuleName, &a.properties.ApexExtractorProperties)
diff --git a/apex/vndk.go b/apex/vndk.go
index 781aa3cbf..3ececc5c1 100644
--- a/apex/vndk.go
+++ b/apex/vndk.go
@@ -54,13 +54,26 @@ type apexVndkProperties struct {
Vndk_version *string
}
-func apexVndkMutator(mctx android.TopDownMutatorContext) {
- if ab, ok := mctx.Module().(*apexBundle); ok && ab.vndkApex {
- if ab.IsNativeBridgeSupported() {
+func apexVndkDepsMutator(mctx android.BottomUpMutatorContext) {
+ if m, ok := mctx.Module().(*cc.Module); ok && cc.IsForVndkApex(mctx, m) {
+ vndkVersion := m.VndkVersion()
+
+ if vndkVersion == "" {
+ return
+ }
+ vndkVersion = "v" + vndkVersion
+
+ vndkApexName := "com.android.vndk." + vndkVersion
+
+ if mctx.OtherModuleExists(vndkApexName) {
+ mctx.AddReverseDependency(mctx.Module(), sharedLibTag, vndkApexName)
+ }
+ } else if a, ok := mctx.Module().(*apexBundle); ok && a.vndkApex {
+ if a.IsNativeBridgeSupported() {
mctx.PropertyErrorf("native_bridge_supported", "%q doesn't support native bridge binary.", mctx.ModuleType())
}
- vndkVersion := ab.vndkVersion()
+ vndkVersion := a.vndkVersion()
if vndkVersion != "" {
apiLevel, err := android.ApiLevelFromUser(mctx, vndkVersion)
if err != nil {
@@ -72,32 +85,14 @@ func apexVndkMutator(mctx android.TopDownMutatorContext) {
if len(targets) > 0 && apiLevel.LessThan(cc.MinApiForArch(mctx, targets[0].Arch.ArchType)) {
// Disable VNDK APEXes for VNDK versions less than the minimum supported API
// level for the primary architecture.
- ab.Disable()
+ a.Disable()
+ } else {
+ mctx.AddDependency(mctx.Module(), prebuiltTag, cc.VndkLibrariesTxtModules(vndkVersion, mctx)...)
}
}
}
}
-func apexVndkDepsMutator(mctx android.BottomUpMutatorContext) {
- if m, ok := mctx.Module().(*cc.Module); ok && cc.IsForVndkApex(mctx, m) {
- vndkVersion := m.VndkVersion()
-
- if vndkVersion == "" {
- return
- }
- vndkVersion = "v" + vndkVersion
-
- vndkApexName := "com.android.vndk." + vndkVersion
-
- if mctx.OtherModuleExists(vndkApexName) {
- mctx.AddReverseDependency(mctx.Module(), sharedLibTag, vndkApexName)
- }
- } else if a, ok := mctx.Module().(*apexBundle); ok && a.vndkApex {
- vndkVersion := proptools.StringDefault(a.vndkProperties.Vndk_version, "current")
- mctx.AddDependency(mctx.Module(), prebuiltTag, cc.VndkLibrariesTxtModules(vndkVersion, mctx)...)
- }
-}
-
// name is module.BaseModuleName() which is used as LOCAL_MODULE_NAME and also LOCAL_OVERRIDES_*
func makeCompatSymlinks(name string, ctx android.ModuleContext) (symlinks android.InstallPaths) {
// small helper to add symlink commands
diff --git a/cc/cc.go b/cc/cc.go
index 6e16142aa..96795d3a9 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -59,10 +59,10 @@ func RegisterCCBuildComponents(ctx android.RegistrationContext) {
san.registerMutators(ctx)
}
- ctx.TopDown("sanitize_runtime_deps", sanitizerRuntimeDepsMutator).Parallel()
+ ctx.BottomUp("sanitize_runtime_deps", sanitizerRuntimeDepsMutator).Parallel()
ctx.BottomUp("sanitize_runtime", sanitizerRuntimeMutator).Parallel()
- ctx.TopDown("fuzz_deps", fuzzMutatorDeps)
+ ctx.BottomUp("fuzz_deps", fuzzMutatorDeps)
ctx.Transition("coverage", &coverageTransitionMutator{})
@@ -73,7 +73,7 @@ func RegisterCCBuildComponents(ctx android.RegistrationContext) {
ctx.Transition("lto", &ltoTransitionMutator{})
ctx.BottomUp("check_linktype", checkLinkTypeMutator).Parallel()
- ctx.TopDown("double_loadable", checkDoubleLoadableLibraries).Parallel()
+ ctx.BottomUp("double_loadable", checkDoubleLoadableLibraries).Parallel()
})
ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) {
@@ -2783,7 +2783,7 @@ func checkLinkTypeMutator(ctx android.BottomUpMutatorContext) {
// If a library has a vendor variant and is a (transitive) dependency of an LLNDK library,
// it is subject to be double loaded. Such lib should be explicitly marked as double_loadable: true
// or as vndk-sp (vndk: { enabled: true, support_system_process: true}).
-func checkDoubleLoadableLibraries(ctx android.TopDownMutatorContext) {
+func checkDoubleLoadableLibraries(ctx android.BottomUpMutatorContext) {
check := func(child, parent android.Module) bool {
to, ok := child.(*Module)
if !ok {
diff --git a/cc/fuzz.go b/cc/fuzz.go
index d9e221b16..3f21bc6e7 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -57,7 +57,7 @@ func (fuzzer *fuzzer) props() []interface{} {
return []interface{}{&fuzzer.Properties}
}
-func fuzzMutatorDeps(mctx android.TopDownMutatorContext) {
+func fuzzMutatorDeps(mctx android.BottomUpMutatorContext) {
currentModule, ok := mctx.Module().(*Module)
if !ok {
return
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 7b0652c38..b10a3dd53 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -176,7 +176,7 @@ func (t SanitizerType) registerMutators(ctx android.RegisterMutatorsContext) {
switch t {
case cfi, Hwasan, Asan, tsan, Fuzzer, scs, Memtag_stack:
sanitizer := &sanitizerSplitMutator{t}
- ctx.TopDown(t.variationName()+"_markapexes", sanitizer.markSanitizableApexesMutator)
+ ctx.BottomUp(t.variationName()+"_markapexes", sanitizer.markSanitizableApexesMutator)
ctx.Transition(t.variationName(), sanitizer)
case Memtag_heap, Memtag_globals, intOverflow:
// do nothing
@@ -1153,7 +1153,7 @@ type sanitizerSplitMutator struct {
// If an APEX is sanitized or not depends on whether it contains at least one
// sanitized module. Transition mutators cannot propagate information up the
// dependency graph this way, so we need an auxiliary mutator to do so.
-func (s *sanitizerSplitMutator) markSanitizableApexesMutator(ctx android.TopDownMutatorContext) {
+func (s *sanitizerSplitMutator) markSanitizableApexesMutator(ctx android.BottomUpMutatorContext) {
if sanitizeable, ok := ctx.Module().(Sanitizeable); ok {
enabled := sanitizeable.IsSanitizerEnabled(ctx.Config(), s.sanitizer.name())
ctx.VisitDirectDeps(func(dep android.Module) {
@@ -1355,7 +1355,7 @@ func (c *Module) IsSanitizerExplicitlyDisabled(t SanitizerType) bool {
}
// Propagate the ubsan minimal runtime dependency when there are integer overflow sanitized static dependencies.
-func sanitizerRuntimeDepsMutator(mctx android.TopDownMutatorContext) {
+func sanitizerRuntimeDepsMutator(mctx android.BottomUpMutatorContext) {
// Change this to PlatformSanitizable when/if non-cc modules support ubsan sanitizers.
if c, ok := mctx.Module().(*Module); ok && c.sanitize != nil {
if c.sanitize.Properties.ForceDisable {