blob: e8c3425312e8a5143c5c260f03c01ee5e1b3600f [file] [log] [blame]
Colin Cross6362e272015-10-29 15:25:03 -07001// 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
Colin Cross635c3b02016-05-18 15:37:25 -070015package android
Colin Cross6362e272015-10-29 15:25:03 -070016
Colin Cross795c3772017-03-16 16:50:10 -070017import (
Colin Cross795c3772017-03-16 16:50:10 -070018 "github.com/google/blueprint"
Colin Cross98530ba2025-02-11 14:25:22 -080019 "github.com/google/blueprint/pool"
Colin Cross795c3772017-03-16 16:50:10 -070020)
Colin Cross6362e272015-10-29 15:25:03 -070021
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -070022// Phases:
23// run Pre-arch mutators
24// run archMutator
25// run Pre-deps mutators
26// run depsMutator
27// run PostDeps mutators
Martin Stjernholm710ec3a2020-01-16 15:12:04 +000028// run FinalDeps mutators (CreateVariations disallowed in this phase)
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -070029// continue on to GenerateAndroidBuildActions
Colin Cross1e676be2016-10-12 14:38:15 -070030
Paul Duffinc05b0342021-03-06 13:28:13 +000031// collateGloballyRegisteredMutators constructs the list of mutators that have been registered
32// with the InitRegistrationContext and will be used at runtime.
33func collateGloballyRegisteredMutators() sortableComponents {
34 return collateRegisteredMutators(preArch, preDeps, postDeps, finalDeps)
35}
36
37// collateRegisteredMutators constructs a single list of mutators from the separate lists.
38func collateRegisteredMutators(preArch, preDeps, postDeps, finalDeps []RegisterMutatorFunc) sortableComponents {
Colin Crosscec81712017-07-13 14:43:27 -070039 mctx := &registerMutatorsContext{}
Nan Zhangdb0b9a32017-02-27 10:12:13 -080040
41 register := func(funcs []RegisterMutatorFunc) {
42 for _, f := range funcs {
Colin Crosscec81712017-07-13 14:43:27 -070043 f(mctx)
Nan Zhangdb0b9a32017-02-27 10:12:13 -080044 }
45 }
46
Colin Crosscec81712017-07-13 14:43:27 -070047 register(preArch)
Nan Zhangdb0b9a32017-02-27 10:12:13 -080048
Colin Crosscec81712017-07-13 14:43:27 -070049 register(preDeps)
50
Liz Kammer356f7d42021-01-26 09:18:53 -050051 register([]RegisterMutatorFunc{registerDepsMutator})
Colin Crosscec81712017-07-13 14:43:27 -070052
53 register(postDeps)
54
Martin Stjernholm710ec3a2020-01-16 15:12:04 +000055 mctx.finalPhase = true
56 register(finalDeps)
57
Paul Duffinc05b0342021-03-06 13:28:13 +000058 return mctx.mutators
Colin Cross795c3772017-03-16 16:50:10 -070059}
60
61type registerMutatorsContext struct {
Colin Crossb63d7b32023-12-07 16:54:51 -080062 mutators sortableComponents
63 finalPhase bool
Colin Cross795c3772017-03-16 16:50:10 -070064}
Colin Cross1e676be2016-10-12 14:38:15 -070065
66type RegisterMutatorsContext interface {
Colin Cross25de6c32019-06-06 14:29:25 -070067 TopDown(name string, m TopDownMutator) MutatorHandle
68 BottomUp(name string, m BottomUpMutator) MutatorHandle
Colin Cross617b88a2020-08-24 18:04:09 -070069 BottomUpBlueprint(name string, m blueprint.BottomUpMutator) MutatorHandle
Lukacs T. Berki6c716762022-06-13 20:50:39 +020070 Transition(name string, m TransitionMutator)
Colin Cross1e676be2016-10-12 14:38:15 -070071}
72
73type RegisterMutatorFunc func(RegisterMutatorsContext)
74
Colin Crosscec81712017-07-13 14:43:27 -070075var preArch = []RegisterMutatorFunc{
Dan Willemsen6e72ef72018-01-26 18:27:02 -080076 RegisterNamespaceMutator,
Paul Duffinaa4162e2020-05-05 11:35:43 +010077
Paul Duffinaa4162e2020-05-05 11:35:43 +010078 // Check the visibility rules are valid.
79 //
80 // This must run after the package renamer mutators so that any issues found during
81 // validation of the package's default_visibility property are reported using the
82 // correct package name and not the synthetic name.
83 //
84 // This must also be run before defaults mutators as the rules for validation are
85 // different before checking the rules than they are afterwards. e.g.
86 // visibility: ["//visibility:private", "//visibility:public"]
87 // would be invalid if specified in a module definition but is valid if it results
88 // from something like this:
89 //
90 // defaults {
91 // name: "defaults",
92 // // Be inaccessible outside a package by default.
93 // visibility: ["//visibility:private"]
94 // }
95 //
96 // defaultable_module {
97 // name: "defaultable_module",
98 // defaults: ["defaults"],
99 // // Override the default.
100 // visibility: ["//visibility:public"]
101 // }
102 //
Paul Duffin593b3c92019-12-05 14:31:48 +0000103 RegisterVisibilityRuleChecker,
Paul Duffinaa4162e2020-05-05 11:35:43 +0100104
Bob Badour37af0462021-01-07 03:34:31 +0000105 // Record the default_applicable_licenses for each package.
106 //
107 // This must run before the defaults so that defaults modules can pick up the package default.
108 RegisterLicensesPackageMapper,
109
Paul Duffinaa4162e2020-05-05 11:35:43 +0100110 // Apply properties from defaults modules to the referencing modules.
Paul Duffinafa9fa12020-04-29 16:47:28 +0100111 //
112 // Any mutators that are added before this will not see any modules created by
113 // a DefaultableHook.
Colin Cross89536d42017-07-07 14:35:50 -0700114 RegisterDefaultsPreArchMutators,
Paul Duffinaa4162e2020-05-05 11:35:43 +0100115
Paul Duffin44f1d842020-06-26 20:17:02 +0100116 // Add dependencies on any components so that any component references can be
117 // resolved within the deps mutator.
118 //
119 // Must be run after defaults so it can be used to create dependencies on the
120 // component modules that are creating in a DefaultableHook.
121 //
122 // Must be run before RegisterPrebuiltsPreArchMutators, i.e. before prebuilts are
123 // renamed. That is so that if a module creates components using a prebuilt module
124 // type that any dependencies (which must use prebuilt_ prefixes) are resolved to
125 // the prebuilt module and not the source module.
126 RegisterComponentsMutator,
127
Paul Duffinc988c8e2020-04-29 18:27:14 +0100128 // Create an association between prebuilt modules and their corresponding source
129 // modules (if any).
Paul Duffinafa9fa12020-04-29 16:47:28 +0100130 //
131 // Must be run after defaults mutators to ensure that any modules created by
132 // a DefaultableHook can be either a prebuilt or a source module with a matching
133 // prebuilt.
Paul Duffinc988c8e2020-04-29 18:27:14 +0100134 RegisterPrebuiltsPreArchMutators,
135
Bob Badour37af0462021-01-07 03:34:31 +0000136 // Gather the licenses properties for all modules for use during expansion and enforcement.
137 //
138 // This must come after the defaults mutators to ensure that any licenses supplied
139 // in a defaults module has been successfully applied before the rules are gathered.
140 RegisterLicensesPropertyGatherer,
141
Paul Duffinaa4162e2020-05-05 11:35:43 +0100142 // Gather the visibility rules for all modules for us during visibility enforcement.
143 //
144 // This must come after the defaults mutators to ensure that any visibility supplied
145 // in a defaults module has been successfully applied before the rules are gathered.
Paul Duffin593b3c92019-12-05 14:31:48 +0000146 RegisterVisibilityRuleGatherer,
Colin Crosscec81712017-07-13 14:43:27 -0700147}
148
Colin Crossae4c6182017-09-15 17:33:55 -0700149func registerArchMutator(ctx RegisterMutatorsContext) {
Colin Cross8bbc3d52024-09-11 15:33:54 -0700150 ctx.Transition("os", &osTransitionMutator{})
Jihoon Kang5402bbd2024-07-31 18:37:49 +0000151 ctx.Transition("image", &imageTransitionMutator{})
Colin Cross8bbc3d52024-09-11 15:33:54 -0700152 ctx.Transition("arch", &archTransitionMutator{})
Colin Crossae4c6182017-09-15 17:33:55 -0700153}
154
Colin Crosscec81712017-07-13 14:43:27 -0700155var preDeps = []RegisterMutatorFunc{
Colin Crossae4c6182017-09-15 17:33:55 -0700156 registerArchMutator,
Colin Crosscec81712017-07-13 14:43:27 -0700157}
158
159var postDeps = []RegisterMutatorFunc{
Colin Cross1b488422019-03-04 22:33:56 -0800160 registerPathDepsMutator,
Colin Cross5ea9bcc2017-07-27 15:41:32 -0700161 RegisterPrebuiltsPostDepsMutators,
Paul Duffin593b3c92019-12-05 14:31:48 +0000162 RegisterVisibilityRuleEnforcer,
Bob Badour37af0462021-01-07 03:34:31 +0000163 RegisterLicensesDependencyChecker,
Paul Duffin45338f02021-03-30 23:07:52 +0100164 registerNeverallowMutator,
Jaewoong Jungb639a6a2019-05-10 15:16:29 -0700165 RegisterOverridePostDepsMutators,
Colin Crosscec81712017-07-13 14:43:27 -0700166}
Colin Cross1e676be2016-10-12 14:38:15 -0700167
Martin Stjernholm710ec3a2020-01-16 15:12:04 +0000168var finalDeps = []RegisterMutatorFunc{}
169
Colin Cross1e676be2016-10-12 14:38:15 -0700170func PreArchMutators(f RegisterMutatorFunc) {
171 preArch = append(preArch, f)
172}
173
174func PreDepsMutators(f RegisterMutatorFunc) {
175 preDeps = append(preDeps, f)
176}
177
178func PostDepsMutators(f RegisterMutatorFunc) {
179 postDeps = append(postDeps, f)
180}
181
Martin Stjernholm710ec3a2020-01-16 15:12:04 +0000182func FinalDepsMutators(f RegisterMutatorFunc) {
183 finalDeps = append(finalDeps, f)
184}
185
Chris Parsons637458d2023-09-19 20:09:00 +0000186type BaseMutatorContext interface {
187 BaseModuleContext
188
189 // MutatorName returns the name that this mutator was registered with.
190 MutatorName() string
191
192 // Rename all variants of a module. The new name is not visible to calls to ModuleName,
193 // AddDependency or OtherModuleName until after this mutator pass is complete.
194 Rename(name string)
Colin Crossda279cf2024-09-17 14:25:45 -0700195
196 // CreateModule creates a new module by calling the factory method for the specified moduleType, and applies
197 // the specified property structs to it as if the properties were set in a blueprint file.
198 CreateModule(ModuleFactory, ...interface{}) Module
Chris Parsons637458d2023-09-19 20:09:00 +0000199}
200
201type TopDownMutator func(TopDownMutatorContext)
202
203type TopDownMutatorContext interface {
204 BaseMutatorContext
Chris Parsons637458d2023-09-19 20:09:00 +0000205}
206
Colin Cross25de6c32019-06-06 14:29:25 -0700207type topDownMutatorContext struct {
Colin Crossdc35e212019-06-06 16:13:11 -0700208 bp blueprint.TopDownMutatorContext
Colin Cross0ea8ba82019-06-06 14:33:29 -0700209 baseModuleContext
Colin Cross6362e272015-10-29 15:25:03 -0700210}
211
Colin Cross25de6c32019-06-06 14:29:25 -0700212type BottomUpMutator func(BottomUpMutatorContext)
Colin Cross6362e272015-10-29 15:25:03 -0700213
Colin Cross635c3b02016-05-18 15:37:25 -0700214type BottomUpMutatorContext interface {
Colin Cross9f35c3d2020-09-16 19:04:41 -0700215 BaseMutatorContext
Colin Crossb63d7b32023-12-07 16:54:51 -0800216
217 // AddDependency adds a dependency to the given module. It returns a slice of modules for each
218 // dependency (some entries may be nil).
219 //
220 // If the mutator is parallel (see MutatorHandle.Parallel), this method will pause until the
221 // new dependencies have had the current mutator called on them. If the mutator is not
222 // parallel this method does not affect the ordering of the current mutator pass, but will
223 // be ordered correctly for all future mutator passes.
224 AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) []blueprint.Module
Colin Crossaabf6792017-11-29 00:27:14 -0800225
Colin Cross9f35c3d2020-09-16 19:04:41 -0700226 // AddReverseDependency adds a dependency from the destination to the given module.
227 // Does not affect the ordering of the current mutator pass, but will be ordered
228 // correctly for all future mutator passes. All reverse dependencies for a destination module are
229 // collected until the end of the mutator pass, sorted by name, and then appended to the destination
230 // module's dependency list.
Colin Crossaabf6792017-11-29 00:27:14 -0800231 AddReverseDependency(module blueprint.Module, tag blueprint.DependencyTag, name string)
Colin Cross9f35c3d2020-09-16 19:04:41 -0700232
233 // CreateVariations splits a module into multiple variants, one for each name in the variationNames
234 // parameter. It returns a list of new modules in the same order as the variationNames
235 // list.
236 //
237 // If any of the dependencies of the module being operated on were already split
238 // by calling CreateVariations with the same name, the dependency will automatically
239 // be updated to point the matching variant.
240 //
241 // If a module is split, and then a module depending on the first module is not split
242 // when the Mutator is later called on it, the dependency of the depending module will
243 // automatically be updated to point to the first variant.
Colin Cross43b92e02019-11-18 15:28:57 -0800244 CreateVariations(...string) []Module
Colin Cross9f35c3d2020-09-16 19:04:41 -0700245
246 // CreateLocationVariations splits a module into multiple variants, one for each name in the variantNames
247 // parameter. It returns a list of new modules in the same order as the variantNames
248 // list.
249 //
250 // Local variations do not affect automatic dependency resolution - dependencies added
251 // to the split module via deps or DynamicDependerModule must exactly match a variant
252 // that contains all the non-local variations.
Colin Cross43b92e02019-11-18 15:28:57 -0800253 CreateLocalVariations(...string) []Module
Colin Cross9f35c3d2020-09-16 19:04:41 -0700254
255 // SetDependencyVariation sets all dangling dependencies on the current module to point to the variation
256 // with given name. This function ignores the default variation set by SetDefaultDependencyVariation.
Colin Crossaabf6792017-11-29 00:27:14 -0800257 SetDependencyVariation(string)
Colin Cross9f35c3d2020-09-16 19:04:41 -0700258
259 // SetDefaultDependencyVariation sets the default variation when a dangling reference is detected
260 // during the subsequent calls on Create*Variations* functions. To reset, set it to nil.
Jiyong Park1d1119f2019-07-29 21:27:18 +0900261 SetDefaultDependencyVariation(*string)
Colin Cross9f35c3d2020-09-16 19:04:41 -0700262
263 // AddVariationDependencies adds deps as dependencies of the current module, but uses the variations
Colin Cross4f1dcb02020-09-16 18:45:04 -0700264 // argument to select which variant of the dependency to use. It returns a slice of modules for
265 // each dependency (some entries may be nil). A variant of the dependency must exist that matches
Usta Shresthac725f472022-01-11 02:44:21 -0500266 // all the non-local variations of the current module, plus the variations argument.
Colin Cross4f1dcb02020-09-16 18:45:04 -0700267 //
268 // If the mutator is parallel (see MutatorHandle.Parallel), this method will pause until the
269 // new dependencies have had the current mutator called on them. If the mutator is not
270 // parallel this method does not affect the ordering of the current mutator pass, but will
271 // be ordered correctly for all future mutator passes.
Usta Shresthac725f472022-01-11 02:44:21 -0500272 AddVariationDependencies(variations []blueprint.Variation, tag blueprint.DependencyTag, names ...string) []blueprint.Module
Colin Cross9f35c3d2020-09-16 19:04:41 -0700273
274 // AddFarVariationDependencies adds deps as dependencies of the current module, but uses the
Colin Cross4f1dcb02020-09-16 18:45:04 -0700275 // variations argument to select which variant of the dependency to use. It returns a slice of
276 // modules for each dependency (some entries may be nil). A variant of the dependency must
277 // exist that matches the variations argument, but may also have other variations.
Colin Cross9f35c3d2020-09-16 19:04:41 -0700278 // For any unspecified variation the first variant will be used.
279 //
280 // Unlike AddVariationDependencies, the variations of the current module are ignored - the
281 // dependency only needs to match the supplied variations.
Colin Cross4f1dcb02020-09-16 18:45:04 -0700282 //
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 AddFarVariationDependencies([]blueprint.Variation, blueprint.DependencyTag, ...string) []blueprint.Module
Colin Cross9f35c3d2020-09-16 19:04:41 -0700288
289 // AddInterVariantDependency adds a dependency between two variants of the same module. Variants are always
290 // ordered in the same orderas they were listed in CreateVariations, and AddInterVariantDependency does not change
291 // that ordering, but it associates a DependencyTag with the dependency and makes it visible to VisitDirectDeps,
292 // WalkDeps, etc.
Colin Crossaabf6792017-11-29 00:27:14 -0800293 AddInterVariantDependency(tag blueprint.DependencyTag, from, to blueprint.Module)
Colin Cross9f35c3d2020-09-16 19:04:41 -0700294
Colin Cross86771322024-05-01 14:19:51 -0700295 // ReplaceDependencies finds all the variants of the module with the specified name, then
296 // replaces all dependencies onto those variants with the current variant of this module.
297 // Replacements don't take effect until after the mutator pass is finished.
Colin Crossaabf6792017-11-29 00:27:14 -0800298 ReplaceDependencies(string)
Colin Cross9f35c3d2020-09-16 19:04:41 -0700299
Colin Cross86771322024-05-01 14:19:51 -0700300 // ReplaceDependenciesIf finds all the variants of the module with the specified name, then
301 // replaces all dependencies onto those variants with the current variant of this module
302 // as long as the supplied predicate returns true.
Colin Cross9f35c3d2020-09-16 19:04:41 -0700303 // Replacements don't take effect until after the mutator pass is finished.
Paul Duffin80342d72020-06-26 22:08:43 +0100304 ReplaceDependenciesIf(string, blueprint.ReplaceDependencyPredicate)
Colin Cross9f35c3d2020-09-16 19:04:41 -0700305
306 // AliasVariation takes a variationName that was passed to CreateVariations for this module,
307 // and creates an alias from the current variant (before the mutator has run) to the new
308 // variant. The alias will be valid until the next time a mutator calls CreateVariations or
309 // CreateLocalVariations on this module without also calling AliasVariation. The alias can
310 // be used to add dependencies on the newly created variant using the variant map from
311 // before CreateVariations was run.
Jaewoong Jung9f88ce22019-11-15 10:57:34 -0800312 AliasVariation(variationName string)
Colin Cross9f35c3d2020-09-16 19:04:41 -0700313
314 // CreateAliasVariation takes a toVariationName that was passed to CreateVariations for this
315 // module, and creates an alias from a new fromVariationName variant the toVariationName
316 // variant. The alias will be valid until the next time a mutator calls CreateVariations or
317 // CreateLocalVariations on this module without also calling AliasVariation. The alias can
318 // be used to add dependencies on the toVariationName variant using the fromVariationName
319 // variant.
Colin Cross1b9604b2020-08-11 12:03:56 -0700320 CreateAliasVariation(fromVariationName, toVariationName string)
Colin Crossd27e7b82020-07-02 11:38:17 -0700321
322 // SetVariationProvider sets the value for a provider for the given newly created variant of
323 // the current module, i.e. one of the Modules returned by CreateVariations.. It panics if
324 // not called during the appropriate mutator or GenerateBuildActions pass for the provider,
325 // if the value is not of the appropriate type, or if the module is not a newly created
326 // variant of the current module. The value should not be modified after being passed to
327 // SetVariationProvider.
Colin Cross3c0a83d2023-12-12 14:13:26 -0800328 SetVariationProvider(module blueprint.Module, provider blueprint.AnyProviderKey, value interface{})
Colin Cross6362e272015-10-29 15:25:03 -0700329}
330
Colin Cross984223f2024-02-01 17:10:23 -0800331// An outgoingTransitionContextImpl and incomingTransitionContextImpl is created for every dependency of every module
332// for each transition mutator. bottomUpMutatorContext and topDownMutatorContext are created once for every module
333// for every BottomUp or TopDown mutator. Use a global pool for each to avoid reallocating every time.
334var (
Colin Cross98530ba2025-02-11 14:25:22 -0800335 outgoingTransitionContextPool = pool.New[outgoingTransitionContextImpl]()
336 incomingTransitionContextPool = pool.New[incomingTransitionContextImpl]()
337 bottomUpMutatorContextPool = pool.New[bottomUpMutatorContext]()
338 topDownMutatorContextPool = pool.New[topDownMutatorContext]()
Colin Cross984223f2024-02-01 17:10:23 -0800339)
340
Colin Cross25de6c32019-06-06 14:29:25 -0700341type bottomUpMutatorContext struct {
Colin Crossdc35e212019-06-06 16:13:11 -0700342 bp blueprint.BottomUpMutatorContext
Colin Cross0ea8ba82019-06-06 14:33:29 -0700343 baseModuleContext
Chris Parsons5a34ffb2021-07-21 14:34:58 -0400344 finalPhase bool
Colin Cross6362e272015-10-29 15:25:03 -0700345}
346
Colin Cross984223f2024-02-01 17:10:23 -0800347// callers must immediately follow the call to this function with defer bottomUpMutatorContextPool.Put(mctx).
Colin Cross617b88a2020-08-24 18:04:09 -0700348func bottomUpMutatorContextFactory(ctx blueprint.BottomUpMutatorContext, a Module,
Colin Cross98530ba2025-02-11 14:25:22 -0800349 finalPhase bool) *bottomUpMutatorContext {
Colin Cross617b88a2020-08-24 18:04:09 -0700350
Chris Parsons5a34ffb2021-07-21 14:34:58 -0400351 moduleContext := a.base().baseModuleContextFactory(ctx)
Colin Cross98530ba2025-02-11 14:25:22 -0800352 mctx := bottomUpMutatorContextPool.Get()
Colin Cross984223f2024-02-01 17:10:23 -0800353 *mctx = bottomUpMutatorContext{
Chris Parsons5a34ffb2021-07-21 14:34:58 -0400354 bp: ctx,
Cole Faust0abd4b42023-01-10 10:49:18 -0800355 baseModuleContext: moduleContext,
Chris Parsons5a34ffb2021-07-21 14:34:58 -0400356 finalPhase: finalPhase,
Colin Cross617b88a2020-08-24 18:04:09 -0700357 }
Colin Cross984223f2024-02-01 17:10:23 -0800358 return mctx
Colin Cross617b88a2020-08-24 18:04:09 -0700359}
360
Colin Cross25de6c32019-06-06 14:29:25 -0700361func (x *registerMutatorsContext) BottomUp(name string, m BottomUpMutator) MutatorHandle {
Martin Stjernholm710ec3a2020-01-16 15:12:04 +0000362 finalPhase := x.finalPhase
Colin Cross798bfce2016-10-12 14:28:16 -0700363 f := func(ctx blueprint.BottomUpMutatorContext) {
Colin Cross635c3b02016-05-18 15:37:25 -0700364 if a, ok := ctx.Module().(Module); ok {
Colin Cross984223f2024-02-01 17:10:23 -0800365 mctx := bottomUpMutatorContextFactory(ctx, a, finalPhase)
366 defer bottomUpMutatorContextPool.Put(mctx)
367 m(mctx)
Colin Cross6362e272015-10-29 15:25:03 -0700368 }
Colin Cross798bfce2016-10-12 14:28:16 -0700369 }
Liz Kammer356f7d42021-01-26 09:18:53 -0500370 mutator := &mutator{name: x.mutatorName(name), bottomUpMutator: f}
Colin Cross795c3772017-03-16 16:50:10 -0700371 x.mutators = append(x.mutators, mutator)
Colin Cross798bfce2016-10-12 14:28:16 -0700372 return mutator
Colin Cross6362e272015-10-29 15:25:03 -0700373}
374
Colin Cross617b88a2020-08-24 18:04:09 -0700375func (x *registerMutatorsContext) BottomUpBlueprint(name string, m blueprint.BottomUpMutator) MutatorHandle {
376 mutator := &mutator{name: name, bottomUpMutator: m}
377 x.mutators = append(x.mutators, mutator)
378 return mutator
379}
380
Lukacs T. Berki6c716762022-06-13 20:50:39 +0200381type IncomingTransitionContext interface {
Colin Cross4aa3e0a2024-01-18 17:22:58 -0800382 ArchModuleContext
Colin Crossaf333f52024-04-15 15:20:23 -0700383 ModuleProviderContext
Colin Cross4aa3e0a2024-01-18 17:22:58 -0800384
Lukacs T. Berki6c716762022-06-13 20:50:39 +0200385 // Module returns the target of the dependency edge for which the transition
386 // is being computed
387 Module() Module
388
389 // Config returns the configuration for the build.
390 Config() Config
Colin Cross4aa3e0a2024-01-18 17:22:58 -0800391
392 DeviceConfig() DeviceConfig
Colin Crosse1a85552024-06-14 12:17:37 -0700393
394 // IsAddingDependency returns true if the transition is being called while adding a dependency
395 // after the transition mutator has already run, or false if it is being called when the transition
396 // mutator is running. This should be used sparingly, all uses will have to be removed in order
397 // to support creating variants on demand.
398 IsAddingDependency() bool
Lukacs T. Berki6c716762022-06-13 20:50:39 +0200399}
400
401type OutgoingTransitionContext interface {
Colin Cross4aa3e0a2024-01-18 17:22:58 -0800402 ArchModuleContext
Colin Crossaf333f52024-04-15 15:20:23 -0700403 ModuleProviderContext
Colin Cross4aa3e0a2024-01-18 17:22:58 -0800404
Lukacs T. Berki6c716762022-06-13 20:50:39 +0200405 // Module returns the target of the dependency edge for which the transition
406 // is being computed
407 Module() Module
408
409 // DepTag() Returns the dependency tag through which this dependency is
410 // reached
411 DepTag() blueprint.DependencyTag
Colin Cross4aa3e0a2024-01-18 17:22:58 -0800412
413 // Config returns the configuration for the build.
414 Config() Config
415
416 DeviceConfig() DeviceConfig
Lukacs T. Berki6c716762022-06-13 20:50:39 +0200417}
Lukacs T. Berki0e691c12022-06-24 10:15:55 +0200418
Colin Cross4aa3e0a2024-01-18 17:22:58 -0800419// TransitionMutator implements a top-down mechanism where a module tells its
Lukacs T. Berki0e691c12022-06-24 10:15:55 +0200420// direct dependencies what variation they should be built in but the dependency
421// has the final say.
422//
423// When implementing a transition mutator, one needs to implement four methods:
424// - Split() that tells what variations a module has by itself
425// - OutgoingTransition() where a module tells what it wants from its
426// dependency
427// - IncomingTransition() where a module has the final say about its own
428// variation
429// - Mutate() that changes the state of a module depending on its variation
430//
431// That the effective variation of module B when depended on by module A is the
432// composition the outgoing transition of module A and the incoming transition
433// of module B.
434//
435// the outgoing transition should not take the properties of the dependency into
436// account, only those of the module that depends on it. For this reason, the
437// dependency is not even passed into it as an argument. Likewise, the incoming
438// transition should not take the properties of the depending module into
439// account and is thus not informed about it. This makes for a nice
440// decomposition of the decision logic.
441//
442// A given transition mutator only affects its own variation; other variations
443// stay unchanged along the dependency edges.
444//
445// Soong makes sure that all modules are created in the desired variations and
446// that dependency edges are set up correctly. This ensures that "missing
447// variation" errors do not happen and allows for more flexible changes in the
448// value of the variation among dependency edges (as oppposed to bottom-up
449// mutators where if module A in variation X depends on module B and module B
450// has that variation X, A must depend on variation X of B)
451//
452// The limited power of the context objects passed to individual mutators
453// methods also makes it more difficult to shoot oneself in the foot. Complete
454// safety is not guaranteed because no one prevents individual transition
455// mutators from mutating modules in illegal ways and for e.g. Split() or
456// Mutate() to run their own visitations of the transitive dependency of the
457// module and both of these are bad ideas, but it's better than no guardrails at
458// all.
459//
460// This model is pretty close to Bazel's configuration transitions. The mapping
461// between concepts in Soong and Bazel is as follows:
462// - Module == configured target
463// - Variant == configuration
464// - Variation name == configuration flag
465// - Variation == configuration flag value
466// - Outgoing transition == attribute transition
467// - Incoming transition == rule transition
468//
469// The Split() method does not have a Bazel equivalent and Bazel split
470// transitions do not have a Soong equivalent.
471//
472// Mutate() does not make sense in Bazel due to the different models of the
473// two systems: when creating new variations, Soong clones the old module and
474// thus some way is needed to change it state whereas Bazel creates each
475// configuration of a given configured target anew.
Lukacs T. Berki6c716762022-06-13 20:50:39 +0200476type TransitionMutator interface {
477 // Split returns the set of variations that should be created for a module no
478 // matter who depends on it. Used when Make depends on a particular variation
479 // or when the module knows its variations just based on information given to
480 // it in the Blueprint file. This method should not mutate the module it is
481 // called on.
482 Split(ctx BaseModuleContext) []string
483
Colin Cross4aa3e0a2024-01-18 17:22:58 -0800484 // OutgoingTransition is called on a module to determine which variation it wants
485 // from its direct dependencies. The dependency itself can override this decision.
486 // This method should not mutate the module itself.
Lukacs T. Berki6c716762022-06-13 20:50:39 +0200487 OutgoingTransition(ctx OutgoingTransitionContext, sourceVariation string) string
488
Colin Cross4aa3e0a2024-01-18 17:22:58 -0800489 // IncomingTransition is called on a module to determine which variation it should
490 // be in based on the variation modules that depend on it want. This gives the module
491 // a final say about its own variations. This method should not mutate the module
Lukacs T. Berki6c716762022-06-13 20:50:39 +0200492 // itself.
493 IncomingTransition(ctx IncomingTransitionContext, incomingVariation string) string
494
Colin Cross4aa3e0a2024-01-18 17:22:58 -0800495 // Mutate is called after a module was split into multiple variations on each variation.
Lukacs T. Berki6c716762022-06-13 20:50:39 +0200496 // It should not split the module any further but adding new dependencies is
497 // fine. Unlike all the other methods on TransitionMutator, this method is
498 // allowed to mutate the module.
499 Mutate(ctx BottomUpMutatorContext, variation string)
500}
501
502type androidTransitionMutator struct {
Colin Crossb63d7b32023-12-07 16:54:51 -0800503 finalPhase bool
504 mutator TransitionMutator
Colin Crossd67425d2024-04-15 15:17:05 -0700505 name string
Lukacs T. Berki6c716762022-06-13 20:50:39 +0200506}
507
508func (a *androidTransitionMutator) Split(ctx blueprint.BaseModuleContext) []string {
Colin Crossd27205e2024-09-12 22:41:37 -0700509 if a.finalPhase {
510 panic("TransitionMutator not allowed in FinalDepsMutators")
511 }
Lukacs T. Berki6c716762022-06-13 20:50:39 +0200512 if m, ok := ctx.Module().(Module); ok {
513 moduleContext := m.base().baseModuleContextFactory(ctx)
Lukacs T. Berki6c716762022-06-13 20:50:39 +0200514 return a.mutator.Split(&moduleContext)
515 } else {
516 return []string{""}
517 }
518}
519
520type outgoingTransitionContextImpl struct {
Colin Cross4aa3e0a2024-01-18 17:22:58 -0800521 archModuleContext
Lukacs T. Berki6c716762022-06-13 20:50:39 +0200522 bp blueprint.OutgoingTransitionContext
523}
524
525func (c *outgoingTransitionContextImpl) Module() Module {
526 return c.bp.Module().(Module)
527}
528
529func (c *outgoingTransitionContextImpl) DepTag() blueprint.DependencyTag {
530 return c.bp.DepTag()
531}
532
Colin Cross4aa3e0a2024-01-18 17:22:58 -0800533func (c *outgoingTransitionContextImpl) Config() Config {
534 return c.bp.Config().(Config)
535}
536
537func (c *outgoingTransitionContextImpl) DeviceConfig() DeviceConfig {
538 return DeviceConfig{c.bp.Config().(Config).deviceConfig}
539}
540
Colin Crossaf333f52024-04-15 15:20:23 -0700541func (c *outgoingTransitionContextImpl) provider(provider blueprint.AnyProviderKey) (any, bool) {
542 return c.bp.Provider(provider)
543}
544
Colin Cross4aa3e0a2024-01-18 17:22:58 -0800545func (a *androidTransitionMutator) OutgoingTransition(bpctx blueprint.OutgoingTransitionContext, sourceVariation string) string {
546 if m, ok := bpctx.Module().(Module); ok {
Colin Cross98530ba2025-02-11 14:25:22 -0800547 ctx := outgoingTransitionContextPool.Get()
Colin Cross984223f2024-02-01 17:10:23 -0800548 defer outgoingTransitionContextPool.Put(ctx)
549 *ctx = outgoingTransitionContextImpl{
Colin Cross4aa3e0a2024-01-18 17:22:58 -0800550 archModuleContext: m.base().archModuleContextFactory(bpctx),
551 bp: bpctx,
552 }
553 return a.mutator.OutgoingTransition(ctx, sourceVariation)
Lukacs T. Berki6c716762022-06-13 20:50:39 +0200554 } else {
555 return ""
556 }
557}
558
559type incomingTransitionContextImpl struct {
Colin Cross4aa3e0a2024-01-18 17:22:58 -0800560 archModuleContext
Lukacs T. Berki6c716762022-06-13 20:50:39 +0200561 bp blueprint.IncomingTransitionContext
562}
563
564func (c *incomingTransitionContextImpl) Module() Module {
565 return c.bp.Module().(Module)
566}
567
568func (c *incomingTransitionContextImpl) Config() Config {
569 return c.bp.Config().(Config)
570}
571
Colin Cross4aa3e0a2024-01-18 17:22:58 -0800572func (c *incomingTransitionContextImpl) DeviceConfig() DeviceConfig {
573 return DeviceConfig{c.bp.Config().(Config).deviceConfig}
574}
575
Colin Crosse1a85552024-06-14 12:17:37 -0700576func (c *incomingTransitionContextImpl) IsAddingDependency() bool {
577 return c.bp.IsAddingDependency()
578}
579
Colin Crossaf333f52024-04-15 15:20:23 -0700580func (c *incomingTransitionContextImpl) provider(provider blueprint.AnyProviderKey) (any, bool) {
581 return c.bp.Provider(provider)
582}
583
Colin Cross4aa3e0a2024-01-18 17:22:58 -0800584func (a *androidTransitionMutator) IncomingTransition(bpctx blueprint.IncomingTransitionContext, incomingVariation string) string {
585 if m, ok := bpctx.Module().(Module); ok {
Colin Cross98530ba2025-02-11 14:25:22 -0800586 ctx := incomingTransitionContextPool.Get()
Colin Cross984223f2024-02-01 17:10:23 -0800587 defer incomingTransitionContextPool.Put(ctx)
588 *ctx = incomingTransitionContextImpl{
Colin Cross4aa3e0a2024-01-18 17:22:58 -0800589 archModuleContext: m.base().archModuleContextFactory(bpctx),
590 bp: bpctx,
591 }
592 return a.mutator.IncomingTransition(ctx, incomingVariation)
Lukacs T. Berki6c716762022-06-13 20:50:39 +0200593 } else {
594 return ""
595 }
596}
597
598func (a *androidTransitionMutator) Mutate(ctx blueprint.BottomUpMutatorContext, variation string) {
599 if am, ok := ctx.Module().(Module); ok {
Colin Cross888046f2024-05-01 14:20:31 -0700600 if variation != "" {
601 // TODO: this should really be checking whether the TransitionMutator affected this module, not
602 // the empty variant, but TransitionMutator has no concept of skipping a module.
603 base := am.base()
604 base.commonProperties.DebugMutators = append(base.commonProperties.DebugMutators, a.name)
605 base.commonProperties.DebugVariations = append(base.commonProperties.DebugVariations, variation)
606 }
607
Colin Cross984223f2024-02-01 17:10:23 -0800608 mctx := bottomUpMutatorContextFactory(ctx, am, a.finalPhase)
609 defer bottomUpMutatorContextPool.Put(mctx)
610 a.mutator.Mutate(mctx, variation)
Lukacs T. Berki6c716762022-06-13 20:50:39 +0200611 }
612}
613
614func (x *registerMutatorsContext) Transition(name string, m TransitionMutator) {
615 atm := &androidTransitionMutator{
Colin Crossb63d7b32023-12-07 16:54:51 -0800616 finalPhase: x.finalPhase,
617 mutator: m,
Colin Crossd67425d2024-04-15 15:17:05 -0700618 name: name,
Lukacs T. Berki6c716762022-06-13 20:50:39 +0200619 }
620 mutator := &mutator{
621 name: name,
622 transitionMutator: atm}
623 x.mutators = append(x.mutators, mutator)
624}
625
Liz Kammer356f7d42021-01-26 09:18:53 -0500626func (x *registerMutatorsContext) mutatorName(name string) string {
Liz Kammer356f7d42021-01-26 09:18:53 -0500627 return name
628}
629
Colin Cross25de6c32019-06-06 14:29:25 -0700630func (x *registerMutatorsContext) TopDown(name string, m TopDownMutator) MutatorHandle {
Colin Cross798bfce2016-10-12 14:28:16 -0700631 f := func(ctx blueprint.TopDownMutatorContext) {
Colin Cross635c3b02016-05-18 15:37:25 -0700632 if a, ok := ctx.Module().(Module); ok {
Chris Parsons5a34ffb2021-07-21 14:34:58 -0400633 moduleContext := a.base().baseModuleContextFactory(ctx)
Colin Cross98530ba2025-02-11 14:25:22 -0800634 actx := topDownMutatorContextPool.Get()
Colin Cross984223f2024-02-01 17:10:23 -0800635 defer topDownMutatorContextPool.Put(actx)
636 *actx = topDownMutatorContext{
Colin Crossdc35e212019-06-06 16:13:11 -0700637 bp: ctx,
Chris Parsons5a34ffb2021-07-21 14:34:58 -0400638 baseModuleContext: moduleContext,
Colin Cross6362e272015-10-29 15:25:03 -0700639 }
Colin Cross798bfce2016-10-12 14:28:16 -0700640 m(actx)
Colin Cross6362e272015-10-29 15:25:03 -0700641 }
Colin Cross798bfce2016-10-12 14:28:16 -0700642 }
Liz Kammer356f7d42021-01-26 09:18:53 -0500643 mutator := &mutator{name: x.mutatorName(name), topDownMutator: f}
Colin Cross795c3772017-03-16 16:50:10 -0700644 x.mutators = append(x.mutators, mutator)
Colin Cross798bfce2016-10-12 14:28:16 -0700645 return mutator
646}
647
Paul Duffin1d2d42f2021-03-06 20:08:12 +0000648func (mutator *mutator) componentName() string {
649 return mutator.name
650}
651
652func (mutator *mutator) register(ctx *Context) {
653 blueprintCtx := ctx.Context
654 var handle blueprint.MutatorHandle
655 if mutator.bottomUpMutator != nil {
656 handle = blueprintCtx.RegisterBottomUpMutator(mutator.name, mutator.bottomUpMutator)
657 } else if mutator.topDownMutator != nil {
658 handle = blueprintCtx.RegisterTopDownMutator(mutator.name, mutator.topDownMutator)
Lukacs T. Berki6c716762022-06-13 20:50:39 +0200659 } else if mutator.transitionMutator != nil {
660 blueprintCtx.RegisterTransitionMutator(mutator.name, mutator.transitionMutator)
Paul Duffin1d2d42f2021-03-06 20:08:12 +0000661 }
662 if mutator.parallel {
663 handle.Parallel()
664 }
665}
666
Colin Cross798bfce2016-10-12 14:28:16 -0700667type MutatorHandle interface {
668 Parallel() MutatorHandle
669}
670
671func (mutator *mutator) Parallel() MutatorHandle {
672 mutator.parallel = true
673 return mutator
Colin Cross6362e272015-10-29 15:25:03 -0700674}
Colin Cross1e676be2016-10-12 14:38:15 -0700675
Paul Duffin44f1d842020-06-26 20:17:02 +0100676func RegisterComponentsMutator(ctx RegisterMutatorsContext) {
677 ctx.BottomUp("component-deps", componentDepsMutator).Parallel()
678}
679
680// A special mutator that runs just prior to the deps mutator to allow the dependencies
681// on component modules to be added so that they can depend directly on a prebuilt
682// module.
683func componentDepsMutator(ctx BottomUpMutatorContext) {
Cole Fausta963b942024-04-11 17:43:00 -0700684 ctx.Module().ComponentDepsMutator(ctx)
Paul Duffin44f1d842020-06-26 20:17:02 +0100685}
686
Colin Cross1e676be2016-10-12 14:38:15 -0700687func depsMutator(ctx BottomUpMutatorContext) {
Cole Fausta963b942024-04-11 17:43:00 -0700688 if m := ctx.Module(); m.Enabled(ctx) {
Ronald Braunstein73b08ff2023-12-19 10:24:47 -0800689 m.base().baseDepsMutator(ctx)
Colin Cross1e676be2016-10-12 14:38:15 -0700690 m.DepsMutator(ctx)
691 }
692}
Colin Crossd11fcda2017-10-23 17:59:01 -0700693
Liz Kammer356f7d42021-01-26 09:18:53 -0500694func registerDepsMutator(ctx RegisterMutatorsContext) {
695 ctx.BottomUp("deps", depsMutator).Parallel()
696}
697
Colin Crossdc35e212019-06-06 16:13:11 -0700698// 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
Colin Crosscb55e082019-07-01 15:32:31 -0700704func (t *topDownMutatorContext) MutatorName() string {
705 return t.bp.MutatorName()
706}
707
Colin Crossdc35e212019-06-06 16:13:11 -0700708func (t *topDownMutatorContext) Rename(name string) {
709 t.bp.Rename(name)
Colin Cross9a362232019-07-01 15:32:45 -0700710 t.Module().base().commonProperties.DebugName = name
Colin Crossdc35e212019-06-06 16:13:11 -0700711}
712
Liz Kammerf31c9002022-04-26 09:08:55 -0400713func (t *topDownMutatorContext) createModule(factory blueprint.ModuleFactory, name string, props ...interface{}) blueprint.Module {
714 return t.bp.CreateModule(factory, name, props...)
715}
716
Colin Crosse003c4a2019-09-25 12:58:36 -0700717func (t *topDownMutatorContext) CreateModule(factory ModuleFactory, props ...interface{}) Module {
Liz Kammerf31c9002022-04-26 09:08:55 -0400718 return createModule(t, factory, "_topDownMutatorModule", props...)
Colin Crossdc35e212019-06-06 16:13:11 -0700719}
720
Liz Kammera060c452021-03-24 10:14:47 -0400721func (t *topDownMutatorContext) createModuleWithoutInheritance(factory ModuleFactory, props ...interface{}) Module {
Liz Kammerf31c9002022-04-26 09:08:55 -0400722 module := t.bp.CreateModule(ModuleFactoryAdaptor(factory), "", props...).(Module)
Liz Kammera060c452021-03-24 10:14:47 -0400723 return module
724}
725
Colin Crosscb55e082019-07-01 15:32:31 -0700726func (b *bottomUpMutatorContext) MutatorName() string {
727 return b.bp.MutatorName()
728}
729
Colin Crossdc35e212019-06-06 16:13:11 -0700730func (b *bottomUpMutatorContext) Rename(name string) {
731 b.bp.Rename(name)
Colin Cross9a362232019-07-01 15:32:45 -0700732 b.Module().base().commonProperties.DebugName = name
Colin Crossdc35e212019-06-06 16:13:11 -0700733}
734
Colin Crossda279cf2024-09-17 14:25:45 -0700735func (b *bottomUpMutatorContext) createModule(factory blueprint.ModuleFactory, name string, props ...interface{}) blueprint.Module {
736 return b.bp.CreateModule(factory, name, props...)
737}
738
739func (b *bottomUpMutatorContext) CreateModule(factory ModuleFactory, props ...interface{}) Module {
740 return createModule(b, factory, "_bottomUpMutatorModule", props...)
741}
742
Colin Cross4f1dcb02020-09-16 18:45:04 -0700743func (b *bottomUpMutatorContext) AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) []blueprint.Module {
Liz Kammerc13f7852023-05-17 13:01:48 -0400744 if b.baseModuleContext.checkedMissingDeps() {
745 panic("Adding deps not allowed after checking for missing deps")
746 }
Colin Cross4f1dcb02020-09-16 18:45:04 -0700747 return b.bp.AddDependency(module, tag, name...)
Colin Crossdc35e212019-06-06 16:13:11 -0700748}
749
750func (b *bottomUpMutatorContext) AddReverseDependency(module blueprint.Module, tag blueprint.DependencyTag, name string) {
Liz Kammerc13f7852023-05-17 13:01:48 -0400751 if b.baseModuleContext.checkedMissingDeps() {
752 panic("Adding deps not allowed after checking for missing deps")
753 }
Colin Crossdc35e212019-06-06 16:13:11 -0700754 b.bp.AddReverseDependency(module, tag, name)
755}
756
Colin Cross43b92e02019-11-18 15:28:57 -0800757func (b *bottomUpMutatorContext) CreateVariations(variations ...string) []Module {
Martin Stjernholm710ec3a2020-01-16 15:12:04 +0000758 if b.finalPhase {
759 panic("CreateVariations not allowed in FinalDepsMutators")
760 }
761
Colin Cross9a362232019-07-01 15:32:45 -0700762 modules := b.bp.CreateVariations(variations...)
763
Colin Cross43b92e02019-11-18 15:28:57 -0800764 aModules := make([]Module, len(modules))
Colin Cross9a362232019-07-01 15:32:45 -0700765 for i := range variations {
Colin Cross43b92e02019-11-18 15:28:57 -0800766 aModules[i] = modules[i].(Module)
767 base := aModules[i].base()
Colin Cross9a362232019-07-01 15:32:45 -0700768 base.commonProperties.DebugMutators = append(base.commonProperties.DebugMutators, b.MutatorName())
769 base.commonProperties.DebugVariations = append(base.commonProperties.DebugVariations, variations[i])
770 }
771
Colin Cross43b92e02019-11-18 15:28:57 -0800772 return aModules
Colin Crossdc35e212019-06-06 16:13:11 -0700773}
774
Colin Cross43b92e02019-11-18 15:28:57 -0800775func (b *bottomUpMutatorContext) CreateLocalVariations(variations ...string) []Module {
Martin Stjernholm710ec3a2020-01-16 15:12:04 +0000776 if b.finalPhase {
777 panic("CreateLocalVariations not allowed in FinalDepsMutators")
778 }
779
Colin Cross9a362232019-07-01 15:32:45 -0700780 modules := b.bp.CreateLocalVariations(variations...)
781
Colin Cross43b92e02019-11-18 15:28:57 -0800782 aModules := make([]Module, len(modules))
Colin Cross9a362232019-07-01 15:32:45 -0700783 for i := range variations {
Colin Cross43b92e02019-11-18 15:28:57 -0800784 aModules[i] = modules[i].(Module)
785 base := aModules[i].base()
Colin Cross9a362232019-07-01 15:32:45 -0700786 base.commonProperties.DebugMutators = append(base.commonProperties.DebugMutators, b.MutatorName())
787 base.commonProperties.DebugVariations = append(base.commonProperties.DebugVariations, variations[i])
788 }
789
Colin Cross43b92e02019-11-18 15:28:57 -0800790 return aModules
Colin Crossdc35e212019-06-06 16:13:11 -0700791}
792
793func (b *bottomUpMutatorContext) SetDependencyVariation(variation string) {
794 b.bp.SetDependencyVariation(variation)
795}
796
Jiyong Park1d1119f2019-07-29 21:27:18 +0900797func (b *bottomUpMutatorContext) SetDefaultDependencyVariation(variation *string) {
798 b.bp.SetDefaultDependencyVariation(variation)
799}
800
Colin Crossdc35e212019-06-06 16:13:11 -0700801func (b *bottomUpMutatorContext) AddVariationDependencies(variations []blueprint.Variation, tag blueprint.DependencyTag,
Colin Cross4f1dcb02020-09-16 18:45:04 -0700802 names ...string) []blueprint.Module {
Liz Kammerc13f7852023-05-17 13:01:48 -0400803 if b.baseModuleContext.checkedMissingDeps() {
804 panic("Adding deps not allowed after checking for missing deps")
805 }
Colin Cross4f1dcb02020-09-16 18:45:04 -0700806 return b.bp.AddVariationDependencies(variations, tag, names...)
Colin Crossdc35e212019-06-06 16:13:11 -0700807}
808
809func (b *bottomUpMutatorContext) AddFarVariationDependencies(variations []blueprint.Variation,
Colin Cross4f1dcb02020-09-16 18:45:04 -0700810 tag blueprint.DependencyTag, names ...string) []blueprint.Module {
Liz Kammerc13f7852023-05-17 13:01:48 -0400811 if b.baseModuleContext.checkedMissingDeps() {
812 panic("Adding deps not allowed after checking for missing deps")
813 }
Colin Crossdc35e212019-06-06 16:13:11 -0700814
Colin Cross4f1dcb02020-09-16 18:45:04 -0700815 return b.bp.AddFarVariationDependencies(variations, tag, names...)
Colin Crossdc35e212019-06-06 16:13:11 -0700816}
817
818func (b *bottomUpMutatorContext) AddInterVariantDependency(tag blueprint.DependencyTag, from, to blueprint.Module) {
819 b.bp.AddInterVariantDependency(tag, from, to)
820}
821
822func (b *bottomUpMutatorContext) ReplaceDependencies(name string) {
Liz Kammerc13f7852023-05-17 13:01:48 -0400823 if b.baseModuleContext.checkedMissingDeps() {
824 panic("Adding deps not allowed after checking for missing deps")
825 }
Colin Crossdc35e212019-06-06 16:13:11 -0700826 b.bp.ReplaceDependencies(name)
827}
Jaewoong Jung9f88ce22019-11-15 10:57:34 -0800828
Paul Duffin80342d72020-06-26 22:08:43 +0100829func (b *bottomUpMutatorContext) ReplaceDependenciesIf(name string, predicate blueprint.ReplaceDependencyPredicate) {
Liz Kammerc13f7852023-05-17 13:01:48 -0400830 if b.baseModuleContext.checkedMissingDeps() {
831 panic("Adding deps not allowed after checking for missing deps")
832 }
Paul Duffin80342d72020-06-26 22:08:43 +0100833 b.bp.ReplaceDependenciesIf(name, predicate)
834}
835
Jaewoong Jung9f88ce22019-11-15 10:57:34 -0800836func (b *bottomUpMutatorContext) AliasVariation(variationName string) {
837 b.bp.AliasVariation(variationName)
838}
Colin Cross1b9604b2020-08-11 12:03:56 -0700839
840func (b *bottomUpMutatorContext) CreateAliasVariation(fromVariationName, toVariationName string) {
841 b.bp.CreateAliasVariation(fromVariationName, toVariationName)
842}
Colin Crossd27e7b82020-07-02 11:38:17 -0700843
Colin Cross3c0a83d2023-12-12 14:13:26 -0800844func (b *bottomUpMutatorContext) SetVariationProvider(module blueprint.Module, provider blueprint.AnyProviderKey, value interface{}) {
Colin Crossd27e7b82020-07-02 11:38:17 -0700845 b.bp.SetVariationProvider(module, provider, value)
846}