blob: c2364a9c2f8b672003e13860f010016ae220f920 [file] [log] [blame]
Colin Cross8e0c5112015-01-23 14:15:10 -08001// Copyright 2014 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
Jamie Gennis1bc967e2014-05-27 16:34:41 -070015package blueprint
16
17import (
18 "fmt"
19 "path/filepath"
Jamie Gennis6a40c192014-07-02 16:40:31 -070020 "text/scanner"
Jamie Gennis1bc967e2014-05-27 16:34:41 -070021)
22
Jamie Gennisb9e87f62014-09-24 20:28:11 -070023// A Module handles generating all of the Ninja build actions needed to build a
Colin Crossc9028482014-12-18 16:28:54 -080024// single module based on properties defined in a Blueprints file. Module
25// objects are initially created during the parse phase of a Context using one
26// of the registered module types (and the associated ModuleFactory function).
27// The Module's properties struct is automatically filled in with the property
28// values specified in the Blueprints file (see Context.RegisterModuleType for more
Jamie Gennisb9e87f62014-09-24 20:28:11 -070029// information on this).
30//
Colin Crossc9028482014-12-18 16:28:54 -080031// A Module can be split into multiple Modules by a Mutator. All existing
32// properties set on the module will be duplicated to the new Module, and then
33// modified as necessary by the Mutator.
34//
Jamie Gennisb9e87f62014-09-24 20:28:11 -070035// The Module implementation can access the build configuration as well as any
36// modules on which on which it depends (as defined by the "deps" property
Colin Cross763b6f12015-10-29 15:32:56 -070037// specified in the Blueprints file, dynamically added by implementing the
38// (deprecated) DynamicDependerModule interface, or dynamically added by a
39// BottomUpMutator) using the ModuleContext passed to GenerateBuildActions.
40// This ModuleContext is also used to create Ninja build actions and to report
41// errors to the user.
Jamie Gennisb9e87f62014-09-24 20:28:11 -070042//
43// In addition to implementing the GenerateBuildActions method, a Module should
44// implement methods that provide dependant modules and singletons information
45// they need to generate their build actions. These methods will only be called
46// after GenerateBuildActions is called because the Context calls
47// GenerateBuildActions in dependency-order (and singletons are invoked after
48// all the Modules). The set of methods a Module supports will determine how
49// dependant Modules interact with it.
50//
51// For example, consider a Module that is responsible for generating a library
52// that other modules can link against. The library Module might implement the
53// following interface:
54//
55// type LibraryProducer interface {
56// LibraryFileName() string
57// }
58//
59// func IsLibraryProducer(module blueprint.Module) {
60// _, ok := module.(LibraryProducer)
61// return ok
62// }
63//
64// A binary-producing Module that depends on the library Module could then do:
65//
66// func (m *myBinaryModule) GenerateBuildActions(ctx blueprint.ModuleContext) {
67// ...
68// var libraryFiles []string
69// ctx.VisitDepsDepthFirstIf(IsLibraryProducer,
70// func(module blueprint.Module) {
71// libProducer := module.(LibraryProducer)
72// libraryFiles = append(libraryFiles, libProducer.LibraryFileName())
73// })
74// ...
75// }
76//
77// to build the list of library file names that should be included in its link
78// command.
Colin Cross691a60d2015-01-07 18:08:56 -080079//
80// GenerateBuildActions may be called from multiple threads. It is guaranteed to
81// be called after it has finished being called on all dependencies and on all
82// variants of that appear earlier in the ModuleContext.VisitAllModuleVariants list.
83// Any accesses to global variables or to Module objects that are not dependencies
84// or variants of the current Module must be synchronized by the implementation of
85// GenerateBuildActions.
Jamie Gennis1bc967e2014-05-27 16:34:41 -070086type Module interface {
Jamie Gennisb9e87f62014-09-24 20:28:11 -070087 // GenerateBuildActions is called by the Context that created the Module
88 // during its generate phase. This call should generate all Ninja build
89 // actions (rules, pools, and build statements) needed to build the module.
Jamie Gennis1bc967e2014-05-27 16:34:41 -070090 GenerateBuildActions(ModuleContext)
91}
92
Jamie Gennisb9e87f62014-09-24 20:28:11 -070093// A DynamicDependerModule is a Module that may add dependencies that do not
94// appear in its "deps" property. Any Module that implements this interface
95// will have its DynamicDependencies method called by the Context that created
96// it during generate phase.
Colin Cross763b6f12015-10-29 15:32:56 -070097//
98// Deprecated, use a BottomUpMutator instead
Jamie Gennisb9e87f62014-09-24 20:28:11 -070099type DynamicDependerModule interface {
100 Module
101
102 // DynamicDependencies is called by the Context that created the
103 // DynamicDependerModule during its generate phase. This call should return
104 // the list of module names that the DynamicDependerModule depends on
105 // dynamically. Module names that already appear in the "deps" property may
106 // but do not need to be included in the returned list.
107 DynamicDependencies(DynamicDependerModuleContext) []string
108}
109
Colin Crossbe1a9a12014-12-18 11:05:45 -0800110type BaseModuleContext interface {
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700111 ModuleName() string
112 ModuleDir() string
Jamie Gennis6eb4d242014-06-11 18:31:16 -0700113 Config() interface{}
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700114
David Allison701fbad2014-10-29 14:51:13 -0700115 ContainsProperty(name string) bool
Jamie Gennis6a40c192014-07-02 16:40:31 -0700116 Errorf(pos scanner.Position, fmt string, args ...interface{})
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700117 ModuleErrorf(fmt string, args ...interface{})
118 PropertyErrorf(property, fmt string, args ...interface{})
Jamie Gennis6a40c192014-07-02 16:40:31 -0700119 Failed() bool
Colin Cross763b6f12015-10-29 15:32:56 -0700120
121 moduleInfo() *moduleInfo
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700122}
123
Colin Cross763b6f12015-10-29 15:32:56 -0700124type DynamicDependerModuleContext BottomUpMutatorContext
Colin Crossbe1a9a12014-12-18 11:05:45 -0800125
Colin Cross1455a0f2014-12-17 13:23:56 -0800126type ModuleContext interface {
Colin Crossbe1a9a12014-12-18 11:05:45 -0800127 BaseModuleContext
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700128
129 OtherModuleName(m Module) string
130 OtherModuleErrorf(m Module, fmt string, args ...interface{})
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700131
Colin Crossc7ffa302015-02-10 11:24:52 -0800132 VisitDirectDeps(visit func(Module))
133 VisitDirectDepsIf(pred func(Module) bool, visit func(Module))
Colin Crossb2e7b5d2014-11-11 14:18:53 -0800134 VisitDepsDepthFirst(visit func(Module))
135 VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
Yuchen Wu222e2452015-10-06 14:03:27 -0700136 WalkDeps(visit func(Module, Module) bool)
Colin Crossb2e7b5d2014-11-11 14:18:53 -0800137
Colin Crossc9028482014-12-18 16:28:54 -0800138 ModuleSubDir() string
139
Jamie Gennis2fb20952014-10-03 02:49:58 -0700140 Variable(pctx *PackageContext, name, value string)
141 Rule(pctx *PackageContext, name string, params RuleParams, argNames ...string) Rule
142 Build(pctx *PackageContext, params BuildParams)
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700143
Mathias Agopian5b8477d2014-06-25 17:21:54 -0700144 AddNinjaFileDeps(deps ...string)
Colin Crossc9028482014-12-18 16:28:54 -0800145
146 PrimaryModule() Module
Colin Cross80ad04d2015-01-06 16:19:59 -0800147 FinalModule() Module
148 VisitAllModuleVariants(visit func(Module))
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700149}
150
Colin Crossbe1a9a12014-12-18 11:05:45 -0800151var _ BaseModuleContext = (*baseModuleContext)(nil)
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700152
Colin Crossbe1a9a12014-12-18 11:05:45 -0800153type baseModuleContext struct {
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700154 context *Context
155 config interface{}
Colin Crossed342d92015-03-11 00:57:25 -0700156 module *moduleInfo
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700157 errs []error
158}
159
Colin Cross763b6f12015-10-29 15:32:56 -0700160func (d *baseModuleContext) moduleInfo() *moduleInfo {
161 return d.module
162}
163
Colin Crossbe1a9a12014-12-18 11:05:45 -0800164func (d *baseModuleContext) ModuleName() string {
Colin Crossed342d92015-03-11 00:57:25 -0700165 return d.module.properties.Name
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700166}
167
Colin Crossbe1a9a12014-12-18 11:05:45 -0800168func (d *baseModuleContext) ContainsProperty(name string) bool {
Colin Crossed342d92015-03-11 00:57:25 -0700169 _, ok := d.module.propertyPos[name]
David Allison701fbad2014-10-29 14:51:13 -0700170 return ok
171}
172
Colin Crossbe1a9a12014-12-18 11:05:45 -0800173func (d *baseModuleContext) ModuleDir() string {
Colin Crossed342d92015-03-11 00:57:25 -0700174 return filepath.Dir(d.module.relBlueprintsFile)
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700175}
176
Colin Crossbe1a9a12014-12-18 11:05:45 -0800177func (d *baseModuleContext) Config() interface{} {
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700178 return d.config
179}
180
Colin Crossbe1a9a12014-12-18 11:05:45 -0800181func (d *baseModuleContext) Errorf(pos scanner.Position,
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700182 format string, args ...interface{}) {
183
184 d.errs = append(d.errs, &Error{
185 Err: fmt.Errorf(format, args...),
186 Pos: pos,
187 })
188}
189
Colin Crossbe1a9a12014-12-18 11:05:45 -0800190func (d *baseModuleContext) ModuleErrorf(format string,
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700191 args ...interface{}) {
192
193 d.errs = append(d.errs, &Error{
194 Err: fmt.Errorf(format, args...),
Colin Crossed342d92015-03-11 00:57:25 -0700195 Pos: d.module.pos,
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700196 })
197}
198
Colin Crossbe1a9a12014-12-18 11:05:45 -0800199func (d *baseModuleContext) PropertyErrorf(property, format string,
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700200 args ...interface{}) {
201
Colin Crossa2ca92c2015-11-02 16:10:23 -0800202 pos := d.module.propertyPos[property]
203
204 if !pos.IsValid() {
205 pos = d.module.pos
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700206 }
207
Colin Crossa2ca92c2015-11-02 16:10:23 -0800208 format = property + ": " + format
209
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700210 d.errs = append(d.errs, &Error{
211 Err: fmt.Errorf(format, args...),
212 Pos: pos,
213 })
214}
215
Colin Crossbe1a9a12014-12-18 11:05:45 -0800216func (d *baseModuleContext) Failed() bool {
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700217 return len(d.errs) > 0
218}
219
Colin Cross1455a0f2014-12-17 13:23:56 -0800220var _ ModuleContext = (*moduleContext)(nil)
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700221
Colin Cross1455a0f2014-12-17 13:23:56 -0800222type moduleContext struct {
Colin Crossbe1a9a12014-12-18 11:05:45 -0800223 baseModuleContext
Colin Cross1455a0f2014-12-17 13:23:56 -0800224 scope *localScope
225 ninjaFileDeps []string
226 actionDefs localBuildActions
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700227}
228
Colin Crossed342d92015-03-11 00:57:25 -0700229func (m *moduleContext) OtherModuleName(logicModule Module) string {
230 module := m.context.moduleInfo[logicModule]
231 return module.properties.Name
Jamie Gennisd4c53d82014-06-22 17:02:55 -0700232}
233
Colin Crossed342d92015-03-11 00:57:25 -0700234func (m *moduleContext) OtherModuleErrorf(logicModule Module, format string,
Jamie Gennisd4c53d82014-06-22 17:02:55 -0700235 args ...interface{}) {
236
Colin Crossed342d92015-03-11 00:57:25 -0700237 module := m.context.moduleInfo[logicModule]
Jamie Gennisd4c53d82014-06-22 17:02:55 -0700238 m.errs = append(m.errs, &Error{
239 Err: fmt.Errorf(format, args...),
Colin Crossed342d92015-03-11 00:57:25 -0700240 Pos: module.pos,
Jamie Gennisd4c53d82014-06-22 17:02:55 -0700241 })
242}
243
Colin Crossc7ffa302015-02-10 11:24:52 -0800244func (m *moduleContext) VisitDirectDeps(visit func(Module)) {
245 m.context.visitDirectDeps(m.module, visit)
246}
247
248func (m *moduleContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) {
249 m.context.visitDirectDepsIf(m.module, pred, visit)
250}
251
Colin Cross1455a0f2014-12-17 13:23:56 -0800252func (m *moduleContext) VisitDepsDepthFirst(visit func(Module)) {
Colin Crossb2e7b5d2014-11-11 14:18:53 -0800253 m.context.visitDepsDepthFirst(m.module, visit)
254}
255
Colin Cross1455a0f2014-12-17 13:23:56 -0800256func (m *moduleContext) VisitDepsDepthFirstIf(pred func(Module) bool,
Colin Crossb2e7b5d2014-11-11 14:18:53 -0800257 visit func(Module)) {
258
259 m.context.visitDepsDepthFirstIf(m.module, pred, visit)
260}
261
Yuchen Wu222e2452015-10-06 14:03:27 -0700262func (m *moduleContext) WalkDeps(visit func(Module, Module) bool) {
263 m.context.walkDeps(m.module, visit)
264}
265
Colin Crossc9028482014-12-18 16:28:54 -0800266func (m *moduleContext) ModuleSubDir() string {
Colin Crosse7daa222015-03-11 14:35:41 -0700267 return m.module.variantName
Colin Crossc9028482014-12-18 16:28:54 -0800268}
269
Jamie Gennis2fb20952014-10-03 02:49:58 -0700270func (m *moduleContext) Variable(pctx *PackageContext, name, value string) {
271 m.scope.ReparentTo(pctx)
Jamie Gennis0ed63ef2014-06-30 18:07:17 -0700272
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700273 v, err := m.scope.AddLocalVariable(name, value)
274 if err != nil {
275 panic(err)
276 }
277
278 m.actionDefs.variables = append(m.actionDefs.variables, v)
279}
280
Jamie Gennis2fb20952014-10-03 02:49:58 -0700281func (m *moduleContext) Rule(pctx *PackageContext, name string,
282 params RuleParams, argNames ...string) Rule {
Jamie Genniscbc6f862014-06-05 20:00:22 -0700283
Jamie Gennis2fb20952014-10-03 02:49:58 -0700284 m.scope.ReparentTo(pctx)
Jamie Gennis0ed63ef2014-06-30 18:07:17 -0700285
Jamie Genniscbc6f862014-06-05 20:00:22 -0700286 r, err := m.scope.AddLocalRule(name, &params, argNames...)
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700287 if err != nil {
288 panic(err)
289 }
290
291 m.actionDefs.rules = append(m.actionDefs.rules, r)
292
293 return r
294}
295
Jamie Gennis2fb20952014-10-03 02:49:58 -0700296func (m *moduleContext) Build(pctx *PackageContext, params BuildParams) {
297 m.scope.ReparentTo(pctx)
Jamie Gennis0ed63ef2014-06-30 18:07:17 -0700298
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700299 def, err := parseBuildParams(m.scope, &params)
300 if err != nil {
301 panic(err)
302 }
303
304 m.actionDefs.buildDefs = append(m.actionDefs.buildDefs, def)
305}
306
Mathias Agopian5b8477d2014-06-25 17:21:54 -0700307func (m *moduleContext) AddNinjaFileDeps(deps ...string) {
308 m.ninjaFileDeps = append(m.ninjaFileDeps, deps...)
309}
Colin Crossc9028482014-12-18 16:28:54 -0800310
311func (m *moduleContext) PrimaryModule() Module {
Colin Cross80ad04d2015-01-06 16:19:59 -0800312 return m.module.group.modules[0].logicModule
313}
314
315func (m *moduleContext) FinalModule() Module {
316 return m.module.group.modules[len(m.module.group.modules)-1].logicModule
317}
318
319func (m *moduleContext) VisitAllModuleVariants(visit func(Module)) {
320 for _, module := range m.module.group.modules {
321 visit(module.logicModule)
322 }
Colin Crossc9028482014-12-18 16:28:54 -0800323}
324
325//
326// MutatorContext
327//
328
329type mutatorContext struct {
330 baseModuleContext
Dan Willemsenfdeb7242015-07-24 16:53:27 -0700331 name string
Colin Crossc9028482014-12-18 16:28:54 -0800332}
333
334type baseMutatorContext interface {
335 BaseModuleContext
336
337 Module() Module
338}
339
Colin Cross65569e42015-03-10 20:08:19 -0700340type EarlyMutatorContext interface {
341 baseMutatorContext
342
Colin Crossf5e34b92015-03-13 16:02:36 -0700343 CreateVariations(...string) []Module
344 CreateLocalVariations(...string) []Module
Colin Cross65569e42015-03-10 20:08:19 -0700345}
346
Colin Crossc9028482014-12-18 16:28:54 -0800347type TopDownMutatorContext interface {
348 baseMutatorContext
349
350 VisitDirectDeps(visit func(Module))
351 VisitDirectDepsIf(pred func(Module) bool, visit func(Module))
352 VisitDepsDepthFirst(visit func(Module))
353 VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
Yuchen Wu222e2452015-10-06 14:03:27 -0700354 WalkDeps(visit func(Module, Module) bool)
Colin Crossc9028482014-12-18 16:28:54 -0800355}
356
357type BottomUpMutatorContext interface {
358 baseMutatorContext
359
Colin Cross763b6f12015-10-29 15:32:56 -0700360 AddDependency(module Module, name ...string)
Dan Willemsenfdeb7242015-07-24 16:53:27 -0700361 AddReverseDependency(module Module, name string)
Colin Crossf5e34b92015-03-13 16:02:36 -0700362 CreateVariations(...string) []Module
Jamie Gennis6a5825e2015-05-19 11:26:11 -0700363 CreateLocalVariations(...string) []Module
Colin Crossf5e34b92015-03-13 16:02:36 -0700364 SetDependencyVariation(string)
Colin Cross763b6f12015-10-29 15:32:56 -0700365 AddVariationDependencies([]Variation, ...string)
366 AddFarVariationDependencies([]Variation, ...string)
Colin Crossc9028482014-12-18 16:28:54 -0800367}
368
369// A Mutator function is called for each Module, and can use
Colin Crossf5e34b92015-03-13 16:02:36 -0700370// MutatorContext.CreateVariations to split a Module into multiple Modules,
Colin Crossc9028482014-12-18 16:28:54 -0800371// modifying properties on the new modules to differentiate them. It is called
372// after parsing all Blueprint files, but before generating any build rules,
373// and is always called on dependencies before being called on the depending module.
374//
375// The Mutator function should only modify members of properties structs, and not
376// members of the module struct itself, to ensure the modified values are copied
377// if a second Mutator chooses to split the module a second time.
378type TopDownMutator func(mctx TopDownMutatorContext)
379type BottomUpMutator func(mctx BottomUpMutatorContext)
Colin Cross65569e42015-03-10 20:08:19 -0700380type EarlyMutator func(mctx EarlyMutatorContext)
Colin Crossc9028482014-12-18 16:28:54 -0800381
Colin Crossf5e34b92015-03-13 16:02:36 -0700382// Split a module into mulitple variants, one for each name in the variationNames
383// parameter. It returns a list of new modules in the same order as the variationNames
Colin Crossc9028482014-12-18 16:28:54 -0800384// list.
385//
386// If any of the dependencies of the module being operated on were already split
Colin Crossf5e34b92015-03-13 16:02:36 -0700387// by calling CreateVariations with the same name, the dependency will automatically
Colin Crossc9028482014-12-18 16:28:54 -0800388// be updated to point the matching variant.
389//
390// If a module is split, and then a module depending on the first module is not split
391// when the Mutator is later called on it, the dependency of the depending module will
392// automatically be updated to point to the first variant.
Colin Crossf5e34b92015-03-13 16:02:36 -0700393func (mctx *mutatorContext) CreateVariations(variationNames ...string) []Module {
394 return mctx.createVariations(variationNames, false)
Colin Cross65569e42015-03-10 20:08:19 -0700395}
396
397// Split a module into mulitple variants, one for each name in the variantNames
398// parameter. It returns a list of new modules in the same order as the variantNames
399// list.
400//
Colin Crossf5e34b92015-03-13 16:02:36 -0700401// Local variations do not affect automatic dependency resolution - dependencies added
Colin Cross65569e42015-03-10 20:08:19 -0700402// to the split module via deps or DynamicDependerModule must exactly match a variant
Colin Crossf5e34b92015-03-13 16:02:36 -0700403// that contains all the non-local variations.
404func (mctx *mutatorContext) CreateLocalVariations(variationNames ...string) []Module {
405 return mctx.createVariations(variationNames, true)
Colin Cross65569e42015-03-10 20:08:19 -0700406}
407
Colin Crossf5e34b92015-03-13 16:02:36 -0700408func (mctx *mutatorContext) createVariations(variationNames []string, local bool) []Module {
Colin Crossc9028482014-12-18 16:28:54 -0800409 ret := []Module{}
Colin Crossf5e34b92015-03-13 16:02:36 -0700410 modules, errs := mctx.context.createVariations(mctx.module, mctx.name, variationNames)
Colin Cross174ae052015-03-03 17:37:03 -0800411 if len(errs) > 0 {
412 mctx.errs = append(mctx.errs, errs...)
413 }
Colin Crossc9028482014-12-18 16:28:54 -0800414
Colin Cross65569e42015-03-10 20:08:19 -0700415 for i, module := range modules {
Colin Crossc9028482014-12-18 16:28:54 -0800416 ret = append(ret, module.logicModule)
Colin Cross65569e42015-03-10 20:08:19 -0700417 if !local {
Colin Crossf5e34b92015-03-13 16:02:36 -0700418 module.dependencyVariant[mctx.name] = variationNames[i]
Colin Cross65569e42015-03-10 20:08:19 -0700419 }
Colin Crossc9028482014-12-18 16:28:54 -0800420 }
421
Colin Crossf5e34b92015-03-13 16:02:36 -0700422 if len(ret) != len(variationNames) {
Colin Crossc9028482014-12-18 16:28:54 -0800423 panic("oops!")
424 }
425
426 return ret
427}
428
Colin Crossf5e34b92015-03-13 16:02:36 -0700429// Set all dangling dependencies on the current module to point to the variation
Colin Crossc9028482014-12-18 16:28:54 -0800430// with given name.
Colin Crossf5e34b92015-03-13 16:02:36 -0700431func (mctx *mutatorContext) SetDependencyVariation(variationName string) {
432 mctx.context.convertDepsToVariation(mctx.module, mctx.name, variationName)
Colin Crossc9028482014-12-18 16:28:54 -0800433}
434
435func (mctx *mutatorContext) Module() Module {
436 return mctx.module.logicModule
437}
438
Dan Willemsenfdeb7242015-07-24 16:53:27 -0700439// Add a dependency to the given module.
Colin Crossc9028482014-12-18 16:28:54 -0800440// Does not affect the ordering of the current mutator pass, but will be ordered
441// correctly for all future mutator passes.
Colin Cross763b6f12015-10-29 15:32:56 -0700442func (mctx *mutatorContext) AddDependency(module Module, deps ...string) {
443 for _, dep := range deps {
444 errs := mctx.context.addDependency(mctx.context.moduleInfo[module], dep)
445 if len(errs) > 0 {
446 mctx.errs = append(mctx.errs, errs...)
447 }
Colin Cross65569e42015-03-10 20:08:19 -0700448 }
Dan Willemsenfdeb7242015-07-24 16:53:27 -0700449}
450
451// Add a dependency from the destination to the given module.
452// Does not affect the ordering of the current mutator pass, but will be ordered
453// correctly for all future mutator passes.
454func (mctx *mutatorContext) AddReverseDependency(module Module, destName string) {
Colin Cross763b6f12015-10-29 15:32:56 -0700455 errs := mctx.context.addReverseDependency(mctx.module, destName)
Dan Willemsenfdeb7242015-07-24 16:53:27 -0700456 if len(errs) > 0 {
457 mctx.errs = append(mctx.errs, errs...)
458 }
Colin Crossc9028482014-12-18 16:28:54 -0800459}
460
Colin Cross763b6f12015-10-29 15:32:56 -0700461// AddVariationDependencies adds deps as dependencies of the current module, but uses the variations
462// argument to select which variant of the dependency to use. A variant of the dependency must
463// exist that matches the all of the non-local variations of the current module, plus the variations
464// argument.
465func (mctx *mutatorContext) AddVariationDependencies(variations []Variation,
466 deps ...string) {
467
468 for _, dep := range deps {
469 errs := mctx.context.addVariationDependency(mctx.module, variations, dep, false)
470 if len(errs) > 0 {
471 mctx.errs = append(mctx.errs, errs...)
472 }
473 }
474}
475
476// AddFarVariationDependencies adds deps as dependencies of the current module, but uses the
477// variations argument to select which variant of the dependency to use. A variant of the
478// dependency must exist that matches the variations argument, but may also have other variations.
479// For any unspecified variation the first variant will be used.
480//
481// Unlike AddVariationDependencies, the variations of the current module are ignored - the
482// depdendency only needs to match the supplied variations.
483func (mctx *mutatorContext) AddFarVariationDependencies(variations []Variation,
484 deps ...string) {
485
486 for _, dep := range deps {
487 errs := mctx.context.addVariationDependency(mctx.module, variations, dep, true)
488 if len(errs) > 0 {
489 mctx.errs = append(mctx.errs, errs...)
490 }
491 }
492}
493
Colin Crossc9028482014-12-18 16:28:54 -0800494func (mctx *mutatorContext) VisitDirectDeps(visit func(Module)) {
495 mctx.context.visitDirectDeps(mctx.module, visit)
496}
497
498func (mctx *mutatorContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) {
499 mctx.context.visitDirectDepsIf(mctx.module, pred, visit)
500}
501
502func (mctx *mutatorContext) VisitDepsDepthFirst(visit func(Module)) {
503 mctx.context.visitDepsDepthFirst(mctx.module, visit)
504}
505
506func (mctx *mutatorContext) VisitDepsDepthFirstIf(pred func(Module) bool,
507 visit func(Module)) {
508
509 mctx.context.visitDepsDepthFirstIf(mctx.module, pred, visit)
510}
Yuchen Wu222e2452015-10-06 14:03:27 -0700511
512func (mctx *mutatorContext) WalkDeps(visit func(Module, Module) bool) {
513 mctx.context.walkDeps(mctx.module, visit)
514}