1// Copyright 2015 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package android 16 17import ( 18 "sync" 19 20 "github.com/google/blueprint" 21) 22 23// Phases: 24// run Pre-arch mutators 25// run archMutator 26// run Pre-deps mutators 27// run depsMutator 28// run PostDeps mutators 29// run FinalDeps mutators (CreateVariations disallowed in this phase) 30// continue on to GenerateAndroidBuildActions 31 32// collateGloballyRegisteredMutators constructs the list of mutators that have been registered 33// with the InitRegistrationContext and will be used at runtime. 34func collateGloballyRegisteredMutators() sortableComponents { 35 return collateRegisteredMutators(preArch, preDeps, postDeps, finalDeps) 36} 37 38// collateRegisteredMutators constructs a single list of mutators from the separate lists. 39func collateRegisteredMutators(preArch, preDeps, postDeps, finalDeps []RegisterMutatorFunc) sortableComponents { 40 mctx := ®isterMutatorsContext{} 41 42 register := func(funcs []RegisterMutatorFunc) { 43 for _, f := range funcs { 44 f(mctx) 45 } 46 } 47 48 register(preArch) 49 50 register(preDeps) 51 52 register([]RegisterMutatorFunc{registerDepsMutator}) 53 54 register(postDeps) 55 56 mctx.finalPhase = true 57 register(finalDeps) 58 59 return mctx.mutators 60} 61 62type registerMutatorsContext struct { 63 mutators sortableComponents 64 finalPhase bool 65} 66 67type RegisterMutatorsContext interface { 68 TopDown(name string, m TopDownMutator) MutatorHandle 69 BottomUp(name string, m BottomUpMutator) MutatorHandle 70 BottomUpBlueprint(name string, m blueprint.BottomUpMutator) MutatorHandle 71 Transition(name string, m TransitionMutator) 72} 73 74type RegisterMutatorFunc func(RegisterMutatorsContext) 75 76var preArch = []RegisterMutatorFunc{ 77 RegisterNamespaceMutator, 78 79 // Check the visibility rules are valid. 80 // 81 // This must run after the package renamer mutators so that any issues found during 82 // validation of the package's default_visibility property are reported using the 83 // correct package name and not the synthetic name. 84 // 85 // This must also be run before defaults mutators as the rules for validation are 86 // different before checking the rules than they are afterwards. e.g. 87 // visibility: ["//visibility:private", "//visibility:public"] 88 // would be invalid if specified in a module definition but is valid if it results 89 // from something like this: 90 // 91 // defaults { 92 // name: "defaults", 93 // // Be inaccessible outside a package by default. 94 // visibility: ["//visibility:private"] 95 // } 96 // 97 // defaultable_module { 98 // name: "defaultable_module", 99 // defaults: ["defaults"], 100 // // Override the default. 101 // visibility: ["//visibility:public"] 102 // } 103 // 104 RegisterVisibilityRuleChecker, 105 106 // Record the default_applicable_licenses for each package. 107 // 108 // This must run before the defaults so that defaults modules can pick up the package default. 109 RegisterLicensesPackageMapper, 110 111 // Apply properties from defaults modules to the referencing modules. 112 // 113 // Any mutators that are added before this will not see any modules created by 114 // a DefaultableHook. 115 RegisterDefaultsPreArchMutators, 116 117 // Add dependencies on any components so that any component references can be 118 // resolved within the deps mutator. 119 // 120 // Must be run after defaults so it can be used to create dependencies on the 121 // component modules that are creating in a DefaultableHook. 122 // 123 // Must be run before RegisterPrebuiltsPreArchMutators, i.e. before prebuilts are 124 // renamed. That is so that if a module creates components using a prebuilt module 125 // type that any dependencies (which must use prebuilt_ prefixes) are resolved to 126 // the prebuilt module and not the source module. 127 RegisterComponentsMutator, 128 129 // Create an association between prebuilt modules and their corresponding source 130 // modules (if any). 131 // 132 // Must be run after defaults mutators to ensure that any modules created by 133 // a DefaultableHook can be either a prebuilt or a source module with a matching 134 // prebuilt. 135 RegisterPrebuiltsPreArchMutators, 136 137 // Gather the licenses properties for all modules for use during expansion and enforcement. 138 // 139 // This must come after the defaults mutators to ensure that any licenses supplied 140 // in a defaults module has been successfully applied before the rules are gathered. 141 RegisterLicensesPropertyGatherer, 142 143 // Gather the visibility rules for all modules for us during visibility enforcement. 144 // 145 // This must come after the defaults mutators to ensure that any visibility supplied 146 // in a defaults module has been successfully applied before the rules are gathered. 147 RegisterVisibilityRuleGatherer, 148} 149 150func registerArchMutator(ctx RegisterMutatorsContext) { 151 ctx.BottomUpBlueprint("os", osMutator).Parallel() 152 ctx.BottomUp("image", imageMutator).Parallel() 153 ctx.BottomUpBlueprint("arch", archMutator).Parallel() 154} 155 156var preDeps = []RegisterMutatorFunc{ 157 registerArchMutator, 158} 159 160var postDeps = []RegisterMutatorFunc{ 161 registerPathDepsMutator, 162 RegisterPrebuiltsPostDepsMutators, 163 RegisterVisibilityRuleEnforcer, 164 RegisterLicensesDependencyChecker, 165 registerNeverallowMutator, 166 RegisterOverridePostDepsMutators, 167} 168 169var finalDeps = []RegisterMutatorFunc{} 170 171func PreArchMutators(f RegisterMutatorFunc) { 172 preArch = append(preArch, f) 173} 174 175func PreDepsMutators(f RegisterMutatorFunc) { 176 preDeps = append(preDeps, f) 177} 178 179func PostDepsMutators(f RegisterMutatorFunc) { 180 postDeps = append(postDeps, f) 181} 182 183func FinalDepsMutators(f RegisterMutatorFunc) { 184 finalDeps = append(finalDeps, f) 185} 186 187type BaseMutatorContext interface { 188 BaseModuleContext 189 190 // MutatorName returns the name that this mutator was registered with. 191 MutatorName() string 192 193 // Rename all variants of a module. The new name is not visible to calls to ModuleName, 194 // AddDependency or OtherModuleName until after this mutator pass is complete. 195 Rename(name string) 196} 197 198type TopDownMutator func(TopDownMutatorContext) 199 200type TopDownMutatorContext interface { 201 BaseMutatorContext 202 203 // CreateModule creates a new module by calling the factory method for the specified moduleType, and applies 204 // the specified property structs to it as if the properties were set in a blueprint file. 205 CreateModule(ModuleFactory, ...interface{}) Module 206} 207 208type topDownMutatorContext struct { 209 bp blueprint.TopDownMutatorContext 210 baseModuleContext 211} 212 213type BottomUpMutator func(BottomUpMutatorContext) 214 215type BottomUpMutatorContext interface { 216 BaseMutatorContext 217 218 // AddDependency adds a dependency to the given module. It returns a slice of modules for each 219 // dependency (some entries may be nil). 220 // 221 // If the mutator is parallel (see MutatorHandle.Parallel), this method will pause until the 222 // new dependencies have had the current mutator called on them. If the mutator is not 223 // parallel this method does not affect the ordering of the current mutator pass, but will 224 // be ordered correctly for all future mutator passes. 225 AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) []blueprint.Module 226 227 // AddReverseDependency adds a dependency from the destination to the given module. 228 // Does not affect the ordering of the current mutator pass, but will be ordered 229 // correctly for all future mutator passes. All reverse dependencies for a destination module are 230 // collected until the end of the mutator pass, sorted by name, and then appended to the destination 231 // module's dependency list. 232 AddReverseDependency(module blueprint.Module, tag blueprint.DependencyTag, name string) 233 234 // CreateVariations splits a module into multiple variants, one for each name in the variationNames 235 // parameter. It returns a list of new modules in the same order as the variationNames 236 // list. 237 // 238 // If any of the dependencies of the module being operated on were already split 239 // by calling CreateVariations with the same name, the dependency will automatically 240 // be updated to point the matching variant. 241 // 242 // If a module is split, and then a module depending on the first module is not split 243 // when the Mutator is later called on it, the dependency of the depending module will 244 // automatically be updated to point to the first variant. 245 CreateVariations(...string) []Module 246 247 // CreateLocationVariations splits a module into multiple variants, one for each name in the variantNames 248 // parameter. It returns a list of new modules in the same order as the variantNames 249 // list. 250 // 251 // Local variations do not affect automatic dependency resolution - dependencies added 252 // to the split module via deps or DynamicDependerModule must exactly match a variant 253 // that contains all the non-local variations. 254 CreateLocalVariations(...string) []Module 255 256 // SetDependencyVariation sets all dangling dependencies on the current module to point to the variation 257 // with given name. This function ignores the default variation set by SetDefaultDependencyVariation. 258 SetDependencyVariation(string) 259 260 // SetDefaultDependencyVariation sets the default variation when a dangling reference is detected 261 // during the subsequent calls on Create*Variations* functions. To reset, set it to nil. 262 SetDefaultDependencyVariation(*string) 263 264 // AddVariationDependencies adds deps as dependencies of the current module, but uses the variations 265 // argument to select which variant of the dependency to use. It returns a slice of modules for 266 // each dependency (some entries may be nil). A variant of the dependency must exist that matches 267 // all the non-local variations of the current module, plus the variations argument. 268 // 269 // If the mutator is parallel (see MutatorHandle.Parallel), this method will pause until the 270 // new dependencies have had the current mutator called on them. If the mutator is not 271 // parallel this method does not affect the ordering of the current mutator pass, but will 272 // be ordered correctly for all future mutator passes. 273 AddVariationDependencies(variations []blueprint.Variation, tag blueprint.DependencyTag, names ...string) []blueprint.Module 274 275 // AddFarVariationDependencies adds deps as dependencies of the current module, but uses the 276 // variations argument to select which variant of the dependency to use. It returns a slice of 277 // modules for each dependency (some entries may be nil). A variant of the dependency must 278 // exist that matches the variations argument, but may also have other variations. 279 // For any unspecified variation the first variant will be used. 280 // 281 // Unlike AddVariationDependencies, the variations of the current module are ignored - the 282 // dependency only needs to match the supplied variations. 283 // 284 // If the mutator is parallel (see MutatorHandle.Parallel), this method will pause until the 285 // new dependencies have had the current mutator called on them. If the mutator is not 286 // parallel this method does not affect the ordering of the current mutator pass, but will 287 // be ordered correctly for all future mutator passes. 288 AddFarVariationDependencies([]blueprint.Variation, blueprint.DependencyTag, ...string) []blueprint.Module 289 290 // AddInterVariantDependency adds a dependency between two variants of the same module. Variants are always 291 // ordered in the same orderas they were listed in CreateVariations, and AddInterVariantDependency does not change 292 // that ordering, but it associates a DependencyTag with the dependency and makes it visible to VisitDirectDeps, 293 // WalkDeps, etc. 294 AddInterVariantDependency(tag blueprint.DependencyTag, from, to blueprint.Module) 295 296 // ReplaceDependencies finds all the variants of the module with the specified name, then 297 // replaces all dependencies onto those variants with the current variant of this module. 298 // Replacements don't take effect until after the mutator pass is finished. 299 ReplaceDependencies(string) 300 301 // ReplaceDependenciesIf finds all the variants of the module with the specified name, then 302 // replaces all dependencies onto those variants with the current variant of this module 303 // as long as the supplied predicate returns true. 304 // Replacements don't take effect until after the mutator pass is finished. 305 ReplaceDependenciesIf(string, blueprint.ReplaceDependencyPredicate) 306 307 // AliasVariation takes a variationName that was passed to CreateVariations for this module, 308 // and creates an alias from the current variant (before the mutator has run) to the new 309 // variant. The alias will be valid until the next time a mutator calls CreateVariations or 310 // CreateLocalVariations on this module without also calling AliasVariation. The alias can 311 // be used to add dependencies on the newly created variant using the variant map from 312 // before CreateVariations was run. 313 AliasVariation(variationName string) 314 315 // CreateAliasVariation takes a toVariationName that was passed to CreateVariations for this 316 // module, and creates an alias from a new fromVariationName variant the toVariationName 317 // variant. The alias will be valid until the next time a mutator calls CreateVariations or 318 // CreateLocalVariations on this module without also calling AliasVariation. The alias can 319 // be used to add dependencies on the toVariationName variant using the fromVariationName 320 // variant. 321 CreateAliasVariation(fromVariationName, toVariationName string) 322 323 // SetVariationProvider sets the value for a provider for the given newly created variant of 324 // the current module, i.e. one of the Modules returned by CreateVariations.. It panics if 325 // not called during the appropriate mutator or GenerateBuildActions pass for the provider, 326 // if the value is not of the appropriate type, or if the module is not a newly created 327 // variant of the current module. The value should not be modified after being passed to 328 // SetVariationProvider. 329 SetVariationProvider(module blueprint.Module, provider blueprint.AnyProviderKey, value interface{}) 330} 331 332// An outgoingTransitionContextImpl and incomingTransitionContextImpl is created for every dependency of every module 333// for each transition mutator. bottomUpMutatorContext and topDownMutatorContext are created once for every module 334// for every BottomUp or TopDown mutator. Use a global pool for each to avoid reallocating every time. 335var ( 336 outgoingTransitionContextPool = sync.Pool{ 337 New: func() any { return &outgoingTransitionContextImpl{} }, 338 } 339 incomingTransitionContextPool = sync.Pool{ 340 New: func() any { return &incomingTransitionContextImpl{} }, 341 } 342 bottomUpMutatorContextPool = sync.Pool{ 343 New: func() any { return &bottomUpMutatorContext{} }, 344 } 345 346 topDownMutatorContextPool = sync.Pool{ 347 New: func() any { return &topDownMutatorContext{} }, 348 } 349) 350 351type bottomUpMutatorContext struct { 352 bp blueprint.BottomUpMutatorContext 353 baseModuleContext 354 finalPhase bool 355} 356 357// callers must immediately follow the call to this function with defer bottomUpMutatorContextPool.Put(mctx). 358func bottomUpMutatorContextFactory(ctx blueprint.BottomUpMutatorContext, a Module, 359 finalPhase bool) BottomUpMutatorContext { 360 361 moduleContext := a.base().baseModuleContextFactory(ctx) 362 mctx := bottomUpMutatorContextPool.Get().(*bottomUpMutatorContext) 363 *mctx = bottomUpMutatorContext{ 364 bp: ctx, 365 baseModuleContext: moduleContext, 366 finalPhase: finalPhase, 367 } 368 return mctx 369} 370 371func (x *registerMutatorsContext) BottomUp(name string, m BottomUpMutator) MutatorHandle { 372 finalPhase := x.finalPhase 373 f := func(ctx blueprint.BottomUpMutatorContext) { 374 if a, ok := ctx.Module().(Module); ok { 375 mctx := bottomUpMutatorContextFactory(ctx, a, finalPhase) 376 defer bottomUpMutatorContextPool.Put(mctx) 377 m(mctx) 378 } 379 } 380 mutator := &mutator{name: x.mutatorName(name), bottomUpMutator: f} 381 x.mutators = append(x.mutators, mutator) 382 return mutator 383} 384 385func (x *registerMutatorsContext) BottomUpBlueprint(name string, m blueprint.BottomUpMutator) MutatorHandle { 386 mutator := &mutator{name: name, bottomUpMutator: m} 387 x.mutators = append(x.mutators, mutator) 388 return mutator 389} 390 391type IncomingTransitionContext interface { 392 ArchModuleContext 393 ModuleProviderContext 394 395 // Module returns the target of the dependency edge for which the transition 396 // is being computed 397 Module() Module 398 399 // Config returns the configuration for the build. 400 Config() Config 401 402 DeviceConfig() DeviceConfig 403} 404 405type OutgoingTransitionContext interface { 406 ArchModuleContext 407 ModuleProviderContext 408 409 // Module returns the target of the dependency edge for which the transition 410 // is being computed 411 Module() Module 412 413 // DepTag() Returns the dependency tag through which this dependency is 414 // reached 415 DepTag() blueprint.DependencyTag 416 417 // Config returns the configuration for the build. 418 Config() Config 419 420 DeviceConfig() DeviceConfig 421} 422 423// TransitionMutator implements a top-down mechanism where a module tells its 424// direct dependencies what variation they should be built in but the dependency 425// has the final say. 426// 427// When implementing a transition mutator, one needs to implement four methods: 428// - Split() that tells what variations a module has by itself 429// - OutgoingTransition() where a module tells what it wants from its 430// dependency 431// - IncomingTransition() where a module has the final say about its own 432// variation 433// - Mutate() that changes the state of a module depending on its variation 434// 435// That the effective variation of module B when depended on by module A is the 436// composition the outgoing transition of module A and the incoming transition 437// of module B. 438// 439// the outgoing transition should not take the properties of the dependency into 440// account, only those of the module that depends on it. For this reason, the 441// dependency is not even passed into it as an argument. Likewise, the incoming 442// transition should not take the properties of the depending module into 443// account and is thus not informed about it. This makes for a nice 444// decomposition of the decision logic. 445// 446// A given transition mutator only affects its own variation; other variations 447// stay unchanged along the dependency edges. 448// 449// Soong makes sure that all modules are created in the desired variations and 450// that dependency edges are set up correctly. This ensures that "missing 451// variation" errors do not happen and allows for more flexible changes in the 452// value of the variation among dependency edges (as oppposed to bottom-up 453// mutators where if module A in variation X depends on module B and module B 454// has that variation X, A must depend on variation X of B) 455// 456// The limited power of the context objects passed to individual mutators 457// methods also makes it more difficult to shoot oneself in the foot. Complete 458// safety is not guaranteed because no one prevents individual transition 459// mutators from mutating modules in illegal ways and for e.g. Split() or 460// Mutate() to run their own visitations of the transitive dependency of the 461// module and both of these are bad ideas, but it's better than no guardrails at 462// all. 463// 464// This model is pretty close to Bazel's configuration transitions. The mapping 465// between concepts in Soong and Bazel is as follows: 466// - Module == configured target 467// - Variant == configuration 468// - Variation name == configuration flag 469// - Variation == configuration flag value 470// - Outgoing transition == attribute transition 471// - Incoming transition == rule transition 472// 473// The Split() method does not have a Bazel equivalent and Bazel split 474// transitions do not have a Soong equivalent. 475// 476// Mutate() does not make sense in Bazel due to the different models of the 477// two systems: when creating new variations, Soong clones the old module and 478// thus some way is needed to change it state whereas Bazel creates each 479// configuration of a given configured target anew. 480type TransitionMutator interface { 481 // Split returns the set of variations that should be created for a module no 482 // matter who depends on it. Used when Make depends on a particular variation 483 // or when the module knows its variations just based on information given to 484 // it in the Blueprint file. This method should not mutate the module it is 485 // called on. 486 Split(ctx BaseModuleContext) []string 487 488 // OutgoingTransition is called on a module to determine which variation it wants 489 // from its direct dependencies. The dependency itself can override this decision. 490 // This method should not mutate the module itself. 491 OutgoingTransition(ctx OutgoingTransitionContext, sourceVariation string) string 492 493 // IncomingTransition is called on a module to determine which variation it should 494 // be in based on the variation modules that depend on it want. This gives the module 495 // a final say about its own variations. This method should not mutate the module 496 // itself. 497 IncomingTransition(ctx IncomingTransitionContext, incomingVariation string) string 498 499 // Mutate is called after a module was split into multiple variations on each variation. 500 // It should not split the module any further but adding new dependencies is 501 // fine. Unlike all the other methods on TransitionMutator, this method is 502 // allowed to mutate the module. 503 Mutate(ctx BottomUpMutatorContext, variation string) 504} 505 506type androidTransitionMutator struct { 507 finalPhase bool 508 mutator TransitionMutator 509 name string 510} 511 512func (a *androidTransitionMutator) Split(ctx blueprint.BaseModuleContext) []string { 513 if m, ok := ctx.Module().(Module); ok { 514 moduleContext := m.base().baseModuleContextFactory(ctx) 515 return a.mutator.Split(&moduleContext) 516 } else { 517 return []string{""} 518 } 519} 520 521type outgoingTransitionContextImpl struct { 522 archModuleContext 523 bp blueprint.OutgoingTransitionContext 524} 525 526func (c *outgoingTransitionContextImpl) Module() Module { 527 return c.bp.Module().(Module) 528} 529 530func (c *outgoingTransitionContextImpl) DepTag() blueprint.DependencyTag { 531 return c.bp.DepTag() 532} 533 534func (c *outgoingTransitionContextImpl) Config() Config { 535 return c.bp.Config().(Config) 536} 537 538func (c *outgoingTransitionContextImpl) DeviceConfig() DeviceConfig { 539 return DeviceConfig{c.bp.Config().(Config).deviceConfig} 540} 541 542func (c *outgoingTransitionContextImpl) provider(provider blueprint.AnyProviderKey) (any, bool) { 543 return c.bp.Provider(provider) 544} 545 546func (a *androidTransitionMutator) OutgoingTransition(bpctx blueprint.OutgoingTransitionContext, sourceVariation string) string { 547 if m, ok := bpctx.Module().(Module); ok { 548 ctx := outgoingTransitionContextPool.Get().(*outgoingTransitionContextImpl) 549 defer outgoingTransitionContextPool.Put(ctx) 550 *ctx = outgoingTransitionContextImpl{ 551 archModuleContext: m.base().archModuleContextFactory(bpctx), 552 bp: bpctx, 553 } 554 return a.mutator.OutgoingTransition(ctx, sourceVariation) 555 } else { 556 return "" 557 } 558} 559 560type incomingTransitionContextImpl struct { 561 archModuleContext 562 bp blueprint.IncomingTransitionContext 563} 564 565func (c *incomingTransitionContextImpl) Module() Module { 566 return c.bp.Module().(Module) 567} 568 569func (c *incomingTransitionContextImpl) Config() Config { 570 return c.bp.Config().(Config) 571} 572 573func (c *incomingTransitionContextImpl) DeviceConfig() DeviceConfig { 574 return DeviceConfig{c.bp.Config().(Config).deviceConfig} 575} 576 577func (c *incomingTransitionContextImpl) provider(provider blueprint.AnyProviderKey) (any, bool) { 578 return c.bp.Provider(provider) 579} 580 581func (a *androidTransitionMutator) IncomingTransition(bpctx blueprint.IncomingTransitionContext, incomingVariation string) string { 582 if m, ok := bpctx.Module().(Module); ok { 583 ctx := incomingTransitionContextPool.Get().(*incomingTransitionContextImpl) 584 defer incomingTransitionContextPool.Put(ctx) 585 *ctx = incomingTransitionContextImpl{ 586 archModuleContext: m.base().archModuleContextFactory(bpctx), 587 bp: bpctx, 588 } 589 return a.mutator.IncomingTransition(ctx, incomingVariation) 590 } else { 591 return "" 592 } 593} 594 595func (a *androidTransitionMutator) Mutate(ctx blueprint.BottomUpMutatorContext, variation string) { 596 if am, ok := ctx.Module().(Module); ok { 597 if variation != "" { 598 // TODO: this should really be checking whether the TransitionMutator affected this module, not 599 // the empty variant, but TransitionMutator has no concept of skipping a module. 600 base := am.base() 601 base.commonProperties.DebugMutators = append(base.commonProperties.DebugMutators, a.name) 602 base.commonProperties.DebugVariations = append(base.commonProperties.DebugVariations, variation) 603 } 604 605 mctx := bottomUpMutatorContextFactory(ctx, am, a.finalPhase) 606 defer bottomUpMutatorContextPool.Put(mctx) 607 a.mutator.Mutate(mctx, variation) 608 } 609} 610 611func (x *registerMutatorsContext) Transition(name string, m TransitionMutator) { 612 atm := &androidTransitionMutator{ 613 finalPhase: x.finalPhase, 614 mutator: m, 615 name: name, 616 } 617 mutator := &mutator{ 618 name: name, 619 transitionMutator: atm} 620 x.mutators = append(x.mutators, mutator) 621} 622 623func (x *registerMutatorsContext) mutatorName(name string) string { 624 return name 625} 626 627func (x *registerMutatorsContext) TopDown(name string, m TopDownMutator) MutatorHandle { 628 f := func(ctx blueprint.TopDownMutatorContext) { 629 if a, ok := ctx.Module().(Module); ok { 630 moduleContext := a.base().baseModuleContextFactory(ctx) 631 actx := topDownMutatorContextPool.Get().(*topDownMutatorContext) 632 defer topDownMutatorContextPool.Put(actx) 633 *actx = topDownMutatorContext{ 634 bp: ctx, 635 baseModuleContext: moduleContext, 636 } 637 m(actx) 638 } 639 } 640 mutator := &mutator{name: x.mutatorName(name), topDownMutator: f} 641 x.mutators = append(x.mutators, mutator) 642 return mutator 643} 644 645func (mutator *mutator) componentName() string { 646 return mutator.name 647} 648 649func (mutator *mutator) register(ctx *Context) { 650 blueprintCtx := ctx.Context 651 var handle blueprint.MutatorHandle 652 if mutator.bottomUpMutator != nil { 653 handle = blueprintCtx.RegisterBottomUpMutator(mutator.name, mutator.bottomUpMutator) 654 } else if mutator.topDownMutator != nil { 655 handle = blueprintCtx.RegisterTopDownMutator(mutator.name, mutator.topDownMutator) 656 } else if mutator.transitionMutator != nil { 657 blueprintCtx.RegisterTransitionMutator(mutator.name, mutator.transitionMutator) 658 } 659 if mutator.parallel { 660 handle.Parallel() 661 } 662} 663 664type MutatorHandle interface { 665 Parallel() MutatorHandle 666} 667 668func (mutator *mutator) Parallel() MutatorHandle { 669 mutator.parallel = true 670 return mutator 671} 672 673func RegisterComponentsMutator(ctx RegisterMutatorsContext) { 674 ctx.BottomUp("component-deps", componentDepsMutator).Parallel() 675} 676 677// A special mutator that runs just prior to the deps mutator to allow the dependencies 678// on component modules to be added so that they can depend directly on a prebuilt 679// module. 680func componentDepsMutator(ctx BottomUpMutatorContext) { 681 ctx.Module().ComponentDepsMutator(ctx) 682} 683 684func depsMutator(ctx BottomUpMutatorContext) { 685 if m := ctx.Module(); m.Enabled(ctx) { 686 m.base().baseDepsMutator(ctx) 687 m.DepsMutator(ctx) 688 } 689} 690 691func registerDepsMutator(ctx RegisterMutatorsContext) { 692 ctx.BottomUp("deps", depsMutator).Parallel() 693} 694 695// android.topDownMutatorContext either has to embed blueprint.TopDownMutatorContext, in which case every method that 696// has an overridden version in android.BaseModuleContext has to be manually forwarded to BaseModuleContext to avoid 697// ambiguous method errors, or it has to store a blueprint.TopDownMutatorContext non-embedded, in which case every 698// non-overridden method has to be forwarded. There are fewer non-overridden methods, so use the latter. The following 699// methods forward to the identical blueprint versions for topDownMutatorContext and bottomUpMutatorContext. 700 701func (t *topDownMutatorContext) MutatorName() string { 702 return t.bp.MutatorName() 703} 704 705func (t *topDownMutatorContext) Rename(name string) { 706 t.bp.Rename(name) 707 t.Module().base().commonProperties.DebugName = name 708} 709 710func (t *topDownMutatorContext) createModule(factory blueprint.ModuleFactory, name string, props ...interface{}) blueprint.Module { 711 return t.bp.CreateModule(factory, name, props...) 712} 713 714func (t *topDownMutatorContext) CreateModule(factory ModuleFactory, props ...interface{}) Module { 715 return createModule(t, factory, "_topDownMutatorModule", props...) 716} 717 718func (t *topDownMutatorContext) createModuleWithoutInheritance(factory ModuleFactory, props ...interface{}) Module { 719 module := t.bp.CreateModule(ModuleFactoryAdaptor(factory), "", props...).(Module) 720 return module 721} 722 723func (b *bottomUpMutatorContext) MutatorName() string { 724 return b.bp.MutatorName() 725} 726 727func (b *bottomUpMutatorContext) Rename(name string) { 728 b.bp.Rename(name) 729 b.Module().base().commonProperties.DebugName = name 730} 731 732func (b *bottomUpMutatorContext) AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) []blueprint.Module { 733 if b.baseModuleContext.checkedMissingDeps() { 734 panic("Adding deps not allowed after checking for missing deps") 735 } 736 return b.bp.AddDependency(module, tag, name...) 737} 738 739func (b *bottomUpMutatorContext) AddReverseDependency(module blueprint.Module, tag blueprint.DependencyTag, name string) { 740 if b.baseModuleContext.checkedMissingDeps() { 741 panic("Adding deps not allowed after checking for missing deps") 742 } 743 b.bp.AddReverseDependency(module, tag, name) 744} 745 746func (b *bottomUpMutatorContext) CreateVariations(variations ...string) []Module { 747 if b.finalPhase { 748 panic("CreateVariations not allowed in FinalDepsMutators") 749 } 750 751 modules := b.bp.CreateVariations(variations...) 752 753 aModules := make([]Module, len(modules)) 754 for i := range variations { 755 aModules[i] = modules[i].(Module) 756 base := aModules[i].base() 757 base.commonProperties.DebugMutators = append(base.commonProperties.DebugMutators, b.MutatorName()) 758 base.commonProperties.DebugVariations = append(base.commonProperties.DebugVariations, variations[i]) 759 } 760 761 return aModules 762} 763 764func (b *bottomUpMutatorContext) CreateLocalVariations(variations ...string) []Module { 765 if b.finalPhase { 766 panic("CreateLocalVariations not allowed in FinalDepsMutators") 767 } 768 769 modules := b.bp.CreateLocalVariations(variations...) 770 771 aModules := make([]Module, len(modules)) 772 for i := range variations { 773 aModules[i] = modules[i].(Module) 774 base := aModules[i].base() 775 base.commonProperties.DebugMutators = append(base.commonProperties.DebugMutators, b.MutatorName()) 776 base.commonProperties.DebugVariations = append(base.commonProperties.DebugVariations, variations[i]) 777 } 778 779 return aModules 780} 781 782func (b *bottomUpMutatorContext) SetDependencyVariation(variation string) { 783 b.bp.SetDependencyVariation(variation) 784} 785 786func (b *bottomUpMutatorContext) SetDefaultDependencyVariation(variation *string) { 787 b.bp.SetDefaultDependencyVariation(variation) 788} 789 790func (b *bottomUpMutatorContext) AddVariationDependencies(variations []blueprint.Variation, tag blueprint.DependencyTag, 791 names ...string) []blueprint.Module { 792 if b.baseModuleContext.checkedMissingDeps() { 793 panic("Adding deps not allowed after checking for missing deps") 794 } 795 return b.bp.AddVariationDependencies(variations, tag, names...) 796} 797 798func (b *bottomUpMutatorContext) AddFarVariationDependencies(variations []blueprint.Variation, 799 tag blueprint.DependencyTag, names ...string) []blueprint.Module { 800 if b.baseModuleContext.checkedMissingDeps() { 801 panic("Adding deps not allowed after checking for missing deps") 802 } 803 804 return b.bp.AddFarVariationDependencies(variations, tag, names...) 805} 806 807func (b *bottomUpMutatorContext) AddInterVariantDependency(tag blueprint.DependencyTag, from, to blueprint.Module) { 808 b.bp.AddInterVariantDependency(tag, from, to) 809} 810 811func (b *bottomUpMutatorContext) ReplaceDependencies(name string) { 812 if b.baseModuleContext.checkedMissingDeps() { 813 panic("Adding deps not allowed after checking for missing deps") 814 } 815 b.bp.ReplaceDependencies(name) 816} 817 818func (b *bottomUpMutatorContext) ReplaceDependenciesIf(name string, predicate blueprint.ReplaceDependencyPredicate) { 819 if b.baseModuleContext.checkedMissingDeps() { 820 panic("Adding deps not allowed after checking for missing deps") 821 } 822 b.bp.ReplaceDependenciesIf(name, predicate) 823} 824 825func (b *bottomUpMutatorContext) AliasVariation(variationName string) { 826 b.bp.AliasVariation(variationName) 827} 828 829func (b *bottomUpMutatorContext) CreateAliasVariation(fromVariationName, toVariationName string) { 830 b.bp.CreateAliasVariation(fromVariationName, toVariationName) 831} 832 833func (b *bottomUpMutatorContext) SetVariationProvider(module blueprint.Module, provider blueprint.AnyProviderKey, value interface{}) { 834 b.bp.SetVariationProvider(module, provider, value) 835} 836