blob: 06819d64a10134f9d6360ff20723897fd3f6d6d1 [file] [log] [blame]
Colin Cross69452e12023-11-15 11:20:53 -08001// Copyright 2015 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package android
16
17import (
18 "fmt"
Colin Cross69452e12023-11-15 11:20:53 -080019 "regexp"
Colin Crossb614cd42024-10-11 12:52:21 -070020 "slices"
Colin Cross69452e12023-11-15 11:20:53 -080021 "strings"
Cole Faustbdd8aee2024-03-14 14:33:02 -070022
23 "github.com/google/blueprint"
Cole Faustfdbf5d42024-04-10 15:01:23 -070024 "github.com/google/blueprint/proptools"
Colin Cross69452e12023-11-15 11:20:53 -080025)
26
27// BaseModuleContext is the same as blueprint.BaseModuleContext except that Config() returns
28// a Config instead of an interface{}, and some methods have been wrapped to use an android.Module
29// instead of a blueprint.Module, plus some extra methods that return Android-specific information
30// about the current module.
31type BaseModuleContext interface {
Colin Cross1d3d9f12024-01-18 14:30:22 -080032 ArchModuleContext
Colin Cross69452e12023-11-15 11:20:53 -080033 EarlyModuleContext
34
35 blueprintBaseModuleContext() blueprint.BaseModuleContext
36
Yu Liudd9ccb42024-10-07 17:07:44 +000037 EqualModules(m1, m2 Module) bool
38
Colin Cross69452e12023-11-15 11:20:53 -080039 // OtherModuleName returns the name of another Module. See BaseModuleContext.ModuleName for more information.
40 // It is intended for use inside the visit functions of Visit* and WalkDeps.
41 OtherModuleName(m blueprint.Module) string
42
43 // OtherModuleDir returns the directory of another Module. See BaseModuleContext.ModuleDir for more information.
44 // It is intended for use inside the visit functions of Visit* and WalkDeps.
45 OtherModuleDir(m blueprint.Module) string
46
47 // OtherModuleErrorf reports an error on another Module. See BaseModuleContext.ModuleErrorf for more information.
48 // It is intended for use inside the visit functions of Visit* and WalkDeps.
49 OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{})
50
51 // OtherModuleDependencyTag returns the dependency tag used to depend on a module, or nil if there is no dependency
52 // on the module. When called inside a Visit* method with current module being visited, and there are multiple
53 // dependencies on the module being visited, it returns the dependency tag used for the current dependency.
54 OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag
55
56 // OtherModuleExists returns true if a module with the specified name exists, as determined by the NameInterface
57 // passed to Context.SetNameInterface, or SimpleNameInterface if it was not called.
58 OtherModuleExists(name string) bool
59
60 // OtherModuleDependencyVariantExists returns true if a module with the
61 // specified name and variant exists. The variant must match the given
62 // variations. It must also match all the non-local variations of the current
63 // module. In other words, it checks for the module that AddVariationDependencies
64 // would add a dependency on with the same arguments.
65 OtherModuleDependencyVariantExists(variations []blueprint.Variation, name string) bool
66
67 // OtherModuleFarDependencyVariantExists returns true if a module with the
68 // specified name and variant exists. The variant must match the given
69 // variations, but not the non-local variations of the current module. In
70 // other words, it checks for the module that AddFarVariationDependencies
71 // would add a dependency on with the same arguments.
72 OtherModuleFarDependencyVariantExists(variations []blueprint.Variation, name string) bool
73
74 // OtherModuleReverseDependencyVariantExists returns true if a module with the
75 // specified name exists with the same variations as the current module. In
76 // other words, it checks for the module that AddReverseDependency would add a
77 // dependency on with the same argument.
78 OtherModuleReverseDependencyVariantExists(name string) bool
79
80 // OtherModuleType returns the type of another Module. See BaseModuleContext.ModuleType for more information.
81 // It is intended for use inside the visit functions of Visit* and WalkDeps.
82 OtherModuleType(m blueprint.Module) string
83
Colin Cross24c1cbe2023-12-21 23:42:56 +000084 // otherModuleProvider returns the value for a provider for the given module. If the value is
85 // not set it returns nil and false. The value returned may be a deep copy of the value originally
86 // passed to SetProvider.
87 //
88 // This method shouldn't be used directly, prefer the type-safe android.OtherModuleProvider instead.
Colin Cross3c0a83d2023-12-12 14:13:26 -080089 otherModuleProvider(m blueprint.Module, provider blueprint.AnyProviderKey) (any, bool)
Colin Cross69452e12023-11-15 11:20:53 -080090
Jihoon Kang2a7bf752024-11-01 21:21:25 +000091 // OtherModuleIsAutoGenerated returns true if the module is auto generated by another module
92 // instead of being defined in Android.bp file.
93 OtherModuleIsAutoGenerated(m blueprint.Module) bool
94
Colin Cross69452e12023-11-15 11:20:53 -080095 // Provider returns the value for a provider for the current module. If the value is
Colin Cross24c1cbe2023-12-21 23:42:56 +000096 // not set it returns nil and false. It panics if called before the appropriate
Colin Cross69452e12023-11-15 11:20:53 -080097 // mutator or GenerateBuildActions pass for the provider. The value returned may be a deep
98 // copy of the value originally passed to SetProvider.
Colin Cross24c1cbe2023-12-21 23:42:56 +000099 //
100 // This method shouldn't be used directly, prefer the type-safe android.ModuleProvider instead.
Colin Cross3c0a83d2023-12-12 14:13:26 -0800101 provider(provider blueprint.AnyProviderKey) (any, bool)
Colin Cross69452e12023-11-15 11:20:53 -0800102
Colin Cross24c1cbe2023-12-21 23:42:56 +0000103 // setProvider sets the value for a provider for the current module. It panics if not called
Colin Cross69452e12023-11-15 11:20:53 -0800104 // during the appropriate mutator or GenerateBuildActions pass for the provider, if the value
105 // is not of the appropriate type, or if the value has already been set. The value should not
106 // be modified after being passed to SetProvider.
Colin Cross24c1cbe2023-12-21 23:42:56 +0000107 //
108 // This method shouldn't be used directly, prefer the type-safe android.SetProvider instead.
109 setProvider(provider blueprint.AnyProviderKey, value any)
Colin Cross69452e12023-11-15 11:20:53 -0800110
111 GetDirectDepsWithTag(tag blueprint.DependencyTag) []Module
112
113 // GetDirectDepWithTag returns the Module the direct dependency with the specified name, or nil if
114 // none exists. It panics if the dependency does not have the specified tag. It skips any
115 // dependencies that are not an android.Module.
Yu Liud3228ac2024-11-08 23:11:47 +0000116 GetDirectDepWithTag(name string, tag blueprint.DependencyTag) Module
Colin Cross69452e12023-11-15 11:20:53 -0800117
LaMont Jones34314b72024-01-18 18:27:35 +0000118 // GetDirectDep returns the Module and DependencyTag for the direct dependency with the specified
Colin Cross69452e12023-11-15 11:20:53 -0800119 // name, or nil if none exists. If there are multiple dependencies on the same module it returns
120 // the first DependencyTag.
121 GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
122
Colin Cross648daea2024-09-12 14:35:29 -0700123 // VisitDirectDeps calls visit for each direct dependency. If there are multiple
124 // direct dependencies on the same module visit will be called multiple times on that module
125 // and OtherModuleDependencyTag will return a different tag for each. It raises an error if any of the
126 // dependencies are disabled.
127 //
128 // The Module passed to the visit function should not be retained outside of the visit
129 // function, it may be invalidated by future mutators.
130 VisitDirectDeps(visit func(Module))
131
Yu Liud3228ac2024-11-08 23:11:47 +0000132 // VisitDirectDepsProxy calls visit for each direct dependency. If there are multiple
Colin Cross69452e12023-11-15 11:20:53 -0800133 // direct dependencies on the same module visit will be called multiple times on that module
Yu Liud3228ac2024-11-08 23:11:47 +0000134 // and OtherModuleDependencyTag will return a different tag for each. It raises an error if any of the
135 // dependencies are disabled.
Colin Cross69452e12023-11-15 11:20:53 -0800136 //
Yu Liud3228ac2024-11-08 23:11:47 +0000137 // The ModuleProxy passed to the visit function should not be retained outside of the visit
Colin Cross69452e12023-11-15 11:20:53 -0800138 // function, it may be invalidated by future mutators.
Yu Liud3228ac2024-11-08 23:11:47 +0000139 VisitDirectDepsProxy(visit func(proxy ModuleProxy))
Colin Cross69452e12023-11-15 11:20:53 -0800140
Yu Liudd9ccb42024-10-07 17:07:44 +0000141 // VisitDirectDepsProxyAllowDisabled calls visit for each direct dependency. If there are
142 // multiple direct dependencies on the same module visit will be called multiple times on
143 // that module and OtherModuleDependencyTag will return a different tag for each.
144 //
Yu Liud2a95952024-10-10 00:15:26 +0000145 // The ModuleProxy passed to the visit function should not be retained outside of the visit function, it may be
Yu Liudd9ccb42024-10-07 17:07:44 +0000146 // invalidated by future mutators.
Yu Liud2a95952024-10-10 00:15:26 +0000147 VisitDirectDepsProxyAllowDisabled(visit func(proxy ModuleProxy))
Yu Liudd9ccb42024-10-07 17:07:44 +0000148
Colin Cross69452e12023-11-15 11:20:53 -0800149 VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module))
150
Yu Liud2a95952024-10-10 00:15:26 +0000151 VisitDirectDepsProxyWithTag(tag blueprint.DependencyTag, visit func(proxy ModuleProxy))
152
Colin Cross69452e12023-11-15 11:20:53 -0800153 // VisitDirectDepsIf calls pred for each direct dependency, and if pred returns true calls visit. If there are
154 // multiple direct dependencies on the same module pred and visit will be called multiple times on that module and
155 // OtherModuleDependencyTag will return a different tag for each. It skips any
156 // dependencies that are not an android.Module.
157 //
158 // The Module passed to the visit function should not be retained outside of the visit function, it may be
159 // invalidated by future mutators.
160 VisitDirectDepsIf(pred func(Module) bool, visit func(Module))
161 // Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
162 VisitDepsDepthFirst(visit func(Module))
163 // Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
164 VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
165
166 // WalkDeps calls visit for each transitive dependency, traversing the dependency tree in top down order. visit may
167 // be called multiple times for the same (child, parent) pair if there are multiple direct dependencies between the
168 // child and parent with different tags. OtherModuleDependencyTag will return the tag for the currently visited
169 // (child, parent) pair. If visit returns false WalkDeps will not continue recursing down to child. It skips
170 // any dependencies that are not an android.Module.
171 //
172 // The Modules passed to the visit function should not be retained outside of the visit function, they may be
173 // invalidated by future mutators.
174 WalkDeps(visit func(child, parent Module) bool)
175
Yu Liudd9ccb42024-10-07 17:07:44 +0000176 // WalkDeps calls visit for each transitive dependency, traversing the dependency tree in top down order. visit may
177 // be called multiple times for the same (child, parent) pair if there are multiple direct dependencies between the
178 // child and parent with different tags. OtherModuleDependencyTag will return the tag for the currently visited
179 // (child, parent) pair. If visit returns false WalkDeps will not continue recursing down to child. It skips
180 // any dependencies that are not an android.Module.
181 //
182 // The Modules passed to the visit function should not be retained outside of the visit function, they may be
183 // invalidated by future mutators.
Yu Liud2a95952024-10-10 00:15:26 +0000184 WalkDepsProxy(visit func(child, parent ModuleProxy) bool)
Yu Liudd9ccb42024-10-07 17:07:44 +0000185
Colin Cross69452e12023-11-15 11:20:53 -0800186 // GetWalkPath is supposed to be called in visit function passed in WalkDeps()
187 // and returns a top-down dependency path from a start module to current child module.
188 GetWalkPath() []Module
189
190 // PrimaryModule returns the first variant of the current module. Variants of a module are always visited in
191 // order by mutators and GenerateBuildActions, so the data created by the current mutator can be read from the
192 // Module returned by PrimaryModule without data races. This can be used to perform singleton actions that are
193 // only done once for all variants of a module.
194 PrimaryModule() Module
195
196 // FinalModule returns the last variant of the current module. Variants of a module are always visited in
197 // order by mutators and GenerateBuildActions, so the data created by the current mutator can be read from all
198 // variants using VisitAllModuleVariants if the current module == FinalModule(). This can be used to perform
199 // singleton actions that are only done once for all variants of a module.
200 FinalModule() Module
201
Yu Liu88ea9ff2024-11-07 19:19:42 +0000202 // IsFinalModule returns if the current module is the last variant. Variants of a module are always visited in
203 // order by mutators and GenerateBuildActions, so the data created by the current mutator can be read from all
204 // variants using VisitAllModuleVariants if the current module is the last one. This can be used to perform
205 // singleton actions that are only done once for all variants of a module.
206 IsFinalModule(module Module) bool
207
Colin Cross69452e12023-11-15 11:20:53 -0800208 // VisitAllModuleVariants calls visit for each variant of the current module. Variants of a module are always
209 // visited in order by mutators and GenerateBuildActions, so the data created by the current mutator can be read
Yu Liu88ea9ff2024-11-07 19:19:42 +0000210 // from all variants if the current module is the last one. Otherwise, care must be taken to not access any
Colin Cross69452e12023-11-15 11:20:53 -0800211 // data modified by the current mutator.
212 VisitAllModuleVariants(visit func(Module))
213
Yu Liub5275322024-11-13 18:40:43 +0000214 // VisitAllModuleVariantProxies calls visit for each variant of the current module. Variants of a module are always
215 // visited in order by mutators and GenerateBuildActions, so the data created by the current mutator can be read
216 // from all variants if the current module is the last one. Otherwise, care must be taken to not access any
217 // data modified by the current mutator.
218 VisitAllModuleVariantProxies(visit func(proxy ModuleProxy))
219
Colin Cross69452e12023-11-15 11:20:53 -0800220 // GetTagPath is supposed to be called in visit function passed in WalkDeps()
221 // and returns a top-down dependency tags path from a start module to current child module.
222 // It has one less entry than GetWalkPath() as it contains the dependency tags that
223 // exist between each adjacent pair of modules in the GetWalkPath().
224 // GetTagPath()[i] is the tag between GetWalkPath()[i] and GetWalkPath()[i+1]
225 GetTagPath() []blueprint.DependencyTag
226
227 // GetPathString is supposed to be called in visit function passed in WalkDeps()
228 // and returns a multi-line string showing the modules and dependency tags
229 // among them along the top-down dependency path from a start module to current child module.
230 // skipFirst when set to true, the output doesn't include the start module,
231 // which is already printed when this function is used along with ModuleErrorf().
232 GetPathString(skipFirst bool) string
233
234 AddMissingDependencies(missingDeps []string)
235
236 // getMissingDependencies returns the list of missing dependencies.
237 // Calling this function prevents adding new dependencies.
238 getMissingDependencies() []string
Cole Faustbdd8aee2024-03-14 14:33:02 -0700239
240 // EvaluateConfiguration makes ModuleContext a valid proptools.ConfigurableEvaluator, so this context
241 // can be used to evaluate the final value of Configurable properties.
Cole Faustfdbf5d42024-04-10 15:01:23 -0700242 EvaluateConfiguration(condition proptools.ConfigurableCondition, property string) proptools.ConfigurableValue
Colin Cross69452e12023-11-15 11:20:53 -0800243}
244
245type baseModuleContext struct {
246 bp blueprint.BaseModuleContext
247 earlyModuleContext
Colin Cross1d3d9f12024-01-18 14:30:22 -0800248 archModuleContext
Colin Cross69452e12023-11-15 11:20:53 -0800249
250 walkPath []Module
251 tagPath []blueprint.DependencyTag
252
253 strictVisitDeps bool // If true, enforce that all dependencies are enabled
254
Colin Cross69452e12023-11-15 11:20:53 -0800255}
256
Yu Liudd9ccb42024-10-07 17:07:44 +0000257func getWrappedModule(module blueprint.Module) blueprint.Module {
258 if mp, isProxy := module.(ModuleProxy); isProxy {
259 return mp.module
260 }
261 return module
262}
263
264func (b *baseModuleContext) EqualModules(m1, m2 Module) bool {
265 return b.bp.EqualModules(getWrappedModule(m1), getWrappedModule(m2))
266}
267
Colin Cross69452e12023-11-15 11:20:53 -0800268func (b *baseModuleContext) OtherModuleName(m blueprint.Module) string {
Yu Liudd9ccb42024-10-07 17:07:44 +0000269 return b.bp.OtherModuleName(getWrappedModule(m))
Colin Cross69452e12023-11-15 11:20:53 -0800270}
Yu Liud3228ac2024-11-08 23:11:47 +0000271func (b *baseModuleContext) OtherModuleDir(m blueprint.Module) string {
272 return b.bp.OtherModuleDir(getWrappedModule(m))
273}
Colin Cross69452e12023-11-15 11:20:53 -0800274func (b *baseModuleContext) OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{}) {
Yu Liuac483e02024-11-11 22:29:30 +0000275 b.bp.OtherModuleErrorf(getWrappedModule(m), fmt, args...)
Colin Cross69452e12023-11-15 11:20:53 -0800276}
277func (b *baseModuleContext) OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag {
Yu Liudd9ccb42024-10-07 17:07:44 +0000278 return b.bp.OtherModuleDependencyTag(getWrappedModule(m))
Colin Cross69452e12023-11-15 11:20:53 -0800279}
280func (b *baseModuleContext) OtherModuleExists(name string) bool { return b.bp.OtherModuleExists(name) }
281func (b *baseModuleContext) OtherModuleDependencyVariantExists(variations []blueprint.Variation, name string) bool {
282 return b.bp.OtherModuleDependencyVariantExists(variations, name)
283}
284func (b *baseModuleContext) OtherModuleFarDependencyVariantExists(variations []blueprint.Variation, name string) bool {
285 return b.bp.OtherModuleFarDependencyVariantExists(variations, name)
286}
287func (b *baseModuleContext) OtherModuleReverseDependencyVariantExists(name string) bool {
288 return b.bp.OtherModuleReverseDependencyVariantExists(name)
289}
290func (b *baseModuleContext) OtherModuleType(m blueprint.Module) string {
Yu Liub1bfa9d2024-12-05 18:57:51 +0000291 return b.bp.OtherModuleType(getWrappedModule(m))
Colin Cross69452e12023-11-15 11:20:53 -0800292}
Colin Cross3c0a83d2023-12-12 14:13:26 -0800293
294func (b *baseModuleContext) otherModuleProvider(m blueprint.Module, provider blueprint.AnyProviderKey) (any, bool) {
Colin Cross69452e12023-11-15 11:20:53 -0800295 return b.bp.OtherModuleProvider(m, provider)
296}
Colin Cross3c0a83d2023-12-12 14:13:26 -0800297
Jihoon Kang2a7bf752024-11-01 21:21:25 +0000298func (b *baseModuleContext) OtherModuleIsAutoGenerated(m blueprint.Module) bool {
299 return b.bp.OtherModuleIsAutoGenerated(m)
300}
301
Colin Cross3c0a83d2023-12-12 14:13:26 -0800302func (b *baseModuleContext) provider(provider blueprint.AnyProviderKey) (any, bool) {
Colin Cross69452e12023-11-15 11:20:53 -0800303 return b.bp.Provider(provider)
304}
Colin Cross3c0a83d2023-12-12 14:13:26 -0800305
Colin Cross24c1cbe2023-12-21 23:42:56 +0000306func (b *baseModuleContext) setProvider(provider blueprint.AnyProviderKey, value any) {
Colin Cross69452e12023-11-15 11:20:53 -0800307 b.bp.SetProvider(provider, value)
308}
309
Yu Liud3228ac2024-11-08 23:11:47 +0000310func (b *baseModuleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) Module {
311 if module := b.bp.GetDirectDepWithTag(name, tag); module != nil {
312 return module.(Module)
313 }
314 return nil
Colin Cross69452e12023-11-15 11:20:53 -0800315}
316
317func (b *baseModuleContext) blueprintBaseModuleContext() blueprint.BaseModuleContext {
318 return b.bp
319}
320
Colin Cross69452e12023-11-15 11:20:53 -0800321func (b *baseModuleContext) AddMissingDependencies(deps []string) {
322 if deps != nil {
323 missingDeps := &b.Module().base().commonProperties.MissingDeps
324 *missingDeps = append(*missingDeps, deps...)
325 *missingDeps = FirstUniqueStrings(*missingDeps)
326 }
327}
328
329func (b *baseModuleContext) checkedMissingDeps() bool {
330 return b.Module().base().commonProperties.CheckedMissingDeps
331}
332
333func (b *baseModuleContext) getMissingDependencies() []string {
334 checked := &b.Module().base().commonProperties.CheckedMissingDeps
335 *checked = true
336 var missingDeps []string
337 missingDeps = append(missingDeps, b.Module().base().commonProperties.MissingDeps...)
338 missingDeps = append(missingDeps, b.bp.EarlyGetMissingDependencies()...)
339 missingDeps = FirstUniqueStrings(missingDeps)
340 return missingDeps
341}
342
343type AllowDisabledModuleDependency interface {
344 blueprint.DependencyTag
345 AllowDisabledModuleDependency(target Module) bool
Yu Liud2a95952024-10-10 00:15:26 +0000346 AllowDisabledModuleDependencyProxy(ctx OtherModuleProviderContext, target ModuleProxy) bool
Colin Cross69452e12023-11-15 11:20:53 -0800347}
348
Jiyong Park8bcf3c62024-03-18 18:37:10 +0900349type AlwaysAllowDisabledModuleDependencyTag struct{}
350
351func (t AlwaysAllowDisabledModuleDependencyTag) AllowDisabledModuleDependency(Module) bool {
352 return true
353}
354
Yu Liud2a95952024-10-10 00:15:26 +0000355func (t AlwaysAllowDisabledModuleDependencyTag) AllowDisabledModuleDependencyProxy(OtherModuleProviderContext, ModuleProxy) bool {
356 return true
357}
358
Colin Cross648daea2024-09-12 14:35:29 -0700359func (b *baseModuleContext) validateAndroidModule(module blueprint.Module, tag blueprint.DependencyTag, strict bool) Module {
Colin Cross69452e12023-11-15 11:20:53 -0800360 aModule, _ := module.(Module)
361
362 if !strict {
363 return aModule
364 }
365
366 if aModule == nil {
Colin Cross648daea2024-09-12 14:35:29 -0700367 panic(fmt.Errorf("module %q (%#v) not an android module", b.OtherModuleName(module), tag))
Colin Cross69452e12023-11-15 11:20:53 -0800368 }
369
Cole Fausta963b942024-04-11 17:43:00 -0700370 if !aModule.Enabled(b) {
Colin Cross69452e12023-11-15 11:20:53 -0800371 if t, ok := tag.(AllowDisabledModuleDependency); !ok || !t.AllowDisabledModuleDependency(aModule) {
372 if b.Config().AllowMissingDependencies() {
373 b.AddMissingDependencies([]string{b.OtherModuleName(aModule)})
374 } else {
375 b.ModuleErrorf("depends on disabled module %q", b.OtherModuleName(aModule))
376 }
377 }
378 return nil
379 }
380 return aModule
381}
382
Yu Liud2a95952024-10-10 00:15:26 +0000383func (b *baseModuleContext) validateAndroidModuleProxy(
384 module blueprint.ModuleProxy, tag blueprint.DependencyTag, strict bool) *ModuleProxy {
385 aModule := ModuleProxy{module: module}
386
387 if !strict {
388 return &aModule
389 }
390
Yu Liub5275322024-11-13 18:40:43 +0000391 if !OtherModuleProviderOrDefault(b, module, CommonModuleInfoKey).Enabled {
Yu Liud2a95952024-10-10 00:15:26 +0000392 if t, ok := tag.(AllowDisabledModuleDependency); !ok || !t.AllowDisabledModuleDependencyProxy(b, aModule) {
393 if b.Config().AllowMissingDependencies() {
394 b.AddMissingDependencies([]string{b.OtherModuleName(aModule)})
395 } else {
396 b.ModuleErrorf("depends on disabled module %q", b.OtherModuleName(aModule))
397 }
398 }
399 return nil
400 }
401
402 return &aModule
403}
404
Colin Cross69452e12023-11-15 11:20:53 -0800405type dep struct {
406 mod blueprint.Module
407 tag blueprint.DependencyTag
408}
409
410func (b *baseModuleContext) getDirectDepsInternal(name string, tag blueprint.DependencyTag) []dep {
411 var deps []dep
Colin Cross648daea2024-09-12 14:35:29 -0700412 b.VisitDirectDeps(func(module Module) {
413 if module.base().BaseModuleName() == name {
Colin Cross69452e12023-11-15 11:20:53 -0800414 returnedTag := b.bp.OtherModuleDependencyTag(module)
415 if tag == nil || returnedTag == tag {
416 deps = append(deps, dep{module, returnedTag})
417 }
418 }
419 })
420 return deps
421}
422
423func (b *baseModuleContext) getDirectDepInternal(name string, tag blueprint.DependencyTag) (blueprint.Module, blueprint.DependencyTag) {
424 deps := b.getDirectDepsInternal(name, tag)
425 if len(deps) == 1 {
426 return deps[0].mod, deps[0].tag
427 } else if len(deps) >= 2 {
428 panic(fmt.Errorf("Multiple dependencies having same BaseModuleName() %q found from %q",
429 name, b.ModuleName()))
430 } else {
431 return nil, nil
432 }
433}
434
435func (b *baseModuleContext) getDirectDepFirstTag(name string) (blueprint.Module, blueprint.DependencyTag) {
436 foundDeps := b.getDirectDepsInternal(name, nil)
437 deps := map[blueprint.Module]bool{}
438 for _, dep := range foundDeps {
439 deps[dep.mod] = true
440 }
441 if len(deps) == 1 {
442 return foundDeps[0].mod, foundDeps[0].tag
443 } else if len(deps) >= 2 {
444 // this could happen if two dependencies have the same name in different namespaces
445 // TODO(b/186554727): this should not occur if namespaces are handled within
446 // getDirectDepsInternal.
447 panic(fmt.Errorf("Multiple dependencies having same BaseModuleName() %q found from %q",
448 name, b.ModuleName()))
449 } else {
450 return nil, nil
451 }
452}
453
454func (b *baseModuleContext) GetDirectDepsWithTag(tag blueprint.DependencyTag) []Module {
455 var deps []Module
Colin Cross648daea2024-09-12 14:35:29 -0700456 b.VisitDirectDeps(func(module Module) {
457 if b.bp.OtherModuleDependencyTag(module) == tag {
458 deps = append(deps, module)
Colin Cross69452e12023-11-15 11:20:53 -0800459 }
460 })
461 return deps
462}
463
464// GetDirectDep returns the Module and DependencyTag for the direct dependency with the specified
465// name, or nil if none exists. If there are multiple dependencies on the same module it returns the
466// first DependencyTag.
467func (b *baseModuleContext) GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag) {
468 return b.getDirectDepFirstTag(name)
469}
470
Colin Cross69452e12023-11-15 11:20:53 -0800471func (b *baseModuleContext) VisitDirectDeps(visit func(Module)) {
472 b.bp.VisitDirectDeps(func(module blueprint.Module) {
Colin Cross648daea2024-09-12 14:35:29 -0700473 if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil {
Colin Cross69452e12023-11-15 11:20:53 -0800474 visit(aModule)
475 }
476 })
477}
478
Yu Liud3228ac2024-11-08 23:11:47 +0000479func (b *baseModuleContext) VisitDirectDepsProxy(visit func(ModuleProxy)) {
480 b.bp.VisitDirectDepsProxy(func(module blueprint.ModuleProxy) {
481 if aModule := b.validateAndroidModuleProxy(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil {
482 visit(*aModule)
483 }
Colin Cross648daea2024-09-12 14:35:29 -0700484 })
485}
486
Yu Liud2a95952024-10-10 00:15:26 +0000487func (b *baseModuleContext) VisitDirectDepsProxyAllowDisabled(visit func(proxy ModuleProxy)) {
Yu Liud3228ac2024-11-08 23:11:47 +0000488 b.bp.VisitDirectDepsProxy(visitProxyAdaptor(visit))
Yu Liudd9ccb42024-10-07 17:07:44 +0000489}
490
Colin Cross69452e12023-11-15 11:20:53 -0800491func (b *baseModuleContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) {
492 b.bp.VisitDirectDeps(func(module blueprint.Module) {
493 if b.bp.OtherModuleDependencyTag(module) == tag {
Yu Liud2a95952024-10-10 00:15:26 +0000494 if aModule := b.validateAndroidModule(module, tag, b.strictVisitDeps); aModule != nil {
Colin Cross69452e12023-11-15 11:20:53 -0800495 visit(aModule)
496 }
497 }
498 })
499}
500
Yu Liud2a95952024-10-10 00:15:26 +0000501func (b *baseModuleContext) VisitDirectDepsProxyWithTag(tag blueprint.DependencyTag, visit func(proxy ModuleProxy)) {
502 b.bp.VisitDirectDepsProxy(func(module blueprint.ModuleProxy) {
503 if b.bp.OtherModuleDependencyTag(module) == tag {
504 if aModule := b.validateAndroidModuleProxy(module, tag, b.strictVisitDeps); aModule != nil {
505 visit(*aModule)
506 }
507 }
508 })
509}
510
Colin Cross69452e12023-11-15 11:20:53 -0800511func (b *baseModuleContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) {
512 b.bp.VisitDirectDepsIf(
513 // pred
514 func(module blueprint.Module) bool {
Colin Cross648daea2024-09-12 14:35:29 -0700515 if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil {
Colin Cross69452e12023-11-15 11:20:53 -0800516 return pred(aModule)
517 } else {
518 return false
519 }
520 },
521 // visit
522 func(module blueprint.Module) {
523 visit(module.(Module))
524 })
525}
526
527func (b *baseModuleContext) VisitDepsDepthFirst(visit func(Module)) {
528 b.bp.VisitDepsDepthFirst(func(module blueprint.Module) {
Colin Cross648daea2024-09-12 14:35:29 -0700529 if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil {
Colin Cross69452e12023-11-15 11:20:53 -0800530 visit(aModule)
531 }
532 })
533}
534
535func (b *baseModuleContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) {
536 b.bp.VisitDepsDepthFirstIf(
537 // pred
538 func(module blueprint.Module) bool {
Colin Cross648daea2024-09-12 14:35:29 -0700539 if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil {
Colin Cross69452e12023-11-15 11:20:53 -0800540 return pred(aModule)
541 } else {
542 return false
543 }
544 },
545 // visit
546 func(module blueprint.Module) {
547 visit(module.(Module))
548 })
549}
550
Colin Cross69452e12023-11-15 11:20:53 -0800551func (b *baseModuleContext) WalkDeps(visit func(Module, Module) bool) {
552 b.walkPath = []Module{b.Module()}
553 b.tagPath = []blueprint.DependencyTag{}
554 b.bp.WalkDeps(func(child, parent blueprint.Module) bool {
555 childAndroidModule, _ := child.(Module)
556 parentAndroidModule, _ := parent.(Module)
557 if childAndroidModule != nil && parentAndroidModule != nil {
558 // record walkPath before visit
559 for b.walkPath[len(b.walkPath)-1] != parentAndroidModule {
560 b.walkPath = b.walkPath[0 : len(b.walkPath)-1]
561 b.tagPath = b.tagPath[0 : len(b.tagPath)-1]
562 }
563 b.walkPath = append(b.walkPath, childAndroidModule)
564 b.tagPath = append(b.tagPath, b.OtherModuleDependencyTag(childAndroidModule))
565 return visit(childAndroidModule, parentAndroidModule)
566 } else {
567 return false
568 }
569 })
570}
571
Yu Liud2a95952024-10-10 00:15:26 +0000572func (b *baseModuleContext) WalkDepsProxy(visit func(ModuleProxy, ModuleProxy) bool) {
Yu Liudd9ccb42024-10-07 17:07:44 +0000573 b.walkPath = []Module{ModuleProxy{blueprint.CreateModuleProxy(b.Module())}}
574 b.tagPath = []blueprint.DependencyTag{}
575 b.bp.WalkDepsProxy(func(child, parent blueprint.ModuleProxy) bool {
576 childAndroidModule := ModuleProxy{child}
577 parentAndroidModule := ModuleProxy{parent}
578 // record walkPath before visit
579 for b.walkPath[len(b.walkPath)-1] != parentAndroidModule {
580 b.walkPath = b.walkPath[0 : len(b.walkPath)-1]
581 b.tagPath = b.tagPath[0 : len(b.tagPath)-1]
582 }
583 b.walkPath = append(b.walkPath, childAndroidModule)
584 b.tagPath = append(b.tagPath, b.OtherModuleDependencyTag(childAndroidModule))
585 return visit(childAndroidModule, parentAndroidModule)
586 })
587}
588
Colin Cross69452e12023-11-15 11:20:53 -0800589func (b *baseModuleContext) GetWalkPath() []Module {
Colin Crossb614cd42024-10-11 12:52:21 -0700590 return slices.Clone(b.walkPath)
Colin Cross69452e12023-11-15 11:20:53 -0800591}
592
593func (b *baseModuleContext) GetTagPath() []blueprint.DependencyTag {
594 return b.tagPath
595}
596
597func (b *baseModuleContext) VisitAllModuleVariants(visit func(Module)) {
598 b.bp.VisitAllModuleVariants(func(module blueprint.Module) {
599 visit(module.(Module))
600 })
601}
602
Yu Liub5275322024-11-13 18:40:43 +0000603func (b *baseModuleContext) VisitAllModuleVariantProxies(visit func(ModuleProxy)) {
604 b.bp.VisitAllModuleVariantProxies(visitProxyAdaptor(visit))
605}
606
Colin Cross69452e12023-11-15 11:20:53 -0800607func (b *baseModuleContext) PrimaryModule() Module {
608 return b.bp.PrimaryModule().(Module)
609}
610
611func (b *baseModuleContext) FinalModule() Module {
612 return b.bp.FinalModule().(Module)
613}
614
Yu Liu88ea9ff2024-11-07 19:19:42 +0000615func (b *baseModuleContext) IsFinalModule(module Module) bool {
616 return b.bp.IsFinalModule(module)
617}
618
Colin Cross69452e12023-11-15 11:20:53 -0800619// IsMetaDependencyTag returns true for cross-cutting metadata dependencies.
620func IsMetaDependencyTag(tag blueprint.DependencyTag) bool {
621 if tag == licenseKindTag {
622 return true
623 } else if tag == licensesTag {
624 return true
Jihoon Kanga3a05462024-04-05 00:36:44 +0000625 } else if tag == AcDepTag {
Colin Cross69452e12023-11-15 11:20:53 -0800626 return true
627 }
628 return false
629}
630
631// A regexp for removing boilerplate from BaseDependencyTag from the string representation of
632// a dependency tag.
633var tagCleaner = regexp.MustCompile(`\QBaseDependencyTag:{}\E(, )?`)
634
635// PrettyPrintTag returns string representation of the tag, but prefers
636// custom String() method if available.
637func PrettyPrintTag(tag blueprint.DependencyTag) string {
638 // Use tag's custom String() method if available.
639 if stringer, ok := tag.(fmt.Stringer); ok {
640 return stringer.String()
641 }
642
643 // Otherwise, get a default string representation of the tag's struct.
644 tagString := fmt.Sprintf("%T: %+v", tag, tag)
645
646 // Remove the boilerplate from BaseDependencyTag as it adds no value.
647 tagString = tagCleaner.ReplaceAllString(tagString, "")
648 return tagString
649}
650
651func (b *baseModuleContext) GetPathString(skipFirst bool) string {
652 sb := strings.Builder{}
653 tagPath := b.GetTagPath()
654 walkPath := b.GetWalkPath()
655 if !skipFirst {
656 sb.WriteString(walkPath[0].String())
657 }
658 for i, m := range walkPath[1:] {
659 sb.WriteString("\n")
660 sb.WriteString(fmt.Sprintf(" via tag %s\n", PrettyPrintTag(tagPath[i])))
661 sb.WriteString(fmt.Sprintf(" -> %s", m.String()))
662 }
663 return sb.String()
664}
Cole Faustbdd8aee2024-03-14 14:33:02 -0700665
Cole Faustfdbf5d42024-04-10 15:01:23 -0700666func (m *baseModuleContext) EvaluateConfiguration(condition proptools.ConfigurableCondition, property string) proptools.ConfigurableValue {
667 return m.Module().ConfigurableEvaluator(m).EvaluateConfiguration(condition, property)
Cole Faustbdd8aee2024-03-14 14:33:02 -0700668}