blob: 4312e9bd47282d7735dec1a7ced705f6ce6411fc [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"
19 "github.com/google/blueprint"
20 "regexp"
21 "strings"
22)
23
24// BaseModuleContext is the same as blueprint.BaseModuleContext except that Config() returns
25// a Config instead of an interface{}, and some methods have been wrapped to use an android.Module
26// instead of a blueprint.Module, plus some extra methods that return Android-specific information
27// about the current module.
28type BaseModuleContext interface {
29 EarlyModuleContext
30
31 blueprintBaseModuleContext() blueprint.BaseModuleContext
32
33 // OtherModuleName returns the name of another Module. See BaseModuleContext.ModuleName for more information.
34 // It is intended for use inside the visit functions of Visit* and WalkDeps.
35 OtherModuleName(m blueprint.Module) string
36
37 // OtherModuleDir returns the directory of another Module. See BaseModuleContext.ModuleDir for more information.
38 // It is intended for use inside the visit functions of Visit* and WalkDeps.
39 OtherModuleDir(m blueprint.Module) string
40
41 // OtherModuleErrorf reports an error on another Module. See BaseModuleContext.ModuleErrorf for more information.
42 // It is intended for use inside the visit functions of Visit* and WalkDeps.
43 OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{})
44
45 // OtherModuleDependencyTag returns the dependency tag used to depend on a module, or nil if there is no dependency
46 // on the module. When called inside a Visit* method with current module being visited, and there are multiple
47 // dependencies on the module being visited, it returns the dependency tag used for the current dependency.
48 OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag
49
50 // OtherModuleExists returns true if a module with the specified name exists, as determined by the NameInterface
51 // passed to Context.SetNameInterface, or SimpleNameInterface if it was not called.
52 OtherModuleExists(name string) bool
53
54 // OtherModuleDependencyVariantExists returns true if a module with the
55 // specified name and variant exists. The variant must match the given
56 // variations. It must also match all the non-local variations of the current
57 // module. In other words, it checks for the module that AddVariationDependencies
58 // would add a dependency on with the same arguments.
59 OtherModuleDependencyVariantExists(variations []blueprint.Variation, name string) bool
60
61 // OtherModuleFarDependencyVariantExists returns true if a module with the
62 // specified name and variant exists. The variant must match the given
63 // variations, but not the non-local variations of the current module. In
64 // other words, it checks for the module that AddFarVariationDependencies
65 // would add a dependency on with the same arguments.
66 OtherModuleFarDependencyVariantExists(variations []blueprint.Variation, name string) bool
67
68 // OtherModuleReverseDependencyVariantExists returns true if a module with the
69 // specified name exists with the same variations as the current module. In
70 // other words, it checks for the module that AddReverseDependency would add a
71 // dependency on with the same argument.
72 OtherModuleReverseDependencyVariantExists(name string) bool
73
74 // OtherModuleType returns the type of another Module. See BaseModuleContext.ModuleType for more information.
75 // It is intended for use inside the visit functions of Visit* and WalkDeps.
76 OtherModuleType(m blueprint.Module) string
77
78 // OtherModuleProvider returns the value for a provider for the given module. If the value is
79 // not set it returns the zero value of the type of the provider, so the return value can always
80 // be type asserted to the type of the provider. The value returned may be a deep copy of the
81 // value originally passed to SetProvider.
82 OtherModuleProvider(m blueprint.Module, provider blueprint.ProviderKey) interface{}
83
84 // OtherModuleHasProvider returns true if the provider for the given module has been set.
85 OtherModuleHasProvider(m blueprint.Module, provider blueprint.ProviderKey) bool
86
87 // Provider returns the value for a provider for the current module. If the value is
88 // not set it returns the zero value of the type of the provider, so the return value can always
89 // be type asserted to the type of the provider. It panics if called before the appropriate
90 // mutator or GenerateBuildActions pass for the provider. The value returned may be a deep
91 // copy of the value originally passed to SetProvider.
92 Provider(provider blueprint.ProviderKey) interface{}
93
94 // HasProvider returns true if the provider for the current module has been set.
95 HasProvider(provider blueprint.ProviderKey) bool
96
97 // SetProvider sets the value for a provider for the current module. It panics if not called
98 // during the appropriate mutator or GenerateBuildActions pass for the provider, if the value
99 // is not of the appropriate type, or if the value has already been set. The value should not
100 // be modified after being passed to SetProvider.
101 SetProvider(provider blueprint.ProviderKey, value interface{})
102
103 GetDirectDepsWithTag(tag blueprint.DependencyTag) []Module
104
105 // GetDirectDepWithTag returns the Module the direct dependency with the specified name, or nil if
106 // none exists. It panics if the dependency does not have the specified tag. It skips any
107 // dependencies that are not an android.Module.
108 GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module
109
110 // GetDirectDep returns the Module and DependencyTag for the direct dependency with the specified
111 // name, or nil if none exists. If there are multiple dependencies on the same module it returns
112 // the first DependencyTag.
113 GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
114
Colin Cross69452e12023-11-15 11:20:53 -0800115 // VisitDirectDepsBlueprint calls visit for each direct dependency. If there are multiple
116 // direct dependencies on the same module visit will be called multiple times on that module
117 // and OtherModuleDependencyTag will return a different tag for each.
118 //
119 // The Module passed to the visit function should not be retained outside of the visit
120 // function, it may be invalidated by future mutators.
121 VisitDirectDepsBlueprint(visit func(blueprint.Module))
122
123 // 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 not an android.Module.
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
132 VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module))
133
134 // VisitDirectDepsIf calls pred for each direct dependency, and if pred returns true calls visit. If there are
135 // multiple direct dependencies on the same module pred and visit will be called multiple times on that module and
136 // OtherModuleDependencyTag will return a different tag for each. It skips any
137 // dependencies that are not an android.Module.
138 //
139 // The Module passed to the visit function should not be retained outside of the visit function, it may be
140 // invalidated by future mutators.
141 VisitDirectDepsIf(pred func(Module) bool, visit func(Module))
142 // Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
143 VisitDepsDepthFirst(visit func(Module))
144 // Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
145 VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
146
147 // WalkDeps calls visit for each transitive dependency, traversing the dependency tree in top down order. visit may
148 // be called multiple times for the same (child, parent) pair if there are multiple direct dependencies between the
149 // child and parent with different tags. OtherModuleDependencyTag will return the tag for the currently visited
150 // (child, parent) pair. If visit returns false WalkDeps will not continue recursing down to child. It skips
151 // any dependencies that are not an android.Module.
152 //
153 // The Modules passed to the visit function should not be retained outside of the visit function, they may be
154 // invalidated by future mutators.
155 WalkDeps(visit func(child, parent Module) bool)
156
157 // WalkDepsBlueprint calls visit for each transitive dependency, traversing the dependency
158 // tree in top down order. visit may be called multiple times for the same (child, parent)
159 // pair if there are multiple direct dependencies between the child and parent with different
160 // tags. OtherModuleDependencyTag will return the tag for the currently visited
161 // (child, parent) pair. If visit returns false WalkDeps will not continue recursing down
162 // to child.
163 //
164 // The Modules passed to the visit function should not be retained outside of the visit function, they may be
165 // invalidated by future mutators.
166 WalkDepsBlueprint(visit func(blueprint.Module, blueprint.Module) bool)
167
168 // GetWalkPath is supposed to be called in visit function passed in WalkDeps()
169 // and returns a top-down dependency path from a start module to current child module.
170 GetWalkPath() []Module
171
172 // PrimaryModule returns the first variant of the current module. Variants of a module are always visited in
173 // order by mutators and GenerateBuildActions, so the data created by the current mutator can be read from the
174 // Module returned by PrimaryModule without data races. This can be used to perform singleton actions that are
175 // only done once for all variants of a module.
176 PrimaryModule() Module
177
178 // FinalModule returns the last variant of the current module. Variants of a module are always visited in
179 // order by mutators and GenerateBuildActions, so the data created by the current mutator can be read from all
180 // variants using VisitAllModuleVariants if the current module == FinalModule(). This can be used to perform
181 // singleton actions that are only done once for all variants of a module.
182 FinalModule() Module
183
184 // VisitAllModuleVariants calls visit for each variant of the current module. Variants of a module are always
185 // visited in order by mutators and GenerateBuildActions, so the data created by the current mutator can be read
186 // from all variants if the current module == FinalModule(). Otherwise, care must be taken to not access any
187 // data modified by the current mutator.
188 VisitAllModuleVariants(visit func(Module))
189
190 // GetTagPath is supposed to be called in visit function passed in WalkDeps()
191 // and returns a top-down dependency tags path from a start module to current child module.
192 // It has one less entry than GetWalkPath() as it contains the dependency tags that
193 // exist between each adjacent pair of modules in the GetWalkPath().
194 // GetTagPath()[i] is the tag between GetWalkPath()[i] and GetWalkPath()[i+1]
195 GetTagPath() []blueprint.DependencyTag
196
197 // GetPathString is supposed to be called in visit function passed in WalkDeps()
198 // and returns a multi-line string showing the modules and dependency tags
199 // among them along the top-down dependency path from a start module to current child module.
200 // skipFirst when set to true, the output doesn't include the start module,
201 // which is already printed when this function is used along with ModuleErrorf().
202 GetPathString(skipFirst bool) string
203
204 AddMissingDependencies(missingDeps []string)
205
206 // getMissingDependencies returns the list of missing dependencies.
207 // Calling this function prevents adding new dependencies.
208 getMissingDependencies() []string
209
Colin Cross69452e12023-11-15 11:20:53 -0800210 Target() Target
211 TargetPrimary() bool
212
213 // The additional arch specific targets (e.g. 32/64 bit) that this module variant is
214 // responsible for creating.
215 MultiTargets() []Target
216 Arch() Arch
217 Os() OsType
218 Host() bool
219 Device() bool
220 Darwin() bool
221 Windows() bool
222 PrimaryArch() bool
223}
224
225type baseModuleContext struct {
226 bp blueprint.BaseModuleContext
227 earlyModuleContext
228 os OsType
229 target Target
230 multiTargets []Target
231 targetPrimary bool
232
233 walkPath []Module
234 tagPath []blueprint.DependencyTag
235
236 strictVisitDeps bool // If true, enforce that all dependencies are enabled
237
Colin Cross69452e12023-11-15 11:20:53 -0800238}
239
Colin Cross69452e12023-11-15 11:20:53 -0800240func (b *baseModuleContext) OtherModuleName(m blueprint.Module) string {
241 return b.bp.OtherModuleName(m)
242}
243func (b *baseModuleContext) OtherModuleDir(m blueprint.Module) string { return b.bp.OtherModuleDir(m) }
244func (b *baseModuleContext) OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{}) {
245 b.bp.OtherModuleErrorf(m, fmt, args...)
246}
247func (b *baseModuleContext) OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag {
248 return b.bp.OtherModuleDependencyTag(m)
249}
250func (b *baseModuleContext) OtherModuleExists(name string) bool { return b.bp.OtherModuleExists(name) }
251func (b *baseModuleContext) OtherModuleDependencyVariantExists(variations []blueprint.Variation, name string) bool {
252 return b.bp.OtherModuleDependencyVariantExists(variations, name)
253}
254func (b *baseModuleContext) OtherModuleFarDependencyVariantExists(variations []blueprint.Variation, name string) bool {
255 return b.bp.OtherModuleFarDependencyVariantExists(variations, name)
256}
257func (b *baseModuleContext) OtherModuleReverseDependencyVariantExists(name string) bool {
258 return b.bp.OtherModuleReverseDependencyVariantExists(name)
259}
260func (b *baseModuleContext) OtherModuleType(m blueprint.Module) string {
261 return b.bp.OtherModuleType(m)
262}
263func (b *baseModuleContext) OtherModuleProvider(m blueprint.Module, provider blueprint.ProviderKey) interface{} {
264 return b.bp.OtherModuleProvider(m, provider)
265}
266func (b *baseModuleContext) OtherModuleHasProvider(m blueprint.Module, provider blueprint.ProviderKey) bool {
267 return b.bp.OtherModuleHasProvider(m, provider)
268}
269func (b *baseModuleContext) Provider(provider blueprint.ProviderKey) interface{} {
270 return b.bp.Provider(provider)
271}
272func (b *baseModuleContext) HasProvider(provider blueprint.ProviderKey) bool {
273 return b.bp.HasProvider(provider)
274}
275func (b *baseModuleContext) SetProvider(provider blueprint.ProviderKey, value interface{}) {
276 b.bp.SetProvider(provider, value)
277}
278
279func (b *baseModuleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module {
280 return b.bp.GetDirectDepWithTag(name, tag)
281}
282
283func (b *baseModuleContext) blueprintBaseModuleContext() blueprint.BaseModuleContext {
284 return b.bp
285}
286
Colin Cross69452e12023-11-15 11:20:53 -0800287func (b *baseModuleContext) AddMissingDependencies(deps []string) {
288 if deps != nil {
289 missingDeps := &b.Module().base().commonProperties.MissingDeps
290 *missingDeps = append(*missingDeps, deps...)
291 *missingDeps = FirstUniqueStrings(*missingDeps)
292 }
293}
294
295func (b *baseModuleContext) checkedMissingDeps() bool {
296 return b.Module().base().commonProperties.CheckedMissingDeps
297}
298
299func (b *baseModuleContext) getMissingDependencies() []string {
300 checked := &b.Module().base().commonProperties.CheckedMissingDeps
301 *checked = true
302 var missingDeps []string
303 missingDeps = append(missingDeps, b.Module().base().commonProperties.MissingDeps...)
304 missingDeps = append(missingDeps, b.bp.EarlyGetMissingDependencies()...)
305 missingDeps = FirstUniqueStrings(missingDeps)
306 return missingDeps
307}
308
309type AllowDisabledModuleDependency interface {
310 blueprint.DependencyTag
311 AllowDisabledModuleDependency(target Module) bool
312}
313
314func (b *baseModuleContext) validateAndroidModule(module blueprint.Module, tag blueprint.DependencyTag, strict bool) Module {
315 aModule, _ := module.(Module)
316
317 if !strict {
318 return aModule
319 }
320
321 if aModule == nil {
322 b.ModuleErrorf("module %q (%#v) not an android module", b.OtherModuleName(module), tag)
323 return nil
324 }
325
326 if !aModule.Enabled() {
327 if t, ok := tag.(AllowDisabledModuleDependency); !ok || !t.AllowDisabledModuleDependency(aModule) {
328 if b.Config().AllowMissingDependencies() {
329 b.AddMissingDependencies([]string{b.OtherModuleName(aModule)})
330 } else {
331 b.ModuleErrorf("depends on disabled module %q", b.OtherModuleName(aModule))
332 }
333 }
334 return nil
335 }
336 return aModule
337}
338
339type dep struct {
340 mod blueprint.Module
341 tag blueprint.DependencyTag
342}
343
344func (b *baseModuleContext) getDirectDepsInternal(name string, tag blueprint.DependencyTag) []dep {
345 var deps []dep
346 b.VisitDirectDepsBlueprint(func(module blueprint.Module) {
347 if aModule, _ := module.(Module); aModule != nil {
348 if aModule.base().BaseModuleName() == name {
349 returnedTag := b.bp.OtherModuleDependencyTag(aModule)
350 if tag == nil || returnedTag == tag {
351 deps = append(deps, dep{aModule, returnedTag})
352 }
353 }
354 } else if b.bp.OtherModuleName(module) == name {
355 returnedTag := b.bp.OtherModuleDependencyTag(module)
356 if tag == nil || returnedTag == tag {
357 deps = append(deps, dep{module, returnedTag})
358 }
359 }
360 })
361 return deps
362}
363
364func (b *baseModuleContext) getDirectDepInternal(name string, tag blueprint.DependencyTag) (blueprint.Module, blueprint.DependencyTag) {
365 deps := b.getDirectDepsInternal(name, tag)
366 if len(deps) == 1 {
367 return deps[0].mod, deps[0].tag
368 } else if len(deps) >= 2 {
369 panic(fmt.Errorf("Multiple dependencies having same BaseModuleName() %q found from %q",
370 name, b.ModuleName()))
371 } else {
372 return nil, nil
373 }
374}
375
376func (b *baseModuleContext) getDirectDepFirstTag(name string) (blueprint.Module, blueprint.DependencyTag) {
377 foundDeps := b.getDirectDepsInternal(name, nil)
378 deps := map[blueprint.Module]bool{}
379 for _, dep := range foundDeps {
380 deps[dep.mod] = true
381 }
382 if len(deps) == 1 {
383 return foundDeps[0].mod, foundDeps[0].tag
384 } else if len(deps) >= 2 {
385 // this could happen if two dependencies have the same name in different namespaces
386 // TODO(b/186554727): this should not occur if namespaces are handled within
387 // getDirectDepsInternal.
388 panic(fmt.Errorf("Multiple dependencies having same BaseModuleName() %q found from %q",
389 name, b.ModuleName()))
390 } else {
391 return nil, nil
392 }
393}
394
395func (b *baseModuleContext) GetDirectDepsWithTag(tag blueprint.DependencyTag) []Module {
396 var deps []Module
397 b.VisitDirectDepsBlueprint(func(module blueprint.Module) {
398 if aModule, _ := module.(Module); aModule != nil {
399 if b.bp.OtherModuleDependencyTag(aModule) == tag {
400 deps = append(deps, aModule)
401 }
402 }
403 })
404 return deps
405}
406
407// GetDirectDep returns the Module and DependencyTag for the direct dependency with the specified
408// name, or nil if none exists. If there are multiple dependencies on the same module it returns the
409// first DependencyTag.
410func (b *baseModuleContext) GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag) {
411 return b.getDirectDepFirstTag(name)
412}
413
Colin Cross69452e12023-11-15 11:20:53 -0800414func (b *baseModuleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module)) {
415 b.bp.VisitDirectDeps(visit)
416}
417
418func (b *baseModuleContext) VisitDirectDeps(visit func(Module)) {
419 b.bp.VisitDirectDeps(func(module blueprint.Module) {
420 if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil {
421 visit(aModule)
422 }
423 })
424}
425
426func (b *baseModuleContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) {
427 b.bp.VisitDirectDeps(func(module blueprint.Module) {
428 if b.bp.OtherModuleDependencyTag(module) == tag {
429 if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil {
430 visit(aModule)
431 }
432 }
433 })
434}
435
436func (b *baseModuleContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) {
437 b.bp.VisitDirectDepsIf(
438 // pred
439 func(module blueprint.Module) bool {
440 if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil {
441 return pred(aModule)
442 } else {
443 return false
444 }
445 },
446 // visit
447 func(module blueprint.Module) {
448 visit(module.(Module))
449 })
450}
451
452func (b *baseModuleContext) VisitDepsDepthFirst(visit func(Module)) {
453 b.bp.VisitDepsDepthFirst(func(module blueprint.Module) {
454 if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil {
455 visit(aModule)
456 }
457 })
458}
459
460func (b *baseModuleContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) {
461 b.bp.VisitDepsDepthFirstIf(
462 // pred
463 func(module blueprint.Module) bool {
464 if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil {
465 return pred(aModule)
466 } else {
467 return false
468 }
469 },
470 // visit
471 func(module blueprint.Module) {
472 visit(module.(Module))
473 })
474}
475
476func (b *baseModuleContext) WalkDepsBlueprint(visit func(blueprint.Module, blueprint.Module) bool) {
477 b.bp.WalkDeps(visit)
478}
479
480func (b *baseModuleContext) WalkDeps(visit func(Module, Module) bool) {
481 b.walkPath = []Module{b.Module()}
482 b.tagPath = []blueprint.DependencyTag{}
483 b.bp.WalkDeps(func(child, parent blueprint.Module) bool {
484 childAndroidModule, _ := child.(Module)
485 parentAndroidModule, _ := parent.(Module)
486 if childAndroidModule != nil && parentAndroidModule != nil {
487 // record walkPath before visit
488 for b.walkPath[len(b.walkPath)-1] != parentAndroidModule {
489 b.walkPath = b.walkPath[0 : len(b.walkPath)-1]
490 b.tagPath = b.tagPath[0 : len(b.tagPath)-1]
491 }
492 b.walkPath = append(b.walkPath, childAndroidModule)
493 b.tagPath = append(b.tagPath, b.OtherModuleDependencyTag(childAndroidModule))
494 return visit(childAndroidModule, parentAndroidModule)
495 } else {
496 return false
497 }
498 })
499}
500
501func (b *baseModuleContext) GetWalkPath() []Module {
502 return b.walkPath
503}
504
505func (b *baseModuleContext) GetTagPath() []blueprint.DependencyTag {
506 return b.tagPath
507}
508
509func (b *baseModuleContext) VisitAllModuleVariants(visit func(Module)) {
510 b.bp.VisitAllModuleVariants(func(module blueprint.Module) {
511 visit(module.(Module))
512 })
513}
514
515func (b *baseModuleContext) PrimaryModule() Module {
516 return b.bp.PrimaryModule().(Module)
517}
518
519func (b *baseModuleContext) FinalModule() Module {
520 return b.bp.FinalModule().(Module)
521}
522
523// IsMetaDependencyTag returns true for cross-cutting metadata dependencies.
524func IsMetaDependencyTag(tag blueprint.DependencyTag) bool {
525 if tag == licenseKindTag {
526 return true
527 } else if tag == licensesTag {
528 return true
529 } else if tag == acDepTag {
530 return true
531 }
532 return false
533}
534
535// A regexp for removing boilerplate from BaseDependencyTag from the string representation of
536// a dependency tag.
537var tagCleaner = regexp.MustCompile(`\QBaseDependencyTag:{}\E(, )?`)
538
539// PrettyPrintTag returns string representation of the tag, but prefers
540// custom String() method if available.
541func PrettyPrintTag(tag blueprint.DependencyTag) string {
542 // Use tag's custom String() method if available.
543 if stringer, ok := tag.(fmt.Stringer); ok {
544 return stringer.String()
545 }
546
547 // Otherwise, get a default string representation of the tag's struct.
548 tagString := fmt.Sprintf("%T: %+v", tag, tag)
549
550 // Remove the boilerplate from BaseDependencyTag as it adds no value.
551 tagString = tagCleaner.ReplaceAllString(tagString, "")
552 return tagString
553}
554
555func (b *baseModuleContext) GetPathString(skipFirst bool) string {
556 sb := strings.Builder{}
557 tagPath := b.GetTagPath()
558 walkPath := b.GetWalkPath()
559 if !skipFirst {
560 sb.WriteString(walkPath[0].String())
561 }
562 for i, m := range walkPath[1:] {
563 sb.WriteString("\n")
564 sb.WriteString(fmt.Sprintf(" via tag %s\n", PrettyPrintTag(tagPath[i])))
565 sb.WriteString(fmt.Sprintf(" -> %s", m.String()))
566 }
567 return sb.String()
568}
569
570func (b *baseModuleContext) Target() Target {
571 return b.target
572}
573
574func (b *baseModuleContext) TargetPrimary() bool {
575 return b.targetPrimary
576}
577
578func (b *baseModuleContext) MultiTargets() []Target {
579 return b.multiTargets
580}
581
582func (b *baseModuleContext) Arch() Arch {
583 return b.target.Arch
584}
585
586func (b *baseModuleContext) Os() OsType {
587 return b.os
588}
589
590func (b *baseModuleContext) Host() bool {
591 return b.os.Class == Host
592}
593
594func (b *baseModuleContext) Device() bool {
595 return b.os.Class == Device
596}
597
598func (b *baseModuleContext) Darwin() bool {
599 return b.os == Darwin
600}
601
602func (b *baseModuleContext) Windows() bool {
603 return b.os == Windows
604}
605
606func (b *baseModuleContext) PrimaryArch() bool {
607 if len(b.config.Targets[b.target.Os]) <= 1 {
608 return true
609 }
610 return b.target.Arch.ArchType == b.config.Targets[b.target.Os][0].Arch.ArchType
611}