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", <oTransitionMutator{}) 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 {