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