mutator.go 36 KB

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