Home | History | Annotate | Download | only in blueprint
      1 // 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 
     15 package blueprint
     16 
     17 import (
     18 	"bytes"
     19 	"errors"
     20 	"fmt"
     21 	"io"
     22 	"path/filepath"
     23 	"reflect"
     24 	"runtime"
     25 	"sort"
     26 	"strconv"
     27 	"strings"
     28 	"sync"
     29 	"sync/atomic"
     30 	"text/scanner"
     31 	"text/template"
     32 
     33 	"github.com/google/blueprint/parser"
     34 	"github.com/google/blueprint/pathtools"
     35 	"github.com/google/blueprint/proptools"
     36 )
     37 
     38 var ErrBuildActionsNotReady = errors.New("build actions are not ready")
     39 
     40 const maxErrors = 10
     41 
     42 // A Context contains all the state needed to parse a set of Blueprints files
     43 // and generate a Ninja file.  The process of generating a Ninja file proceeds
     44 // through a series of four phases.  Each phase corresponds with a some methods
     45 // on the Context object
     46 //
     47 //         Phase                            Methods
     48 //      ------------      -------------------------------------------
     49 //   1. Registration         RegisterModuleType, RegisterSingletonType
     50 //
     51 //   2. Parse                    ParseBlueprintsFiles, Parse
     52 //
     53 //   3. Generate            ResolveDependencies, PrepareBuildActions
     54 //
     55 //   4. Write                           WriteBuildFile
     56 //
     57 // The registration phase prepares the context to process Blueprints files
     58 // containing various types of modules.  The parse phase reads in one or more
     59 // Blueprints files and validates their contents against the module types that
     60 // have been registered.  The generate phase then analyzes the parsed Blueprints
     61 // contents to create an internal representation for the build actions that must
     62 // be performed.  This phase also performs validation of the module dependencies
     63 // and property values defined in the parsed Blueprints files.  Finally, the
     64 // write phase generates the Ninja manifest text based on the generated build
     65 // actions.
     66 type Context struct {
     67 	// set at instantiation
     68 	moduleFactories     map[string]ModuleFactory
     69 	moduleNames         map[string]*moduleGroup
     70 	moduleGroups        []*moduleGroup
     71 	moduleInfo          map[Module]*moduleInfo
     72 	modulesSorted       []*moduleInfo
     73 	singletonInfo       []*singletonInfo
     74 	mutatorInfo         []*mutatorInfo
     75 	earlyMutatorInfo    []*mutatorInfo
     76 	variantMutatorNames []string
     77 	moduleNinjaNames    map[string]*moduleGroup
     78 
     79 	depsModified uint32 // positive if a mutator modified the dependencies
     80 
     81 	dependenciesReady bool // set to true on a successful ResolveDependencies
     82 	buildActionsReady bool // set to true on a successful PrepareBuildActions
     83 
     84 	// set by SetIgnoreUnknownModuleTypes
     85 	ignoreUnknownModuleTypes bool
     86 
     87 	// set by SetAllowMissingDependencies
     88 	allowMissingDependencies bool
     89 
     90 	// set during PrepareBuildActions
     91 	pkgNames        map[*packageContext]string
     92 	globalVariables map[Variable]*ninjaString
     93 	globalPools     map[Pool]*poolDef
     94 	globalRules     map[Rule]*ruleDef
     95 
     96 	// set during PrepareBuildActions
     97 	ninjaBuildDir      *ninjaString // The builddir special Ninja variable
     98 	requiredNinjaMajor int          // For the ninja_required_version variable
     99 	requiredNinjaMinor int          // For the ninja_required_version variable
    100 	requiredNinjaMicro int          // For the ninja_required_version variable
    101 
    102 	// set lazily by sortedModuleNames
    103 	cachedSortedModuleNames []string
    104 
    105 	globs    map[string]GlobPath
    106 	globLock sync.Mutex
    107 
    108 	fs pathtools.FileSystem
    109 }
    110 
    111 // An Error describes a problem that was encountered that is related to a
    112 // particular location in a Blueprints file.
    113 type BlueprintError struct {
    114 	Err error            // the error that occurred
    115 	Pos scanner.Position // the relevant Blueprints file location
    116 }
    117 
    118 // A ModuleError describes a problem that was encountered that is related to a
    119 // particular module in a Blueprints file
    120 type ModuleError struct {
    121 	BlueprintError
    122 	module *moduleInfo
    123 }
    124 
    125 // A PropertyError describes a problem that was encountered that is related to a
    126 // particular property in a Blueprints file
    127 type PropertyError struct {
    128 	ModuleError
    129 	property string
    130 }
    131 
    132 func (e *BlueprintError) Error() string {
    133 	return fmt.Sprintf("%s: %s", e.Pos, e.Err)
    134 }
    135 
    136 func (e *ModuleError) Error() string {
    137 	return fmt.Sprintf("%s: %s: %s", e.Pos, e.module, e.Err)
    138 }
    139 
    140 func (e *PropertyError) Error() string {
    141 	return fmt.Sprintf("%s: %s: %s: %s", e.Pos, e.module, e.property, e.Err)
    142 }
    143 
    144 type localBuildActions struct {
    145 	variables []*localVariable
    146 	rules     []*localRule
    147 	buildDefs []*buildDef
    148 }
    149 
    150 type moduleGroup struct {
    151 	name      string
    152 	ninjaName string
    153 
    154 	modules []*moduleInfo
    155 }
    156 
    157 type moduleInfo struct {
    158 	// set during Parse
    159 	typeName          string
    160 	relBlueprintsFile string
    161 	pos               scanner.Position
    162 	propertyPos       map[string]scanner.Position
    163 
    164 	variantName       string
    165 	variant           variationMap
    166 	dependencyVariant variationMap
    167 
    168 	logicModule      Module
    169 	group            *moduleGroup
    170 	moduleProperties []interface{}
    171 
    172 	// set during ResolveDependencies
    173 	directDeps  []depInfo
    174 	missingDeps []string
    175 
    176 	// set during updateDependencies
    177 	reverseDeps []*moduleInfo
    178 	forwardDeps []*moduleInfo
    179 
    180 	// used by parallelVisitAllBottomUp
    181 	waitingCount int
    182 
    183 	// set during each runMutator
    184 	splitModules []*moduleInfo
    185 
    186 	// set during PrepareBuildActions
    187 	actionDefs localBuildActions
    188 }
    189 
    190 type depInfo struct {
    191 	module *moduleInfo
    192 	tag    DependencyTag
    193 }
    194 
    195 func (module *moduleInfo) Name() string {
    196 	return module.group.name
    197 }
    198 
    199 func (module *moduleInfo) String() string {
    200 	s := fmt.Sprintf("module %q", module.Name())
    201 	if module.variantName != "" {
    202 		s += fmt.Sprintf(" variant %q", module.variantName)
    203 	}
    204 	return s
    205 }
    206 
    207 // A Variation is a way that a variant of a module differs from other variants of the same module.
    208 // For example, two variants of the same module might have Variation{"arch","arm"} and
    209 // Variation{"arch","arm64"}
    210 type Variation struct {
    211 	// Mutator is the axis on which this variation applies, i.e. "arch" or "link"
    212 	Mutator string
    213 	// Variation is the name of the variation on the axis, i.e. "arm" or "arm64" for arch, or
    214 	// "shared" or "static" for link.
    215 	Variation string
    216 }
    217 
    218 // A variationMap stores a map of Mutator to Variation to specify a variant of a module.
    219 type variationMap map[string]string
    220 
    221 func (vm variationMap) clone() variationMap {
    222 	newVm := make(variationMap)
    223 	for k, v := range vm {
    224 		newVm[k] = v
    225 	}
    226 
    227 	return newVm
    228 }
    229 
    230 // Compare this variationMap to another one.  Returns true if the every entry in this map
    231 // is either the same in the other map or doesn't exist in the other map.
    232 func (vm variationMap) subset(other variationMap) bool {
    233 	for k, v1 := range vm {
    234 		if v2, ok := other[k]; ok && v1 != v2 {
    235 			return false
    236 		}
    237 	}
    238 	return true
    239 }
    240 
    241 func (vm variationMap) equal(other variationMap) bool {
    242 	return reflect.DeepEqual(vm, other)
    243 }
    244 
    245 type singletonInfo struct {
    246 	// set during RegisterSingletonType
    247 	factory   SingletonFactory
    248 	singleton Singleton
    249 	name      string
    250 
    251 	// set during PrepareBuildActions
    252 	actionDefs localBuildActions
    253 }
    254 
    255 type mutatorInfo struct {
    256 	// set during RegisterMutator
    257 	topDownMutator  TopDownMutator
    258 	bottomUpMutator BottomUpMutator
    259 	name            string
    260 	parallel        bool
    261 }
    262 
    263 // NewContext creates a new Context object.  The created context initially has
    264 // no module or singleton factories registered, so the RegisterModuleFactory and
    265 // RegisterSingletonFactory methods must be called before it can do anything
    266 // useful.
    267 func NewContext() *Context {
    268 	ctx := &Context{
    269 		moduleFactories:  make(map[string]ModuleFactory),
    270 		moduleNames:      make(map[string]*moduleGroup),
    271 		moduleInfo:       make(map[Module]*moduleInfo),
    272 		moduleNinjaNames: make(map[string]*moduleGroup),
    273 		globs:            make(map[string]GlobPath),
    274 		fs:               pathtools.OsFs,
    275 	}
    276 
    277 	ctx.RegisterBottomUpMutator("blueprint_deps", blueprintDepsMutator)
    278 
    279 	return ctx
    280 }
    281 
    282 // A ModuleFactory function creates a new Module object.  See the
    283 // Context.RegisterModuleType method for details about how a registered
    284 // ModuleFactory is used by a Context.
    285 type ModuleFactory func() (m Module, propertyStructs []interface{})
    286 
    287 // RegisterModuleType associates a module type name (which can appear in a
    288 // Blueprints file) with a Module factory function.  When the given module type
    289 // name is encountered in a Blueprints file during parsing, the Module factory
    290 // is invoked to instantiate a new Module object to handle the build action
    291 // generation for the module.  If a Mutator splits a module into multiple variants,
    292 // the factory is invoked again to create a new Module for each variant.
    293 //
    294 // The module type names given here must be unique for the context.  The factory
    295 // function should be a named function so that its package and name can be
    296 // included in the generated Ninja file for debugging purposes.
    297 //
    298 // The factory function returns two values.  The first is the newly created
    299 // Module object.  The second is a slice of pointers to that Module object's
    300 // properties structs.  Each properties struct is examined when parsing a module
    301 // definition of this type in a Blueprints file.  Exported fields of the
    302 // properties structs are automatically set to the property values specified in
    303 // the Blueprints file.  The properties struct field names determine the name of
    304 // the Blueprints file properties that are used - the Blueprints property name
    305 // matches that of the properties struct field name with the first letter
    306 // converted to lower-case.
    307 //
    308 // The fields of the properties struct must be either []string, a string, or
    309 // bool. The Context will panic if a Module gets instantiated with a properties
    310 // struct containing a field that is not one these supported types.
    311 //
    312 // Any properties that appear in the Blueprints files that are not built-in
    313 // module properties (such as "name" and "deps") and do not have a corresponding
    314 // field in the returned module properties struct result in an error during the
    315 // Context's parse phase.
    316 //
    317 // As an example, the follow code:
    318 //
    319 //   type myModule struct {
    320 //       properties struct {
    321 //           Foo string
    322 //           Bar []string
    323 //       }
    324 //   }
    325 //
    326 //   func NewMyModule() (blueprint.Module, []interface{}) {
    327 //       module := new(myModule)
    328 //       properties := &module.properties
    329 //       return module, []interface{}{properties}
    330 //   }
    331 //
    332 //   func main() {
    333 //       ctx := blueprint.NewContext()
    334 //       ctx.RegisterModuleType("my_module", NewMyModule)
    335 //       // ...
    336 //   }
    337 //
    338 // would support parsing a module defined in a Blueprints file as follows:
    339 //
    340 //   my_module {
    341 //       name: "myName",
    342 //       foo:  "my foo string",
    343 //       bar:  ["my", "bar", "strings"],
    344 //   }
    345 //
    346 // The factory function may be called from multiple goroutines.  Any accesses
    347 // to global variables must be synchronized.
    348 func (c *Context) RegisterModuleType(name string, factory ModuleFactory) {
    349 	if _, present := c.moduleFactories[name]; present {
    350 		panic(errors.New("module type name is already registered"))
    351 	}
    352 	c.moduleFactories[name] = factory
    353 }
    354 
    355 // A SingletonFactory function creates a new Singleton object.  See the
    356 // Context.RegisterSingletonType method for details about how a registered
    357 // SingletonFactory is used by a Context.
    358 type SingletonFactory func() Singleton
    359 
    360 // RegisterSingletonType registers a singleton type that will be invoked to
    361 // generate build actions.  Each registered singleton type is instantiated and
    362 // and invoked exactly once as part of the generate phase.  Each registered
    363 // singleton is invoked in registration order.
    364 //
    365 // The singleton type names given here must be unique for the context.  The
    366 // factory function should be a named function so that its package and name can
    367 // be included in the generated Ninja file for debugging purposes.
    368 func (c *Context) RegisterSingletonType(name string, factory SingletonFactory) {
    369 	for _, s := range c.singletonInfo {
    370 		if s.name == name {
    371 			panic(errors.New("singleton name is already registered"))
    372 		}
    373 	}
    374 
    375 	c.singletonInfo = append(c.singletonInfo, &singletonInfo{
    376 		factory:   factory,
    377 		singleton: factory(),
    378 		name:      name,
    379 	})
    380 }
    381 
    382 func singletonPkgPath(singleton Singleton) string {
    383 	typ := reflect.TypeOf(singleton)
    384 	for typ.Kind() == reflect.Ptr {
    385 		typ = typ.Elem()
    386 	}
    387 	return typ.PkgPath()
    388 }
    389 
    390 func singletonTypeName(singleton Singleton) string {
    391 	typ := reflect.TypeOf(singleton)
    392 	for typ.Kind() == reflect.Ptr {
    393 		typ = typ.Elem()
    394 	}
    395 	return typ.PkgPath() + "." + typ.Name()
    396 }
    397 
    398 // RegisterTopDownMutator registers a mutator that will be invoked to propagate dependency info
    399 // top-down between Modules.  Each registered mutator is invoked in registration order (mixing
    400 // TopDownMutators and BottomUpMutators) once per Module, and the invocation on any module will
    401 // have returned before it is in invoked on any of its dependencies.
    402 //
    403 // The mutator type names given here must be unique to all top down mutators in
    404 // the Context.
    405 //
    406 // Returns a MutatorHandle, on which Parallel can be called to set the mutator to visit modules in
    407 // parallel while maintaining ordering.
    408 func (c *Context) RegisterTopDownMutator(name string, mutator TopDownMutator) MutatorHandle {
    409 	for _, m := range c.mutatorInfo {
    410 		if m.name == name && m.topDownMutator != nil {
    411 			panic(fmt.Errorf("mutator name %s is already registered", name))
    412 		}
    413 	}
    414 
    415 	info := &mutatorInfo{
    416 		topDownMutator: mutator,
    417 		name:           name,
    418 	}
    419 
    420 	c.mutatorInfo = append(c.mutatorInfo, info)
    421 
    422 	return info
    423 }
    424 
    425 // RegisterBottomUpMutator registers a mutator that will be invoked to split Modules into variants.
    426 // Each registered mutator is invoked in registration order (mixing TopDownMutators and
    427 // BottomUpMutators) once per Module, will not be invoked on a module until the invocations on all
    428 // of the modules dependencies have returned.
    429 //
    430 // The mutator type names given here must be unique to all bottom up or early
    431 // mutators in the Context.
    432 //
    433 // Returns a MutatorHandle, on which Parallel can be called to set the mutator to visit modules in
    434 // parallel while maintaining ordering.
    435 func (c *Context) RegisterBottomUpMutator(name string, mutator BottomUpMutator) MutatorHandle {
    436 	for _, m := range c.variantMutatorNames {
    437 		if m == name {
    438 			panic(fmt.Errorf("mutator name %s is already registered", name))
    439 		}
    440 	}
    441 
    442 	info := &mutatorInfo{
    443 		bottomUpMutator: mutator,
    444 		name:            name,
    445 	}
    446 	c.mutatorInfo = append(c.mutatorInfo, info)
    447 
    448 	c.variantMutatorNames = append(c.variantMutatorNames, name)
    449 
    450 	return info
    451 }
    452 
    453 type MutatorHandle interface {
    454 	// Set the mutator to visit modules in parallel while maintaining ordering.  Calling any
    455 	// method on the mutator context is thread-safe, but the mutator must handle synchronization
    456 	// for any modifications to global state or any modules outside the one it was invoked on.
    457 	Parallel() MutatorHandle
    458 }
    459 
    460 func (mutator *mutatorInfo) Parallel() MutatorHandle {
    461 	mutator.parallel = true
    462 	return mutator
    463 }
    464 
    465 // RegisterEarlyMutator registers a mutator that will be invoked to split
    466 // Modules into multiple variant Modules before any dependencies have been
    467 // created.  Each registered mutator is invoked in registration order once
    468 // per Module (including each variant from previous early mutators).  Module
    469 // order is unpredictable.
    470 //
    471 // In order for dependencies to be satisifed in a later pass, all dependencies
    472 // of a module either must have an identical variant or must have no variations.
    473 //
    474 // The mutator type names given here must be unique to all bottom up or early
    475 // mutators in the Context.
    476 //
    477 // Deprecated, use a BottomUpMutator instead.  The only difference between
    478 // EarlyMutator and BottomUpMutator is that EarlyMutator runs before the
    479 // deprecated DynamicDependencies.
    480 func (c *Context) RegisterEarlyMutator(name string, mutator EarlyMutator) {
    481 	for _, m := range c.variantMutatorNames {
    482 		if m == name {
    483 			panic(fmt.Errorf("mutator name %s is already registered", name))
    484 		}
    485 	}
    486 
    487 	c.earlyMutatorInfo = append(c.earlyMutatorInfo, &mutatorInfo{
    488 		bottomUpMutator: func(mctx BottomUpMutatorContext) {
    489 			mutator(mctx)
    490 		},
    491 		name: name,
    492 	})
    493 
    494 	c.variantMutatorNames = append(c.variantMutatorNames, name)
    495 }
    496 
    497 // SetIgnoreUnknownModuleTypes sets the behavior of the context in the case
    498 // where it encounters an unknown module type while parsing Blueprints files. By
    499 // default, the context will report unknown module types as an error.  If this
    500 // method is called with ignoreUnknownModuleTypes set to true then the context
    501 // will silently ignore unknown module types.
    502 //
    503 // This method should generally not be used.  It exists to facilitate the
    504 // bootstrapping process.
    505 func (c *Context) SetIgnoreUnknownModuleTypes(ignoreUnknownModuleTypes bool) {
    506 	c.ignoreUnknownModuleTypes = ignoreUnknownModuleTypes
    507 }
    508 
    509 // SetAllowMissingDependencies changes the behavior of Blueprint to ignore
    510 // unresolved dependencies.  If the module's GenerateBuildActions calls
    511 // ModuleContext.GetMissingDependencies Blueprint will not emit any errors
    512 // for missing dependencies.
    513 func (c *Context) SetAllowMissingDependencies(allowMissingDependencies bool) {
    514 	c.allowMissingDependencies = allowMissingDependencies
    515 }
    516 
    517 // Parse parses a single Blueprints file from r, creating Module objects for
    518 // each of the module definitions encountered.  If the Blueprints file contains
    519 // an assignment to the "subdirs" variable, then the subdirectories listed are
    520 // searched for Blueprints files returned in the subBlueprints return value.
    521 // If the Blueprints file contains an assignment to the "build" variable, then
    522 // the file listed are returned in the subBlueprints return value.
    523 //
    524 // rootDir specifies the path to the root directory of the source tree, while
    525 // filename specifies the path to the Blueprints file.  These paths are used for
    526 // error reporting and for determining the module's directory.
    527 func (c *Context) parse(rootDir, filename string, r io.Reader,
    528 	scope *parser.Scope) (file *parser.File, subBlueprints []stringAndScope, errs []error) {
    529 
    530 	relBlueprintsFile, err := filepath.Rel(rootDir, filename)
    531 	if err != nil {
    532 		return nil, nil, []error{err}
    533 	}
    534 
    535 	scope = parser.NewScope(scope)
    536 	scope.Remove("subdirs")
    537 	scope.Remove("optional_subdirs")
    538 	scope.Remove("build")
    539 	file, errs = parser.ParseAndEval(filename, r, scope)
    540 	if len(errs) > 0 {
    541 		for i, err := range errs {
    542 			if parseErr, ok := err.(*parser.ParseError); ok {
    543 				err = &BlueprintError{
    544 					Err: parseErr.Err,
    545 					Pos: parseErr.Pos,
    546 				}
    547 				errs[i] = err
    548 			}
    549 		}
    550 
    551 		// If there were any parse errors don't bother trying to interpret the
    552 		// result.
    553 		return nil, nil, errs
    554 	}
    555 	file.Name = relBlueprintsFile
    556 
    557 	subdirs, subdirsPos, err := getLocalStringListFromScope(scope, "subdirs")
    558 	if err != nil {
    559 		errs = append(errs, err)
    560 	}
    561 
    562 	optionalSubdirs, optionalSubdirsPos, err := getLocalStringListFromScope(scope, "optional_subdirs")
    563 	if err != nil {
    564 		errs = append(errs, err)
    565 	}
    566 
    567 	build, buildPos, err := getLocalStringListFromScope(scope, "build")
    568 	if err != nil {
    569 		errs = append(errs, err)
    570 	}
    571 
    572 	subBlueprintsName, _, err := getStringFromScope(scope, "subname")
    573 	if err != nil {
    574 		errs = append(errs, err)
    575 	}
    576 
    577 	if subBlueprintsName == "" {
    578 		subBlueprintsName = "Blueprints"
    579 	}
    580 
    581 	var blueprints []string
    582 
    583 	newBlueprints, newErrs := c.findBuildBlueprints(filepath.Dir(filename), build, buildPos)
    584 	blueprints = append(blueprints, newBlueprints...)
    585 	errs = append(errs, newErrs...)
    586 
    587 	newBlueprints, newErrs = c.findSubdirBlueprints(filepath.Dir(filename), subdirs, subdirsPos,
    588 		subBlueprintsName, false)
    589 	blueprints = append(blueprints, newBlueprints...)
    590 	errs = append(errs, newErrs...)
    591 
    592 	newBlueprints, newErrs = c.findSubdirBlueprints(filepath.Dir(filename), optionalSubdirs,
    593 		optionalSubdirsPos, subBlueprintsName, true)
    594 	blueprints = append(blueprints, newBlueprints...)
    595 	errs = append(errs, newErrs...)
    596 
    597 	subBlueprintsAndScope := make([]stringAndScope, len(blueprints))
    598 	for i, b := range blueprints {
    599 		subBlueprintsAndScope[i] = stringAndScope{b, scope}
    600 	}
    601 
    602 	return file, subBlueprintsAndScope, errs
    603 }
    604 
    605 type stringAndScope struct {
    606 	string
    607 	*parser.Scope
    608 }
    609 
    610 // ParseBlueprintsFiles parses a set of Blueprints files starting with the file
    611 // at rootFile.  When it encounters a Blueprints file with a set of subdirs
    612 // listed it recursively parses any Blueprints files found in those
    613 // subdirectories.
    614 //
    615 // If no errors are encountered while parsing the files, the list of paths on
    616 // which the future output will depend is returned.  This list will include both
    617 // Blueprints file paths as well as directory paths for cases where wildcard
    618 // subdirs are found.
    619 func (c *Context) ParseBlueprintsFiles(rootFile string) (deps []string,
    620 	errs []error) {
    621 
    622 	c.dependenciesReady = false
    623 
    624 	moduleCh := make(chan *moduleInfo)
    625 	errsCh := make(chan []error)
    626 	doneCh := make(chan struct{})
    627 	var numErrs uint32
    628 	var numGoroutines int32
    629 
    630 	// handler must be reentrant
    631 	handler := func(file *parser.File) {
    632 		if atomic.LoadUint32(&numErrs) > maxErrors {
    633 			return
    634 		}
    635 
    636 		atomic.AddInt32(&numGoroutines, 1)
    637 		go func() {
    638 			for _, def := range file.Defs {
    639 				var module *moduleInfo
    640 				var errs []error
    641 				switch def := def.(type) {
    642 				case *parser.Module:
    643 					module, errs = c.processModuleDef(def, file.Name)
    644 				case *parser.Assignment:
    645 					// Already handled via Scope object
    646 				default:
    647 					panic("unknown definition type")
    648 				}
    649 
    650 				if len(errs) > 0 {
    651 					atomic.AddUint32(&numErrs, uint32(len(errs)))
    652 					errsCh <- errs
    653 				} else if module != nil {
    654 					moduleCh <- module
    655 				}
    656 			}
    657 			doneCh <- struct{}{}
    658 		}()
    659 	}
    660 
    661 	atomic.AddInt32(&numGoroutines, 1)
    662 	go func() {
    663 		var errs []error
    664 		deps, errs = c.WalkBlueprintsFiles(rootFile, handler)
    665 		if len(errs) > 0 {
    666 			errsCh <- errs
    667 		}
    668 		doneCh <- struct{}{}
    669 	}()
    670 
    671 loop:
    672 	for {
    673 		select {
    674 		case newErrs := <-errsCh:
    675 			errs = append(errs, newErrs...)
    676 		case module := <-moduleCh:
    677 			newErrs := c.addModule(module)
    678 			if len(newErrs) > 0 {
    679 				errs = append(errs, newErrs...)
    680 			}
    681 		case <-doneCh:
    682 			n := atomic.AddInt32(&numGoroutines, -1)
    683 			if n == 0 {
    684 				break loop
    685 			}
    686 		}
    687 	}
    688 
    689 	return deps, errs
    690 }
    691 
    692 type FileHandler func(*parser.File)
    693 
    694 // Walk a set of Blueprints files starting with the file at rootFile, calling handler on each.
    695 // When it encounters a Blueprints file with a set of subdirs listed it recursively parses any
    696 // Blueprints files found in those subdirectories.  handler will be called from a goroutine, so
    697 // it must be reentrant.
    698 //
    699 // If no errors are encountered while parsing the files, the list of paths on
    700 // which the future output will depend is returned.  This list will include both
    701 // Blueprints file paths as well as directory paths for cases where wildcard
    702 // subdirs are found.
    703 func (c *Context) WalkBlueprintsFiles(rootFile string, handler FileHandler) (deps []string,
    704 	errs []error) {
    705 
    706 	rootDir := filepath.Dir(rootFile)
    707 
    708 	blueprintsSet := make(map[string]bool)
    709 
    710 	// Channels to receive data back from parseBlueprintsFile goroutines
    711 	blueprintsCh := make(chan stringAndScope)
    712 	errsCh := make(chan []error)
    713 	fileCh := make(chan *parser.File)
    714 	depsCh := make(chan string)
    715 
    716 	// Channel to notify main loop that a parseBlueprintsFile goroutine has finished
    717 	doneCh := make(chan struct{})
    718 
    719 	// Number of outstanding goroutines to wait for
    720 	count := 0
    721 
    722 	startParseBlueprintsFile := func(filename string, scope *parser.Scope) {
    723 		count++
    724 		go func() {
    725 			c.parseBlueprintsFile(filename, scope, rootDir,
    726 				errsCh, fileCh, blueprintsCh, depsCh)
    727 			doneCh <- struct{}{}
    728 		}()
    729 	}
    730 
    731 	tooManyErrors := false
    732 
    733 	startParseBlueprintsFile(rootFile, nil)
    734 
    735 loop:
    736 	for {
    737 		if len(errs) > maxErrors {
    738 			tooManyErrors = true
    739 		}
    740 
    741 		select {
    742 		case newErrs := <-errsCh:
    743 			errs = append(errs, newErrs...)
    744 		case dep := <-depsCh:
    745 			deps = append(deps, dep)
    746 		case file := <-fileCh:
    747 			handler(file)
    748 		case blueprint := <-blueprintsCh:
    749 			if tooManyErrors {
    750 				continue
    751 			}
    752 			if blueprintsSet[blueprint.string] {
    753 				continue
    754 			}
    755 
    756 			blueprintsSet[blueprint.string] = true
    757 			startParseBlueprintsFile(blueprint.string, blueprint.Scope)
    758 		case <-doneCh:
    759 			count--
    760 			if count == 0 {
    761 				break loop
    762 			}
    763 		}
    764 	}
    765 
    766 	return
    767 }
    768 
    769 // MockFileSystem causes the Context to replace all reads with accesses to the provided map of
    770 // filenames to contents stored as a byte slice.
    771 func (c *Context) MockFileSystem(files map[string][]byte) {
    772 	c.fs = pathtools.MockFs(files)
    773 }
    774 
    775 // parseBlueprintFile parses a single Blueprints file, returning any errors through
    776 // errsCh, any defined modules through modulesCh, any sub-Blueprints files through
    777 // blueprintsCh, and any dependencies on Blueprints files or directories through
    778 // depsCh.
    779 func (c *Context) parseBlueprintsFile(filename string, scope *parser.Scope, rootDir string,
    780 	errsCh chan<- []error, fileCh chan<- *parser.File, blueprintsCh chan<- stringAndScope,
    781 	depsCh chan<- string) {
    782 
    783 	f, err := c.fs.Open(filename)
    784 	if err != nil {
    785 		errsCh <- []error{err}
    786 		return
    787 	}
    788 	defer func() {
    789 		err = f.Close()
    790 		if err != nil {
    791 			errsCh <- []error{err}
    792 		}
    793 	}()
    794 
    795 	file, subBlueprints, errs := c.parse(rootDir, filename, f, scope)
    796 	if len(errs) > 0 {
    797 		errsCh <- errs
    798 	} else {
    799 		fileCh <- file
    800 	}
    801 
    802 	for _, b := range subBlueprints {
    803 		blueprintsCh <- b
    804 		depsCh <- b.string
    805 	}
    806 }
    807 
    808 func (c *Context) findBuildBlueprints(dir string, build []string,
    809 	buildPos scanner.Position) ([]string, []error) {
    810 
    811 	var blueprints []string
    812 	var errs []error
    813 
    814 	for _, file := range build {
    815 		pattern := filepath.Join(dir, file)
    816 		var matches []string
    817 		var err error
    818 
    819 		matches, err = c.glob(pattern, nil)
    820 
    821 		if err != nil {
    822 			errs = append(errs, &BlueprintError{
    823 				Err: fmt.Errorf("%q: %s", pattern, err.Error()),
    824 				Pos: buildPos,
    825 			})
    826 			continue
    827 		}
    828 
    829 		if len(matches) == 0 {
    830 			errs = append(errs, &BlueprintError{
    831 				Err: fmt.Errorf("%q: not found", pattern),
    832 				Pos: buildPos,
    833 			})
    834 		}
    835 
    836 		for _, foundBlueprints := range matches {
    837 			blueprints = append(blueprints, foundBlueprints)
    838 		}
    839 	}
    840 
    841 	return blueprints, errs
    842 }
    843 
    844 func (c *Context) findSubdirBlueprints(dir string, subdirs []string, subdirsPos scanner.Position,
    845 	subBlueprintsName string, optional bool) ([]string, []error) {
    846 
    847 	var blueprints []string
    848 	var errs []error
    849 
    850 	for _, subdir := range subdirs {
    851 		pattern := filepath.Join(dir, subdir, subBlueprintsName)
    852 		var matches []string
    853 		var err error
    854 
    855 		matches, err = c.glob(pattern, nil)
    856 
    857 		if err != nil {
    858 			errs = append(errs, &BlueprintError{
    859 				Err: fmt.Errorf("%q: %s", pattern, err.Error()),
    860 				Pos: subdirsPos,
    861 			})
    862 			continue
    863 		}
    864 
    865 		if len(matches) == 0 && !optional {
    866 			errs = append(errs, &BlueprintError{
    867 				Err: fmt.Errorf("%q: not found", pattern),
    868 				Pos: subdirsPos,
    869 			})
    870 		}
    871 
    872 		for _, subBlueprints := range matches {
    873 			blueprints = append(blueprints, subBlueprints)
    874 		}
    875 	}
    876 
    877 	return blueprints, errs
    878 }
    879 
    880 func getLocalStringListFromScope(scope *parser.Scope, v string) ([]string, scanner.Position, error) {
    881 	if assignment, local := scope.Get(v); assignment == nil || !local {
    882 		return nil, scanner.Position{}, nil
    883 	} else {
    884 		switch value := assignment.Value.Eval().(type) {
    885 		case *parser.List:
    886 			ret := make([]string, 0, len(value.Values))
    887 
    888 			for _, listValue := range value.Values {
    889 				s, ok := listValue.(*parser.String)
    890 				if !ok {
    891 					// The parser should not produce this.
    892 					panic("non-string value found in list")
    893 				}
    894 
    895 				ret = append(ret, s.Value)
    896 			}
    897 
    898 			return ret, assignment.EqualsPos, nil
    899 		case *parser.Bool, *parser.String:
    900 			return nil, scanner.Position{}, &BlueprintError{
    901 				Err: fmt.Errorf("%q must be a list of strings", v),
    902 				Pos: assignment.EqualsPos,
    903 			}
    904 		default:
    905 			panic(fmt.Errorf("unknown value type: %d", assignment.Value.Type))
    906 		}
    907 	}
    908 }
    909 
    910 func getStringFromScope(scope *parser.Scope, v string) (string, scanner.Position, error) {
    911 	if assignment, _ := scope.Get(v); assignment == nil {
    912 		return "", scanner.Position{}, nil
    913 	} else {
    914 		switch value := assignment.Value.Eval().(type) {
    915 		case *parser.String:
    916 			return value.Value, assignment.EqualsPos, nil
    917 		case *parser.Bool, *parser.List:
    918 			return "", scanner.Position{}, &BlueprintError{
    919 				Err: fmt.Errorf("%q must be a string", v),
    920 				Pos: assignment.EqualsPos,
    921 			}
    922 		default:
    923 			panic(fmt.Errorf("unknown value type: %d", assignment.Value.Type))
    924 		}
    925 	}
    926 }
    927 
    928 // Clones a build logic module by calling the factory method for its module type, and then cloning
    929 // property values.  Any values stored in the module object that are not stored in properties
    930 // structs will be lost.
    931 func (c *Context) cloneLogicModule(origModule *moduleInfo) (Module, []interface{}) {
    932 	typeName := origModule.typeName
    933 	factory, ok := c.moduleFactories[typeName]
    934 	if !ok {
    935 		panic(fmt.Sprintf("unrecognized module type %q during cloning", typeName))
    936 	}
    937 
    938 	newLogicModule, newProperties := factory()
    939 
    940 	if len(newProperties) != len(origModule.moduleProperties) {
    941 		panic("mismatched properties array length in " + origModule.Name())
    942 	}
    943 
    944 	for i := range newProperties {
    945 		dst := reflect.ValueOf(newProperties[i]).Elem()
    946 		src := reflect.ValueOf(origModule.moduleProperties[i]).Elem()
    947 
    948 		proptools.CopyProperties(dst, src)
    949 	}
    950 
    951 	return newLogicModule, newProperties
    952 }
    953 
    954 func (c *Context) createVariations(origModule *moduleInfo, mutatorName string,
    955 	variationNames []string) ([]*moduleInfo, []error) {
    956 
    957 	if len(variationNames) == 0 {
    958 		panic(fmt.Errorf("mutator %q passed zero-length variation list for module %q",
    959 			mutatorName, origModule.Name()))
    960 	}
    961 
    962 	newModules := []*moduleInfo{}
    963 
    964 	var errs []error
    965 
    966 	for i, variationName := range variationNames {
    967 		var newLogicModule Module
    968 		var newProperties []interface{}
    969 
    970 		if i == 0 {
    971 			// Reuse the existing module for the first new variant
    972 			// This both saves creating a new module, and causes the insertion in c.moduleInfo below
    973 			// with logicModule as the key to replace the original entry in c.moduleInfo
    974 			newLogicModule, newProperties = origModule.logicModule, origModule.moduleProperties
    975 		} else {
    976 			newLogicModule, newProperties = c.cloneLogicModule(origModule)
    977 		}
    978 
    979 		newVariant := origModule.variant.clone()
    980 		newVariant[mutatorName] = variationName
    981 
    982 		m := *origModule
    983 		newModule := &m
    984 		newModule.directDeps = append([]depInfo{}, origModule.directDeps...)
    985 		newModule.logicModule = newLogicModule
    986 		newModule.variant = newVariant
    987 		newModule.dependencyVariant = origModule.dependencyVariant.clone()
    988 		newModule.moduleProperties = newProperties
    989 
    990 		if variationName != "" {
    991 			if newModule.variantName == "" {
    992 				newModule.variantName = variationName
    993 			} else {
    994 				newModule.variantName += "_" + variationName
    995 			}
    996 		}
    997 
    998 		newModules = append(newModules, newModule)
    999 
   1000 		newErrs := c.convertDepsToVariation(newModule, mutatorName, variationName)
   1001 		if len(newErrs) > 0 {
   1002 			errs = append(errs, newErrs...)
   1003 		}
   1004 	}
   1005 
   1006 	// Mark original variant as invalid.  Modules that depend on this module will still
   1007 	// depend on origModule, but we'll fix it when the mutator is called on them.
   1008 	origModule.logicModule = nil
   1009 	origModule.splitModules = newModules
   1010 
   1011 	atomic.AddUint32(&c.depsModified, 1)
   1012 
   1013 	return newModules, errs
   1014 }
   1015 
   1016 func (c *Context) convertDepsToVariation(module *moduleInfo,
   1017 	mutatorName, variationName string) (errs []error) {
   1018 
   1019 	for i, dep := range module.directDeps {
   1020 		if dep.module.logicModule == nil {
   1021 			var newDep *moduleInfo
   1022 			for _, m := range dep.module.splitModules {
   1023 				if m.variant[mutatorName] == variationName {
   1024 					newDep = m
   1025 					break
   1026 				}
   1027 			}
   1028 			if newDep == nil {
   1029 				errs = append(errs, &BlueprintError{
   1030 					Err: fmt.Errorf("failed to find variation %q for module %q needed by %q",
   1031 						variationName, dep.module.Name(), module.Name()),
   1032 					Pos: module.pos,
   1033 				})
   1034 				continue
   1035 			}
   1036 			module.directDeps[i].module = newDep
   1037 		}
   1038 	}
   1039 
   1040 	return errs
   1041 }
   1042 
   1043 func (c *Context) prettyPrintVariant(variant variationMap) string {
   1044 	names := make([]string, 0, len(variant))
   1045 	for _, m := range c.variantMutatorNames {
   1046 		if v, ok := variant[m]; ok {
   1047 			names = append(names, m+":"+v)
   1048 		}
   1049 	}
   1050 
   1051 	return strings.Join(names, ", ")
   1052 }
   1053 
   1054 func (c *Context) processModuleDef(moduleDef *parser.Module,
   1055 	relBlueprintsFile string) (*moduleInfo, []error) {
   1056 
   1057 	factory, ok := c.moduleFactories[moduleDef.Type]
   1058 	if !ok {
   1059 		if c.ignoreUnknownModuleTypes {
   1060 			return nil, nil
   1061 		}
   1062 
   1063 		return nil, []error{
   1064 			&BlueprintError{
   1065 				Err: fmt.Errorf("unrecognized module type %q", moduleDef.Type),
   1066 				Pos: moduleDef.TypePos,
   1067 			},
   1068 		}
   1069 	}
   1070 
   1071 	logicModule, properties := factory()
   1072 
   1073 	module := &moduleInfo{
   1074 		logicModule:       logicModule,
   1075 		typeName:          moduleDef.Type,
   1076 		relBlueprintsFile: relBlueprintsFile,
   1077 	}
   1078 
   1079 	module.moduleProperties = properties
   1080 
   1081 	propertyMap, errs := unpackProperties(moduleDef.Properties, properties...)
   1082 	if len(errs) > 0 {
   1083 		return nil, errs
   1084 	}
   1085 
   1086 	module.pos = moduleDef.TypePos
   1087 	module.propertyPos = make(map[string]scanner.Position)
   1088 	for name, propertyDef := range propertyMap {
   1089 		module.propertyPos[name] = propertyDef.ColonPos
   1090 	}
   1091 
   1092 	return module, nil
   1093 }
   1094 
   1095 func (c *Context) addModule(module *moduleInfo) []error {
   1096 	name := module.logicModule.Name()
   1097 	c.moduleInfo[module.logicModule] = module
   1098 
   1099 	if group, present := c.moduleNames[name]; present {
   1100 		return []error{
   1101 			&BlueprintError{
   1102 				Err: fmt.Errorf("module %q already defined", name),
   1103 				Pos: module.pos,
   1104 			},
   1105 			&BlueprintError{
   1106 				Err: fmt.Errorf("<-- previous definition here"),
   1107 				Pos: group.modules[0].pos,
   1108 			},
   1109 		}
   1110 	}
   1111 
   1112 	ninjaName := toNinjaName(name)
   1113 
   1114 	// The sanitizing in toNinjaName can result in collisions, uniquify the name if it
   1115 	// already exists
   1116 	for i := 0; c.moduleNinjaNames[ninjaName] != nil; i++ {
   1117 		ninjaName = toNinjaName(name) + strconv.Itoa(i)
   1118 	}
   1119 
   1120 	group := &moduleGroup{
   1121 		name:      name,
   1122 		ninjaName: ninjaName,
   1123 		modules:   []*moduleInfo{module},
   1124 	}
   1125 	module.group = group
   1126 	c.moduleNames[name] = group
   1127 	c.moduleNinjaNames[ninjaName] = group
   1128 	c.moduleGroups = append(c.moduleGroups, group)
   1129 
   1130 	return nil
   1131 }
   1132 
   1133 // ResolveDependencies checks that the dependencies specified by all of the
   1134 // modules defined in the parsed Blueprints files are valid.  This means that
   1135 // the modules depended upon are defined and that no circular dependencies
   1136 // exist.
   1137 func (c *Context) ResolveDependencies(config interface{}) []error {
   1138 	errs := c.updateDependencies()
   1139 	if len(errs) > 0 {
   1140 		return errs
   1141 	}
   1142 
   1143 	errs = c.runMutators(config)
   1144 	if len(errs) > 0 {
   1145 		return errs
   1146 	}
   1147 
   1148 	c.cloneModules()
   1149 
   1150 	c.dependenciesReady = true
   1151 	return nil
   1152 }
   1153 
   1154 // Default dependencies handling.  If the module implements the (deprecated)
   1155 // DynamicDependerModule interface then this set consists of the union of those
   1156 // module names returned by its DynamicDependencies method and those added by calling
   1157 // AddDependencies or AddVariationDependencies on DynamicDependencyModuleContext.
   1158 func blueprintDepsMutator(ctx BottomUpMutatorContext) {
   1159 	if dynamicDepender, ok := ctx.Module().(DynamicDependerModule); ok {
   1160 		func() {
   1161 			defer func() {
   1162 				if r := recover(); r != nil {
   1163 					ctx.error(newPanicErrorf(r, "DynamicDependencies for %s", ctx.moduleInfo()))
   1164 				}
   1165 			}()
   1166 			dynamicDeps := dynamicDepender.DynamicDependencies(ctx)
   1167 
   1168 			if ctx.Failed() {
   1169 				return
   1170 			}
   1171 
   1172 			ctx.AddDependency(ctx.Module(), nil, dynamicDeps...)
   1173 		}()
   1174 	}
   1175 }
   1176 
   1177 // findMatchingVariant searches the moduleGroup for a module with the same variant as module,
   1178 // and returns the matching module, or nil if one is not found.
   1179 func (c *Context) findMatchingVariant(module *moduleInfo, possible []*moduleInfo) *moduleInfo {
   1180 	if len(possible) == 1 {
   1181 		return possible[0]
   1182 	} else {
   1183 		for _, m := range possible {
   1184 			if m.variant.equal(module.dependencyVariant) {
   1185 				return m
   1186 			}
   1187 		}
   1188 	}
   1189 
   1190 	return nil
   1191 }
   1192 
   1193 func (c *Context) addDependency(module *moduleInfo, tag DependencyTag, depName string) []error {
   1194 	if _, ok := tag.(BaseDependencyTag); ok {
   1195 		panic("BaseDependencyTag is not allowed to be used directly!")
   1196 	}
   1197 
   1198 	if depName == module.Name() {
   1199 		return []error{&BlueprintError{
   1200 			Err: fmt.Errorf("%q depends on itself", depName),
   1201 			Pos: module.pos,
   1202 		}}
   1203 	}
   1204 
   1205 	possibleDeps := c.modulesFromName(depName)
   1206 	if possibleDeps == nil {
   1207 		if c.allowMissingDependencies {
   1208 			module.missingDeps = append(module.missingDeps, depName)
   1209 			return nil
   1210 		}
   1211 		return []error{&BlueprintError{
   1212 			Err: fmt.Errorf("%q depends on undefined module %q",
   1213 				module.Name(), depName),
   1214 			Pos: module.pos,
   1215 		}}
   1216 	}
   1217 
   1218 	if m := c.findMatchingVariant(module, possibleDeps); m != nil {
   1219 		for _, dep := range module.directDeps {
   1220 			if m == dep.module {
   1221 				// TODO(ccross): what if adding a dependency with a different tag?
   1222 				return nil
   1223 			}
   1224 		}
   1225 		module.directDeps = append(module.directDeps, depInfo{m, tag})
   1226 		atomic.AddUint32(&c.depsModified, 1)
   1227 		return nil
   1228 	}
   1229 
   1230 	variants := make([]string, len(possibleDeps))
   1231 	for i, mod := range possibleDeps {
   1232 		variants[i] = c.prettyPrintVariant(mod.variant)
   1233 	}
   1234 	sort.Strings(variants)
   1235 
   1236 	return []error{&BlueprintError{
   1237 		Err: fmt.Errorf("dependency %q of %q missing variant:\n  %s\navailable variants:\n  %s",
   1238 			depName, module.Name(),
   1239 			c.prettyPrintVariant(module.dependencyVariant),
   1240 			strings.Join(variants, "\n  ")),
   1241 		Pos: module.pos,
   1242 	}}
   1243 }
   1244 
   1245 func (c *Context) findReverseDependency(module *moduleInfo, destName string) (*moduleInfo, []error) {
   1246 	if destName == module.Name() {
   1247 		return nil, []error{&BlueprintError{
   1248 			Err: fmt.Errorf("%q depends on itself", destName),
   1249 			Pos: module.pos,
   1250 		}}
   1251 	}
   1252 
   1253 	possibleDeps := c.modulesFromName(destName)
   1254 	if possibleDeps == nil {
   1255 		return nil, []error{&BlueprintError{
   1256 			Err: fmt.Errorf("%q has a reverse dependency on undefined module %q",
   1257 				module.Name(), destName),
   1258 			Pos: module.pos,
   1259 		}}
   1260 	}
   1261 
   1262 	if m := c.findMatchingVariant(module, possibleDeps); m != nil {
   1263 		return m, nil
   1264 	}
   1265 
   1266 	variants := make([]string, len(possibleDeps))
   1267 	for i, mod := range possibleDeps {
   1268 		variants[i] = c.prettyPrintVariant(mod.variant)
   1269 	}
   1270 	sort.Strings(variants)
   1271 
   1272 	return nil, []error{&BlueprintError{
   1273 		Err: fmt.Errorf("reverse dependency %q of %q missing variant:\n  %s\navailable variants:\n  %s",
   1274 			destName, module.Name(),
   1275 			c.prettyPrintVariant(module.dependencyVariant),
   1276 			strings.Join(variants, "\n  ")),
   1277 		Pos: module.pos,
   1278 	}}
   1279 }
   1280 
   1281 func (c *Context) addVariationDependency(module *moduleInfo, variations []Variation,
   1282 	tag DependencyTag, depName string, far bool) []error {
   1283 	if _, ok := tag.(BaseDependencyTag); ok {
   1284 		panic("BaseDependencyTag is not allowed to be used directly!")
   1285 	}
   1286 
   1287 	possibleDeps := c.modulesFromName(depName)
   1288 	if possibleDeps == nil {
   1289 		if c.allowMissingDependencies {
   1290 			module.missingDeps = append(module.missingDeps, depName)
   1291 			return nil
   1292 		}
   1293 		return []error{&BlueprintError{
   1294 			Err: fmt.Errorf("%q depends on undefined module %q",
   1295 				module.Name(), depName),
   1296 			Pos: module.pos,
   1297 		}}
   1298 	}
   1299 
   1300 	// We can't just append variant.Variant to module.dependencyVariants.variantName and
   1301 	// compare the strings because the result won't be in mutator registration order.
   1302 	// Create a new map instead, and then deep compare the maps.
   1303 	var newVariant variationMap
   1304 	if !far {
   1305 		newVariant = module.dependencyVariant.clone()
   1306 	} else {
   1307 		newVariant = make(variationMap)
   1308 	}
   1309 	for _, v := range variations {
   1310 		newVariant[v.Mutator] = v.Variation
   1311 	}
   1312 
   1313 	for _, m := range possibleDeps {
   1314 		var found bool
   1315 		if far {
   1316 			found = m.variant.subset(newVariant)
   1317 		} else {
   1318 			found = m.variant.equal(newVariant)
   1319 		}
   1320 		if found {
   1321 			if module == m {
   1322 				return []error{&BlueprintError{
   1323 					Err: fmt.Errorf("%q depends on itself", depName),
   1324 					Pos: module.pos,
   1325 				}}
   1326 			}
   1327 			// AddVariationDependency allows adding a dependency on itself, but only if
   1328 			// that module is earlier in the module list than this one, since we always
   1329 			// run GenerateBuildActions in order for the variants of a module
   1330 			if m.group == module.group && beforeInModuleList(module, m, module.group.modules) {
   1331 				return []error{&BlueprintError{
   1332 					Err: fmt.Errorf("%q depends on later version of itself", depName),
   1333 					Pos: module.pos,
   1334 				}}
   1335 			}
   1336 			module.directDeps = append(module.directDeps, depInfo{m, tag})
   1337 			atomic.AddUint32(&c.depsModified, 1)
   1338 			return nil
   1339 		}
   1340 	}
   1341 
   1342 	variants := make([]string, len(possibleDeps))
   1343 	for i, mod := range possibleDeps {
   1344 		variants[i] = c.prettyPrintVariant(mod.variant)
   1345 	}
   1346 	sort.Strings(variants)
   1347 
   1348 	return []error{&BlueprintError{
   1349 		Err: fmt.Errorf("dependency %q of %q missing variant:\n  %s\navailable variants:\n  %s",
   1350 			depName, module.Name(),
   1351 			c.prettyPrintVariant(newVariant),
   1352 			strings.Join(variants, "\n  ")),
   1353 		Pos: module.pos,
   1354 	}}
   1355 }
   1356 
   1357 func (c *Context) addInterVariantDependency(origModule *moduleInfo, tag DependencyTag,
   1358 	from, to Module) {
   1359 	if _, ok := tag.(BaseDependencyTag); ok {
   1360 		panic("BaseDependencyTag is not allowed to be used directly!")
   1361 	}
   1362 
   1363 	var fromInfo, toInfo *moduleInfo
   1364 	for _, m := range origModule.splitModules {
   1365 		if m.logicModule == from {
   1366 			fromInfo = m
   1367 		}
   1368 		if m.logicModule == to {
   1369 			toInfo = m
   1370 			if fromInfo != nil {
   1371 				panic(fmt.Errorf("%q depends on later version of itself", origModule.Name()))
   1372 			}
   1373 		}
   1374 	}
   1375 
   1376 	if fromInfo == nil || toInfo == nil {
   1377 		panic(fmt.Errorf("AddInterVariantDependency called for module %q on invalid variant",
   1378 			origModule.Name()))
   1379 	}
   1380 
   1381 	fromInfo.directDeps = append(fromInfo.directDeps, depInfo{toInfo, tag})
   1382 	atomic.AddUint32(&c.depsModified, 1)
   1383 }
   1384 
   1385 type visitOrderer interface {
   1386 	// returns the number of modules that this module needs to wait for
   1387 	waitCount(module *moduleInfo) int
   1388 	// returns the list of modules that are waiting for this module
   1389 	propagate(module *moduleInfo) []*moduleInfo
   1390 	// visit modules in order
   1391 	visit(modules []*moduleInfo, visit func(*moduleInfo) bool)
   1392 }
   1393 
   1394 type bottomUpVisitorImpl struct{}
   1395 
   1396 func (bottomUpVisitorImpl) waitCount(module *moduleInfo) int {
   1397 	return len(module.forwardDeps)
   1398 }
   1399 
   1400 func (bottomUpVisitorImpl) propagate(module *moduleInfo) []*moduleInfo {
   1401 	return module.reverseDeps
   1402 }
   1403 
   1404 func (bottomUpVisitorImpl) visit(modules []*moduleInfo, visit func(*moduleInfo) bool) {
   1405 	for _, module := range modules {
   1406 		if visit(module) {
   1407 			return
   1408 		}
   1409 	}
   1410 }
   1411 
   1412 type topDownVisitorImpl struct{}
   1413 
   1414 func (topDownVisitorImpl) waitCount(module *moduleInfo) int {
   1415 	return len(module.reverseDeps)
   1416 }
   1417 
   1418 func (topDownVisitorImpl) propagate(module *moduleInfo) []*moduleInfo {
   1419 	return module.forwardDeps
   1420 }
   1421 
   1422 func (topDownVisitorImpl) visit(modules []*moduleInfo, visit func(*moduleInfo) bool) {
   1423 	for i := 0; i < len(modules); i++ {
   1424 		module := modules[len(modules)-1-i]
   1425 		if visit(module) {
   1426 			return
   1427 		}
   1428 	}
   1429 }
   1430 
   1431 var (
   1432 	bottomUpVisitor bottomUpVisitorImpl
   1433 	topDownVisitor  topDownVisitorImpl
   1434 )
   1435 
   1436 // Calls visit on each module, guaranteeing that visit is not called on a module until visit on all
   1437 // of its dependencies has finished.
   1438 func (c *Context) parallelVisit(order visitOrderer, visit func(group *moduleInfo) bool) {
   1439 	doneCh := make(chan *moduleInfo)
   1440 	cancelCh := make(chan bool)
   1441 	count := 0
   1442 	cancel := false
   1443 
   1444 	for _, module := range c.modulesSorted {
   1445 		module.waitingCount = order.waitCount(module)
   1446 	}
   1447 
   1448 	visitOne := func(module *moduleInfo) {
   1449 		count++
   1450 		go func() {
   1451 			ret := visit(module)
   1452 			if ret {
   1453 				cancelCh <- true
   1454 			}
   1455 			doneCh <- module
   1456 		}()
   1457 	}
   1458 
   1459 	for _, module := range c.modulesSorted {
   1460 		if module.waitingCount == 0 {
   1461 			visitOne(module)
   1462 		}
   1463 	}
   1464 
   1465 	for count > 0 {
   1466 		select {
   1467 		case cancel = <-cancelCh:
   1468 		case doneModule := <-doneCh:
   1469 			if !cancel {
   1470 				for _, module := range order.propagate(doneModule) {
   1471 					module.waitingCount--
   1472 					if module.waitingCount == 0 {
   1473 						visitOne(module)
   1474 					}
   1475 				}
   1476 			}
   1477 			count--
   1478 		}
   1479 	}
   1480 }
   1481 
   1482 // updateDependencies recursively walks the module dependency graph and updates
   1483 // additional fields based on the dependencies.  It builds a sorted list of modules
   1484 // such that dependencies of a module always appear first, and populates reverse
   1485 // dependency links and counts of total dependencies.  It also reports errors when
   1486 // it encounters dependency cycles.  This should called after resolveDependencies,
   1487 // as well as after any mutator pass has called addDependency
   1488 func (c *Context) updateDependencies() (errs []error) {
   1489 	visited := make(map[*moduleInfo]bool)  // modules that were already checked
   1490 	checking := make(map[*moduleInfo]bool) // modules actively being checked
   1491 
   1492 	sorted := make([]*moduleInfo, 0, len(c.moduleInfo))
   1493 
   1494 	var check func(group *moduleInfo) []*moduleInfo
   1495 
   1496 	cycleError := func(cycle []*moduleInfo) {
   1497 		// We are the "start" of the cycle, so we're responsible
   1498 		// for generating the errors.  The cycle list is in
   1499 		// reverse order because all the 'check' calls append
   1500 		// their own module to the list.
   1501 		errs = append(errs, &BlueprintError{
   1502 			Err: fmt.Errorf("encountered dependency cycle:"),
   1503 			Pos: cycle[len(cycle)-1].pos,
   1504 		})
   1505 
   1506 		// Iterate backwards through the cycle list.
   1507 		curModule := cycle[0]
   1508 		for i := len(cycle) - 1; i >= 0; i-- {
   1509 			nextModule := cycle[i]
   1510 			errs = append(errs, &BlueprintError{
   1511 				Err: fmt.Errorf("    %q depends on %q",
   1512 					curModule.Name(),
   1513 					nextModule.Name()),
   1514 				Pos: curModule.pos,
   1515 			})
   1516 			curModule = nextModule
   1517 		}
   1518 	}
   1519 
   1520 	check = func(module *moduleInfo) []*moduleInfo {
   1521 		visited[module] = true
   1522 		checking[module] = true
   1523 		defer delete(checking, module)
   1524 
   1525 		deps := make(map[*moduleInfo]bool)
   1526 
   1527 		// Add an implicit dependency ordering on all earlier modules in the same module group
   1528 		for _, dep := range module.group.modules {
   1529 			if dep == module {
   1530 				break
   1531 			}
   1532 			deps[dep] = true
   1533 		}
   1534 
   1535 		for _, dep := range module.directDeps {
   1536 			deps[dep.module] = true
   1537 		}
   1538 
   1539 		module.reverseDeps = []*moduleInfo{}
   1540 		module.forwardDeps = []*moduleInfo{}
   1541 
   1542 		for dep := range deps {
   1543 			if checking[dep] {
   1544 				// This is a cycle.
   1545 				return []*moduleInfo{dep, module}
   1546 			}
   1547 
   1548 			if !visited[dep] {
   1549 				cycle := check(dep)
   1550 				if cycle != nil {
   1551 					if cycle[0] == module {
   1552 						// We are the "start" of the cycle, so we're responsible
   1553 						// for generating the errors.  The cycle list is in
   1554 						// reverse order because all the 'check' calls append
   1555 						// their own module to the list.
   1556 						cycleError(cycle)
   1557 
   1558 						// We can continue processing this module's children to
   1559 						// find more cycles.  Since all the modules that were
   1560 						// part of the found cycle were marked as visited we
   1561 						// won't run into that cycle again.
   1562 					} else {
   1563 						// We're not the "start" of the cycle, so we just append
   1564 						// our module to the list and return it.
   1565 						return append(cycle, module)
   1566 					}
   1567 				}
   1568 			}
   1569 
   1570 			module.forwardDeps = append(module.forwardDeps, dep)
   1571 			dep.reverseDeps = append(dep.reverseDeps, module)
   1572 		}
   1573 
   1574 		sorted = append(sorted, module)
   1575 
   1576 		return nil
   1577 	}
   1578 
   1579 	for _, module := range c.moduleInfo {
   1580 		if !visited[module] {
   1581 			cycle := check(module)
   1582 			if cycle != nil {
   1583 				if cycle[len(cycle)-1] != module {
   1584 					panic("inconceivable!")
   1585 				}
   1586 				cycleError(cycle)
   1587 			}
   1588 		}
   1589 	}
   1590 
   1591 	c.modulesSorted = sorted
   1592 
   1593 	return
   1594 }
   1595 
   1596 // PrepareBuildActions generates an internal representation of all the build
   1597 // actions that need to be performed.  This process involves invoking the
   1598 // GenerateBuildActions method on each of the Module objects created during the
   1599 // parse phase and then on each of the registered Singleton objects.
   1600 //
   1601 // If the ResolveDependencies method has not already been called it is called
   1602 // automatically by this method.
   1603 //
   1604 // The config argument is made available to all of the Module and Singleton
   1605 // objects via the Config method on the ModuleContext and SingletonContext
   1606 // objects passed to GenerateBuildActions.  It is also passed to the functions
   1607 // specified via PoolFunc, RuleFunc, and VariableFunc so that they can compute
   1608 // config-specific values.
   1609 //
   1610 // The returned deps is a list of the ninja files dependencies that were added
   1611 // by the modules and singletons via the ModuleContext.AddNinjaFileDeps(),
   1612 // SingletonContext.AddNinjaFileDeps(), and PackageContext.AddNinjaFileDeps()
   1613 // methods.
   1614 func (c *Context) PrepareBuildActions(config interface{}) (deps []string, errs []error) {
   1615 	c.buildActionsReady = false
   1616 
   1617 	if !c.dependenciesReady {
   1618 		errs := c.ResolveDependencies(config)
   1619 		if len(errs) > 0 {
   1620 			return nil, errs
   1621 		}
   1622 	}
   1623 
   1624 	liveGlobals := newLiveTracker(config)
   1625 
   1626 	c.initSpecialVariables()
   1627 
   1628 	depsModules, errs := c.generateModuleBuildActions(config, liveGlobals)
   1629 	if len(errs) > 0 {
   1630 		return nil, errs
   1631 	}
   1632 
   1633 	depsSingletons, errs := c.generateSingletonBuildActions(config, liveGlobals)
   1634 	if len(errs) > 0 {
   1635 		return nil, errs
   1636 	}
   1637 
   1638 	deps = append(depsModules, depsSingletons...)
   1639 
   1640 	if c.ninjaBuildDir != nil {
   1641 		liveGlobals.addNinjaStringDeps(c.ninjaBuildDir)
   1642 	}
   1643 
   1644 	pkgNames, depsPackages := c.makeUniquePackageNames(liveGlobals)
   1645 
   1646 	deps = append(deps, depsPackages...)
   1647 
   1648 	// This will panic if it finds a problem since it's a programming error.
   1649 	c.checkForVariableReferenceCycles(liveGlobals.variables, pkgNames)
   1650 
   1651 	c.pkgNames = pkgNames
   1652 	c.globalVariables = liveGlobals.variables
   1653 	c.globalPools = liveGlobals.pools
   1654 	c.globalRules = liveGlobals.rules
   1655 
   1656 	c.buildActionsReady = true
   1657 
   1658 	return deps, nil
   1659 }
   1660 
   1661 func (c *Context) runMutators(config interface{}) (errs []error) {
   1662 	var mutators []*mutatorInfo
   1663 
   1664 	mutators = append(mutators, c.earlyMutatorInfo...)
   1665 	mutators = append(mutators, c.mutatorInfo...)
   1666 
   1667 	for _, mutator := range mutators {
   1668 		if mutator.topDownMutator != nil {
   1669 			errs = c.runMutator(config, mutator, topDownMutator)
   1670 		} else if mutator.bottomUpMutator != nil {
   1671 			errs = c.runMutator(config, mutator, bottomUpMutator)
   1672 		} else {
   1673 			panic("no mutator set on " + mutator.name)
   1674 		}
   1675 		if len(errs) > 0 {
   1676 			return errs
   1677 		}
   1678 	}
   1679 
   1680 	return nil
   1681 }
   1682 
   1683 type mutatorDirection interface {
   1684 	run(mutator *mutatorInfo, ctx *mutatorContext)
   1685 	orderer() visitOrderer
   1686 	fmt.Stringer
   1687 }
   1688 
   1689 type bottomUpMutatorImpl struct{}
   1690 
   1691 func (bottomUpMutatorImpl) run(mutator *mutatorInfo, ctx *mutatorContext) {
   1692 	mutator.bottomUpMutator(ctx)
   1693 }
   1694 
   1695 func (bottomUpMutatorImpl) orderer() visitOrderer {
   1696 	return bottomUpVisitor
   1697 }
   1698 
   1699 func (bottomUpMutatorImpl) String() string {
   1700 	return "bottom up mutator"
   1701 }
   1702 
   1703 type topDownMutatorImpl struct{}
   1704 
   1705 func (topDownMutatorImpl) run(mutator *mutatorInfo, ctx *mutatorContext) {
   1706 	mutator.topDownMutator(ctx)
   1707 }
   1708 
   1709 func (topDownMutatorImpl) orderer() visitOrderer {
   1710 	return topDownVisitor
   1711 }
   1712 
   1713 func (topDownMutatorImpl) String() string {
   1714 	return "top down mutator"
   1715 }
   1716 
   1717 var (
   1718 	topDownMutator  topDownMutatorImpl
   1719 	bottomUpMutator bottomUpMutatorImpl
   1720 )
   1721 
   1722 type reverseDep struct {
   1723 	module *moduleInfo
   1724 	dep    depInfo
   1725 }
   1726 
   1727 func (c *Context) runMutator(config interface{}, mutator *mutatorInfo,
   1728 	direction mutatorDirection) (errs []error) {
   1729 
   1730 	newModuleInfo := make(map[Module]*moduleInfo)
   1731 	for k, v := range c.moduleInfo {
   1732 		newModuleInfo[k] = v
   1733 	}
   1734 
   1735 	type globalStateChange struct {
   1736 		reverse []reverseDep
   1737 		rename  []rename
   1738 		replace []replace
   1739 	}
   1740 
   1741 	reverseDeps := make(map[*moduleInfo][]depInfo)
   1742 	var rename []rename
   1743 	var replace []replace
   1744 
   1745 	errsCh := make(chan []error)
   1746 	globalStateCh := make(chan globalStateChange)
   1747 	newModulesCh := make(chan []*moduleInfo)
   1748 	done := make(chan bool)
   1749 
   1750 	c.depsModified = 0
   1751 
   1752 	visit := func(module *moduleInfo) bool {
   1753 		if module.splitModules != nil {
   1754 			panic("split module found in sorted module list")
   1755 		}
   1756 
   1757 		mctx := &mutatorContext{
   1758 			baseModuleContext: baseModuleContext{
   1759 				context: c,
   1760 				config:  config,
   1761 				module:  module,
   1762 			},
   1763 			name: mutator.name,
   1764 		}
   1765 
   1766 		func() {
   1767 			defer func() {
   1768 				if r := recover(); r != nil {
   1769 					in := fmt.Sprintf("%s %q for %s", direction, mutator.name, module)
   1770 					if err, ok := r.(panicError); ok {
   1771 						err.addIn(in)
   1772 						mctx.error(err)
   1773 					} else {
   1774 						mctx.error(newPanicErrorf(r, in))
   1775 					}
   1776 				}
   1777 			}()
   1778 			direction.run(mutator, mctx)
   1779 		}()
   1780 
   1781 		if len(mctx.errs) > 0 {
   1782 			errsCh <- mctx.errs
   1783 			return true
   1784 		}
   1785 
   1786 		if len(mctx.newModules) > 0 {
   1787 			newModulesCh <- mctx.newModules
   1788 		}
   1789 
   1790 		if len(mctx.reverseDeps) > 0 || len(mctx.replace) > 0 || len(mctx.rename) > 0 {
   1791 			globalStateCh <- globalStateChange{
   1792 				reverse: mctx.reverseDeps,
   1793 				replace: mctx.replace,
   1794 				rename:  mctx.rename,
   1795 			}
   1796 		}
   1797 
   1798 		return false
   1799 	}
   1800 
   1801 	// Process errs and reverseDeps in a single goroutine
   1802 	go func() {
   1803 		for {
   1804 			select {
   1805 			case newErrs := <-errsCh:
   1806 				errs = append(errs, newErrs...)
   1807 			case globalStateChange := <-globalStateCh:
   1808 				for _, r := range globalStateChange.reverse {
   1809 					reverseDeps[r.module] = append(reverseDeps[r.module], r.dep)
   1810 				}
   1811 				replace = append(replace, globalStateChange.replace...)
   1812 				rename = append(rename, globalStateChange.rename...)
   1813 			case newModules := <-newModulesCh:
   1814 				for _, m := range newModules {
   1815 					newModuleInfo[m.logicModule] = m
   1816 				}
   1817 			case <-done:
   1818 				return
   1819 			}
   1820 		}
   1821 	}()
   1822 
   1823 	if mutator.parallel {
   1824 		c.parallelVisit(direction.orderer(), visit)
   1825 	} else {
   1826 		direction.orderer().visit(c.modulesSorted, visit)
   1827 	}
   1828 
   1829 	done <- true
   1830 
   1831 	if len(errs) > 0 {
   1832 		return errs
   1833 	}
   1834 
   1835 	c.moduleInfo = newModuleInfo
   1836 
   1837 	for _, group := range c.moduleGroups {
   1838 		for i := 0; i < len(group.modules); i++ {
   1839 			module := group.modules[i]
   1840 
   1841 			// Update module group to contain newly split variants
   1842 			if module.splitModules != nil {
   1843 				group.modules, i = spliceModules(group.modules, i, module.splitModules)
   1844 			}
   1845 
   1846 			// Fix up any remaining dependencies on modules that were split into variants
   1847 			// by replacing them with the first variant
   1848 			for j, dep := range module.directDeps {
   1849 				if dep.module.logicModule == nil {
   1850 					module.directDeps[j].module = dep.module.splitModules[0]
   1851 				}
   1852 			}
   1853 		}
   1854 	}
   1855 
   1856 	for module, deps := range reverseDeps {
   1857 		sort.Sort(depSorter(deps))
   1858 		module.directDeps = append(module.directDeps, deps...)
   1859 		c.depsModified++
   1860 	}
   1861 
   1862 	errs = c.handleRenames(rename)
   1863 	if len(errs) > 0 {
   1864 		return errs
   1865 	}
   1866 
   1867 	errs = c.handleReplacements(replace)
   1868 	if len(errs) > 0 {
   1869 		return errs
   1870 	}
   1871 
   1872 	if c.depsModified > 0 {
   1873 		errs = c.updateDependencies()
   1874 		if len(errs) > 0 {
   1875 			return errs
   1876 		}
   1877 	}
   1878 
   1879 	return errs
   1880 }
   1881 
   1882 // Replaces every build logic module with a clone of itself.  Prevents introducing problems where
   1883 // a mutator sets a non-property member variable on a module, which works until a later mutator
   1884 // creates variants of that module.
   1885 func (c *Context) cloneModules() {
   1886 	type update struct {
   1887 		orig  Module
   1888 		clone *moduleInfo
   1889 	}
   1890 	ch := make(chan update, 100)
   1891 
   1892 	for _, m := range c.modulesSorted {
   1893 		go func(m *moduleInfo) {
   1894 			origLogicModule := m.logicModule
   1895 			m.logicModule, m.moduleProperties = c.cloneLogicModule(m)
   1896 			ch <- update{origLogicModule, m}
   1897 		}(m)
   1898 	}
   1899 
   1900 	for i := 0; i < len(c.modulesSorted); i++ {
   1901 		update := <-ch
   1902 		delete(c.moduleInfo, update.orig)
   1903 		c.moduleInfo[update.clone.logicModule] = update.clone
   1904 	}
   1905 }
   1906 
   1907 // Removes modules[i] from the list and inserts newModules... where it was located, returning
   1908 // the new slice and the index of the last inserted element
   1909 func spliceModules(modules []*moduleInfo, i int, newModules []*moduleInfo) ([]*moduleInfo, int) {
   1910 	spliceSize := len(newModules)
   1911 	newLen := len(modules) + spliceSize - 1
   1912 	var dest []*moduleInfo
   1913 	if cap(modules) >= len(modules)-1+len(newModules) {
   1914 		// We can fit the splice in the existing capacity, do everything in place
   1915 		dest = modules[:newLen]
   1916 	} else {
   1917 		dest = make([]*moduleInfo, newLen)
   1918 		copy(dest, modules[:i])
   1919 	}
   1920 
   1921 	// Move the end of the slice over by spliceSize-1
   1922 	copy(dest[i+spliceSize:], modules[i+1:])
   1923 
   1924 	// Copy the new modules into the slice
   1925 	copy(dest[i:], newModules)
   1926 
   1927 	return dest, i + spliceSize - 1
   1928 }
   1929 
   1930 func (c *Context) initSpecialVariables() {
   1931 	c.ninjaBuildDir = nil
   1932 	c.requiredNinjaMajor = 1
   1933 	c.requiredNinjaMinor = 7
   1934 	c.requiredNinjaMicro = 0
   1935 }
   1936 
   1937 func (c *Context) generateModuleBuildActions(config interface{},
   1938 	liveGlobals *liveTracker) ([]string, []error) {
   1939 
   1940 	var deps []string
   1941 	var errs []error
   1942 
   1943 	cancelCh := make(chan struct{})
   1944 	errsCh := make(chan []error)
   1945 	depsCh := make(chan []string)
   1946 
   1947 	go func() {
   1948 		for {
   1949 			select {
   1950 			case <-cancelCh:
   1951 				close(cancelCh)
   1952 				return
   1953 			case newErrs := <-errsCh:
   1954 				errs = append(errs, newErrs...)
   1955 			case newDeps := <-depsCh:
   1956 				deps = append(deps, newDeps...)
   1957 
   1958 			}
   1959 		}
   1960 	}()
   1961 
   1962 	c.parallelVisit(bottomUpVisitor, func(module *moduleInfo) bool {
   1963 		// The parent scope of the moduleContext's local scope gets overridden to be that of the
   1964 		// calling Go package on a per-call basis.  Since the initial parent scope doesn't matter we
   1965 		// just set it to nil.
   1966 		prefix := moduleNamespacePrefix(module.group.ninjaName + "_" + module.variantName)
   1967 		scope := newLocalScope(nil, prefix)
   1968 
   1969 		mctx := &moduleContext{
   1970 			baseModuleContext: baseModuleContext{
   1971 				context: c,
   1972 				config:  config,
   1973 				module:  module,
   1974 			},
   1975 			scope:              scope,
   1976 			handledMissingDeps: module.missingDeps == nil,
   1977 		}
   1978 
   1979 		func() {
   1980 			defer func() {
   1981 				if r := recover(); r != nil {
   1982 					in := fmt.Sprintf("GenerateBuildActions for %s", module)
   1983 					if err, ok := r.(panicError); ok {
   1984 						err.addIn(in)
   1985 						mctx.error(err)
   1986 					} else {
   1987 						mctx.error(newPanicErrorf(r, in))
   1988 					}
   1989 				}
   1990 			}()
   1991 			mctx.module.logicModule.GenerateBuildActions(mctx)
   1992 		}()
   1993 
   1994 		if len(mctx.errs) > 0 {
   1995 			errsCh <- mctx.errs
   1996 			return true
   1997 		}
   1998 
   1999 		if module.missingDeps != nil && !mctx.handledMissingDeps {
   2000 			var errs []error
   2001 			for _, depName := range module.missingDeps {
   2002 				errs = append(errs, &BlueprintError{
   2003 					Err: fmt.Errorf("%q depends on undefined module %q",
   2004 						module.Name(), depName),
   2005 					Pos: module.pos,
   2006 				})
   2007 			}
   2008 			errsCh <- errs
   2009 			return true
   2010 		}
   2011 
   2012 		depsCh <- mctx.ninjaFileDeps
   2013 
   2014 		newErrs := c.processLocalBuildActions(&module.actionDefs,
   2015 			&mctx.actionDefs, liveGlobals)
   2016 		if len(newErrs) > 0 {
   2017 			errsCh <- newErrs
   2018 			return true
   2019 		}
   2020 		return false
   2021 	})
   2022 
   2023 	cancelCh <- struct{}{}
   2024 	<-cancelCh
   2025 
   2026 	return deps, errs
   2027 }
   2028 
   2029 func (c *Context) generateSingletonBuildActions(config interface{},
   2030 	liveGlobals *liveTracker) ([]string, []error) {
   2031 
   2032 	var deps []string
   2033 	var errs []error
   2034 
   2035 	for _, info := range c.singletonInfo {
   2036 		// The parent scope of the singletonContext's local scope gets overridden to be that of the
   2037 		// calling Go package on a per-call basis.  Since the initial parent scope doesn't matter we
   2038 		// just set it to nil.
   2039 		scope := newLocalScope(nil, singletonNamespacePrefix(info.name))
   2040 
   2041 		sctx := &singletonContext{
   2042 			context: c,
   2043 			config:  config,
   2044 			scope:   scope,
   2045 			globals: liveGlobals,
   2046 		}
   2047 
   2048 		func() {
   2049 			defer func() {
   2050 				if r := recover(); r != nil {
   2051 					in := fmt.Sprintf("GenerateBuildActions for singleton %s", info.name)
   2052 					if err, ok := r.(panicError); ok {
   2053 						err.addIn(in)
   2054 						sctx.error(err)
   2055 					} else {
   2056 						sctx.error(newPanicErrorf(r, in))
   2057 					}
   2058 				}
   2059 			}()
   2060 			info.singleton.GenerateBuildActions(sctx)
   2061 		}()
   2062 
   2063 		if len(sctx.errs) > 0 {
   2064 			errs = append(errs, sctx.errs...)
   2065 			if len(errs) > maxErrors {
   2066 				break
   2067 			}
   2068 			continue
   2069 		}
   2070 
   2071 		deps = append(deps, sctx.ninjaFileDeps...)
   2072 
   2073 		newErrs := c.processLocalBuildActions(&info.actionDefs,
   2074 			&sctx.actionDefs, liveGlobals)
   2075 		errs = append(errs, newErrs...)
   2076 		if len(errs) > maxErrors {
   2077 			break
   2078 		}
   2079 	}
   2080 
   2081 	return deps, errs
   2082 }
   2083 
   2084 func (c *Context) processLocalBuildActions(out, in *localBuildActions,
   2085 	liveGlobals *liveTracker) []error {
   2086 
   2087 	var errs []error
   2088 
   2089 	// First we go through and add everything referenced by the module's
   2090 	// buildDefs to the live globals set.  This will end up adding the live
   2091 	// locals to the set as well, but we'll take them out after.
   2092 	for _, def := range in.buildDefs {
   2093 		err := liveGlobals.AddBuildDefDeps(def)
   2094 		if err != nil {
   2095 			errs = append(errs, err)
   2096 		}
   2097 	}
   2098 
   2099 	if len(errs) > 0 {
   2100 		return errs
   2101 	}
   2102 
   2103 	out.buildDefs = append(out.buildDefs, in.buildDefs...)
   2104 
   2105 	// We use the now-incorrect set of live "globals" to determine which local
   2106 	// definitions are live.  As we go through copying those live locals to the
   2107 	// moduleGroup we remove them from the live globals set.
   2108 	for _, v := range in.variables {
   2109 		isLive := liveGlobals.RemoveVariableIfLive(v)
   2110 		if isLive {
   2111 			out.variables = append(out.variables, v)
   2112 		}
   2113 	}
   2114 
   2115 	for _, r := range in.rules {
   2116 		isLive := liveGlobals.RemoveRuleIfLive(r)
   2117 		if isLive {
   2118 			out.rules = append(out.rules, r)
   2119 		}
   2120 	}
   2121 
   2122 	return nil
   2123 }
   2124 
   2125 func (c *Context) walkDeps(topModule *moduleInfo,
   2126 	visitDown func(depInfo, *moduleInfo) bool, visitUp func(depInfo, *moduleInfo)) {
   2127 
   2128 	visited := make(map[*moduleInfo]bool)
   2129 	var visiting *moduleInfo
   2130 
   2131 	defer func() {
   2132 		if r := recover(); r != nil {
   2133 			panic(newPanicErrorf(r, "WalkDeps(%s, %s, %s) for dependency %s",
   2134 				topModule, funcName(visitDown), funcName(visitUp), visiting))
   2135 		}
   2136 	}()
   2137 
   2138 	var walk func(module *moduleInfo)
   2139 	walk = func(module *moduleInfo) {
   2140 		for _, dep := range module.directDeps {
   2141 			if !visited[dep.module] {
   2142 				visited[dep.module] = true
   2143 				visiting = dep.module
   2144 				recurse := true
   2145 				if visitDown != nil {
   2146 					recurse = visitDown(dep, module)
   2147 				}
   2148 				if recurse {
   2149 					walk(dep.module)
   2150 				}
   2151 				if visitUp != nil {
   2152 					visitUp(dep, module)
   2153 				}
   2154 			}
   2155 		}
   2156 	}
   2157 
   2158 	walk(topModule)
   2159 }
   2160 
   2161 type replace struct {
   2162 	from, to *moduleInfo
   2163 }
   2164 
   2165 type rename struct {
   2166 	group *moduleGroup
   2167 	name  string
   2168 }
   2169 
   2170 func (c *Context) moduleMatchingVariant(module *moduleInfo, name string) *moduleInfo {
   2171 	targets := c.modulesFromName(name)
   2172 
   2173 	if targets == nil {
   2174 		return nil
   2175 	}
   2176 
   2177 	for _, m := range targets {
   2178 		if module.variantName == m.variantName {
   2179 			return m
   2180 		}
   2181 	}
   2182 
   2183 	return nil
   2184 }
   2185 
   2186 func (c *Context) handleRenames(renames []rename) []error {
   2187 	var errs []error
   2188 	for _, rename := range renames {
   2189 		group, name := rename.group, rename.name
   2190 		if name == group.name {
   2191 			continue
   2192 		}
   2193 
   2194 		existing := c.moduleNames[name]
   2195 		if existing != nil {
   2196 			errs = append(errs,
   2197 				&BlueprintError{
   2198 					Err: fmt.Errorf("renaming module %q to %q conflicts with existing module",
   2199 						group.name, name),
   2200 					Pos: group.modules[0].pos,
   2201 				},
   2202 				&BlueprintError{
   2203 					Err: fmt.Errorf("<-- existing module defined here"),
   2204 					Pos: existing.modules[0].pos,
   2205 				},
   2206 			)
   2207 			continue
   2208 		}
   2209 
   2210 		c.moduleNames[name] = group
   2211 		delete(c.moduleNames, group.name)
   2212 		group.name = name
   2213 	}
   2214 
   2215 	return errs
   2216 }
   2217 
   2218 func (c *Context) handleReplacements(replacements []replace) []error {
   2219 	var errs []error
   2220 	for _, replace := range replacements {
   2221 		for _, m := range replace.from.reverseDeps {
   2222 			for i, d := range m.directDeps {
   2223 				if d.module == replace.from {
   2224 					m.directDeps[i].module = replace.to
   2225 				}
   2226 			}
   2227 		}
   2228 
   2229 		atomic.AddUint32(&c.depsModified, 1)
   2230 	}
   2231 
   2232 	return errs
   2233 }
   2234 
   2235 func (c *Context) modulesFromName(name string) []*moduleInfo {
   2236 	if group := c.moduleNames[name]; group != nil {
   2237 		return group.modules
   2238 	}
   2239 	return nil
   2240 }
   2241 
   2242 func (c *Context) sortedModuleNames() []string {
   2243 	if c.cachedSortedModuleNames == nil {
   2244 		c.cachedSortedModuleNames = make([]string, 0, len(c.moduleNames))
   2245 		for moduleName := range c.moduleNames {
   2246 			c.cachedSortedModuleNames = append(c.cachedSortedModuleNames,
   2247 				moduleName)
   2248 		}
   2249 		sort.Strings(c.cachedSortedModuleNames)
   2250 	}
   2251 
   2252 	return c.cachedSortedModuleNames
   2253 }
   2254 
   2255 func (c *Context) visitAllModules(visit func(Module)) {
   2256 	var module *moduleInfo
   2257 
   2258 	defer func() {
   2259 		if r := recover(); r != nil {
   2260 			panic(newPanicErrorf(r, "VisitAllModules(%s) for %s",
   2261 				funcName(visit), module))
   2262 		}
   2263 	}()
   2264 
   2265 	for _, moduleName := range c.sortedModuleNames() {
   2266 		modules := c.modulesFromName(moduleName)
   2267 		for _, module = range modules {
   2268 			visit(module.logicModule)
   2269 		}
   2270 	}
   2271 }
   2272 
   2273 func (c *Context) visitAllModulesIf(pred func(Module) bool,
   2274 	visit func(Module)) {
   2275 
   2276 	var module *moduleInfo
   2277 
   2278 	defer func() {
   2279 		if r := recover(); r != nil {
   2280 			panic(newPanicErrorf(r, "VisitAllModulesIf(%s, %s) for %s",
   2281 				funcName(pred), funcName(visit), module))
   2282 		}
   2283 	}()
   2284 
   2285 	for _, moduleName := range c.sortedModuleNames() {
   2286 		modules := c.modulesFromName(moduleName)
   2287 		for _, module := range modules {
   2288 			if pred(module.logicModule) {
   2289 				visit(module.logicModule)
   2290 			}
   2291 		}
   2292 	}
   2293 }
   2294 
   2295 func (c *Context) visitAllModuleVariants(module *moduleInfo,
   2296 	visit func(Module)) {
   2297 
   2298 	var variant *moduleInfo
   2299 
   2300 	defer func() {
   2301 		if r := recover(); r != nil {
   2302 			panic(newPanicErrorf(r, "VisitAllModuleVariants(%s, %s) for %s",
   2303 				module, funcName(visit), variant))
   2304 		}
   2305 	}()
   2306 
   2307 	for _, variant = range module.group.modules {
   2308 		visit(variant.logicModule)
   2309 	}
   2310 }
   2311 
   2312 func (c *Context) requireNinjaVersion(major, minor, micro int) {
   2313 	if major != 1 {
   2314 		panic("ninja version with major version != 1 not supported")
   2315 	}
   2316 	if c.requiredNinjaMinor < minor {
   2317 		c.requiredNinjaMinor = minor
   2318 		c.requiredNinjaMicro = micro
   2319 	}
   2320 	if c.requiredNinjaMinor == minor && c.requiredNinjaMicro < micro {
   2321 		c.requiredNinjaMicro = micro
   2322 	}
   2323 }
   2324 
   2325 func (c *Context) setNinjaBuildDir(value *ninjaString) {
   2326 	if c.ninjaBuildDir == nil {
   2327 		c.ninjaBuildDir = value
   2328 	}
   2329 }
   2330 
   2331 func (c *Context) makeUniquePackageNames(
   2332 	liveGlobals *liveTracker) (map[*packageContext]string, []string) {
   2333 
   2334 	pkgs := make(map[string]*packageContext)
   2335 	pkgNames := make(map[*packageContext]string)
   2336 	longPkgNames := make(map[*packageContext]bool)
   2337 
   2338 	processPackage := func(pctx *packageContext) {
   2339 		if pctx == nil {
   2340 			// This is a built-in rule and has no package.
   2341 			return
   2342 		}
   2343 		if _, ok := pkgNames[pctx]; ok {
   2344 			// We've already processed this package.
   2345 			return
   2346 		}
   2347 
   2348 		otherPkg, present := pkgs[pctx.shortName]
   2349 		if present {
   2350 			// Short name collision.  Both this package and the one that's
   2351 			// already there need to use their full names.  We leave the short
   2352 			// name in pkgNames for now so future collisions still get caught.
   2353 			longPkgNames[pctx] = true
   2354 			longPkgNames[otherPkg] = true
   2355 		} else {
   2356 			// No collision so far.  Tentatively set the package's name to be
   2357 			// its short name.
   2358 			pkgNames[pctx] = pctx.shortName
   2359 			pkgs[pctx.shortName] = pctx
   2360 		}
   2361 	}
   2362 
   2363 	// We try to give all packages their short name, but when we get collisions
   2364 	// we need to use the full unique package name.
   2365 	for v, _ := range liveGlobals.variables {
   2366 		processPackage(v.packageContext())
   2367 	}
   2368 	for p, _ := range liveGlobals.pools {
   2369 		processPackage(p.packageContext())
   2370 	}
   2371 	for r, _ := range liveGlobals.rules {
   2372 		processPackage(r.packageContext())
   2373 	}
   2374 
   2375 	// Add the packages that had collisions using their full unique names.  This
   2376 	// will overwrite any short names that were added in the previous step.
   2377 	for pctx := range longPkgNames {
   2378 		pkgNames[pctx] = pctx.fullName
   2379 	}
   2380 
   2381 	// Create deps list from calls to PackageContext.AddNinjaFileDeps
   2382 	deps := []string{}
   2383 	for _, pkg := range pkgs {
   2384 		deps = append(deps, pkg.ninjaFileDeps...)
   2385 	}
   2386 
   2387 	return pkgNames, deps
   2388 }
   2389 
   2390 func (c *Context) checkForVariableReferenceCycles(
   2391 	variables map[Variable]*ninjaString, pkgNames map[*packageContext]string) {
   2392 
   2393 	visited := make(map[Variable]bool)  // variables that were already checked
   2394 	checking := make(map[Variable]bool) // variables actively being checked
   2395 
   2396 	var check func(v Variable) []Variable
   2397 
   2398 	check = func(v Variable) []Variable {
   2399 		visited[v] = true
   2400 		checking[v] = true
   2401 		defer delete(checking, v)
   2402 
   2403 		value := variables[v]
   2404 		for _, dep := range value.variables {
   2405 			if checking[dep] {
   2406 				// This is a cycle.
   2407 				return []Variable{dep, v}
   2408 			}
   2409 
   2410 			if !visited[dep] {
   2411 				cycle := check(dep)
   2412 				if cycle != nil {
   2413 					if cycle[0] == v {
   2414 						// We are the "start" of the cycle, so we're responsible
   2415 						// for generating the errors.  The cycle list is in
   2416 						// reverse order because all the 'check' calls append
   2417 						// their own module to the list.
   2418 						msgs := []string{"detected variable reference cycle:"}
   2419 
   2420 						// Iterate backwards through the cycle list.
   2421 						curName := v.fullName(pkgNames)
   2422 						curValue := value.Value(pkgNames)
   2423 						for i := len(cycle) - 1; i >= 0; i-- {
   2424 							next := cycle[i]
   2425 							nextName := next.fullName(pkgNames)
   2426 							nextValue := variables[next].Value(pkgNames)
   2427 
   2428 							msgs = append(msgs, fmt.Sprintf(
   2429 								"    %q depends on %q", curName, nextName))
   2430 							msgs = append(msgs, fmt.Sprintf(
   2431 								"    [%s = %s]", curName, curValue))
   2432 
   2433 							curName = nextName
   2434 							curValue = nextValue
   2435 						}
   2436 
   2437 						// Variable reference cycles are a programming error,
   2438 						// not the fault of the Blueprint file authors.
   2439 						panic(strings.Join(msgs, "\n"))
   2440 					} else {
   2441 						// We're not the "start" of the cycle, so we just append
   2442 						// our module to the list and return it.
   2443 						return append(cycle, v)
   2444 					}
   2445 				}
   2446 			}
   2447 		}
   2448 
   2449 		return nil
   2450 	}
   2451 
   2452 	for v := range variables {
   2453 		if !visited[v] {
   2454 			cycle := check(v)
   2455 			if cycle != nil {
   2456 				panic("inconceivable!")
   2457 			}
   2458 		}
   2459 	}
   2460 }
   2461 
   2462 // AllTargets returns a map all the build target names to the rule used to build
   2463 // them.  This is the same information that is output by running 'ninja -t
   2464 // targets all'.  If this is called before PrepareBuildActions successfully
   2465 // completes then ErrbuildActionsNotReady is returned.
   2466 func (c *Context) AllTargets() (map[string]string, error) {
   2467 	if !c.buildActionsReady {
   2468 		return nil, ErrBuildActionsNotReady
   2469 	}
   2470 
   2471 	targets := map[string]string{}
   2472 
   2473 	// Collect all the module build targets.
   2474 	for _, module := range c.moduleInfo {
   2475 		for _, buildDef := range module.actionDefs.buildDefs {
   2476 			ruleName := buildDef.Rule.fullName(c.pkgNames)
   2477 			for _, output := range append(buildDef.Outputs, buildDef.ImplicitOutputs...) {
   2478 				outputValue, err := output.Eval(c.globalVariables)
   2479 				if err != nil {
   2480 					return nil, err
   2481 				}
   2482 				targets[outputValue] = ruleName
   2483 			}
   2484 		}
   2485 	}
   2486 
   2487 	// Collect all the singleton build targets.
   2488 	for _, info := range c.singletonInfo {
   2489 		for _, buildDef := range info.actionDefs.buildDefs {
   2490 			ruleName := buildDef.Rule.fullName(c.pkgNames)
   2491 			for _, output := range append(buildDef.Outputs, buildDef.ImplicitOutputs...) {
   2492 				outputValue, err := output.Eval(c.globalVariables)
   2493 				if err != nil {
   2494 					return nil, err
   2495 				}
   2496 				targets[outputValue] = ruleName
   2497 			}
   2498 		}
   2499 	}
   2500 
   2501 	return targets, nil
   2502 }
   2503 
   2504 func (c *Context) NinjaBuildDir() (string, error) {
   2505 	if c.ninjaBuildDir != nil {
   2506 		return c.ninjaBuildDir.Eval(c.globalVariables)
   2507 	} else {
   2508 		return "", nil
   2509 	}
   2510 }
   2511 
   2512 // ModuleTypePropertyStructs returns a mapping from module type name to a list of pointers to
   2513 // property structs returned by the factory for that module type.
   2514 func (c *Context) ModuleTypePropertyStructs() map[string][]interface{} {
   2515 	ret := make(map[string][]interface{})
   2516 	for moduleType, factory := range c.moduleFactories {
   2517 		_, ret[moduleType] = factory()
   2518 	}
   2519 
   2520 	return ret
   2521 }
   2522 
   2523 func (c *Context) ModuleName(logicModule Module) string {
   2524 	module := c.moduleInfo[logicModule]
   2525 	return module.Name()
   2526 }
   2527 
   2528 func (c *Context) ModuleDir(logicModule Module) string {
   2529 	module := c.moduleInfo[logicModule]
   2530 	return filepath.Dir(module.relBlueprintsFile)
   2531 }
   2532 
   2533 func (c *Context) ModuleSubDir(logicModule Module) string {
   2534 	module := c.moduleInfo[logicModule]
   2535 	return module.variantName
   2536 }
   2537 
   2538 func (c *Context) ModuleType(logicModule Module) string {
   2539 	module := c.moduleInfo[logicModule]
   2540 	return module.typeName
   2541 }
   2542 
   2543 func (c *Context) BlueprintFile(logicModule Module) string {
   2544 	module := c.moduleInfo[logicModule]
   2545 	return module.relBlueprintsFile
   2546 }
   2547 
   2548 func (c *Context) ModuleErrorf(logicModule Module, format string,
   2549 	args ...interface{}) error {
   2550 
   2551 	module := c.moduleInfo[logicModule]
   2552 	return &BlueprintError{
   2553 		Err: fmt.Errorf(format, args...),
   2554 		Pos: module.pos,
   2555 	}
   2556 }
   2557 
   2558 func (c *Context) VisitAllModules(visit func(Module)) {
   2559 	c.visitAllModules(visit)
   2560 }
   2561 
   2562 func (c *Context) VisitAllModulesIf(pred func(Module) bool,
   2563 	visit func(Module)) {
   2564 
   2565 	c.visitAllModulesIf(pred, visit)
   2566 }
   2567 
   2568 func (c *Context) VisitDirectDeps(module Module, visit func(Module)) {
   2569 	topModule := c.moduleInfo[module]
   2570 
   2571 	var visiting *moduleInfo
   2572 
   2573 	defer func() {
   2574 		if r := recover(); r != nil {
   2575 			panic(newPanicErrorf(r, "VisitDirectDeps(%s, %s) for dependency %s",
   2576 				topModule, funcName(visit), visiting))
   2577 		}
   2578 	}()
   2579 
   2580 	for _, dep := range topModule.directDeps {
   2581 		visiting = dep.module
   2582 		visit(dep.module.logicModule)
   2583 	}
   2584 }
   2585 
   2586 func (c *Context) VisitDirectDepsIf(module Module, pred func(Module) bool, visit func(Module)) {
   2587 	topModule := c.moduleInfo[module]
   2588 
   2589 	var visiting *moduleInfo
   2590 
   2591 	defer func() {
   2592 		if r := recover(); r != nil {
   2593 			panic(newPanicErrorf(r, "VisitDirectDepsIf(%s, %s, %s) for dependency %s",
   2594 				topModule, funcName(pred), funcName(visit), visiting))
   2595 		}
   2596 	}()
   2597 
   2598 	for _, dep := range topModule.directDeps {
   2599 		visiting = dep.module
   2600 		if pred(dep.module.logicModule) {
   2601 			visit(dep.module.logicModule)
   2602 		}
   2603 	}
   2604 }
   2605 
   2606 func (c *Context) VisitDepsDepthFirst(module Module, visit func(Module)) {
   2607 	topModule := c.moduleInfo[module]
   2608 
   2609 	var visiting *moduleInfo
   2610 
   2611 	defer func() {
   2612 		if r := recover(); r != nil {
   2613 			panic(newPanicErrorf(r, "VisitDepsDepthFirst(%s, %s) for dependency %s",
   2614 				topModule, funcName(visit), visiting))
   2615 		}
   2616 	}()
   2617 
   2618 	c.walkDeps(topModule, nil, func(dep depInfo, parent *moduleInfo) {
   2619 		visiting = dep.module
   2620 		visit(dep.module.logicModule)
   2621 	})
   2622 }
   2623 
   2624 func (c *Context) VisitDepsDepthFirstIf(module Module, pred func(Module) bool, visit func(Module)) {
   2625 	topModule := c.moduleInfo[module]
   2626 
   2627 	var visiting *moduleInfo
   2628 
   2629 	defer func() {
   2630 		if r := recover(); r != nil {
   2631 			panic(newPanicErrorf(r, "VisitDepsDepthFirstIf(%s, %s, %s) for dependency %s",
   2632 				topModule, funcName(pred), funcName(visit), visiting))
   2633 		}
   2634 	}()
   2635 
   2636 	c.walkDeps(topModule, nil, func(dep depInfo, parent *moduleInfo) {
   2637 		if pred(dep.module.logicModule) {
   2638 			visiting = dep.module
   2639 			visit(dep.module.logicModule)
   2640 		}
   2641 	})
   2642 }
   2643 
   2644 func (c *Context) PrimaryModule(module Module) Module {
   2645 	return c.moduleInfo[module].group.modules[0].logicModule
   2646 }
   2647 
   2648 func (c *Context) FinalModule(module Module) Module {
   2649 	modules := c.moduleInfo[module].group.modules
   2650 	return modules[len(modules)-1].logicModule
   2651 }
   2652 
   2653 func (c *Context) VisitAllModuleVariants(module Module,
   2654 	visit func(Module)) {
   2655 
   2656 	c.visitAllModuleVariants(c.moduleInfo[module], visit)
   2657 }
   2658 
   2659 // WriteBuildFile writes the Ninja manifeset text for the generated build
   2660 // actions to w.  If this is called before PrepareBuildActions successfully
   2661 // completes then ErrBuildActionsNotReady is returned.
   2662 func (c *Context) WriteBuildFile(w io.Writer) error {
   2663 	if !c.buildActionsReady {
   2664 		return ErrBuildActionsNotReady
   2665 	}
   2666 
   2667 	nw := newNinjaWriter(w)
   2668 
   2669 	err := c.writeBuildFileHeader(nw)
   2670 	if err != nil {
   2671 		return err
   2672 	}
   2673 
   2674 	err = c.writeNinjaRequiredVersion(nw)
   2675 	if err != nil {
   2676 		return err
   2677 	}
   2678 
   2679 	// TODO: Group the globals by package.
   2680 
   2681 	err = c.writeGlobalVariables(nw)
   2682 	if err != nil {
   2683 		return err
   2684 	}
   2685 
   2686 	err = c.writeGlobalPools(nw)
   2687 	if err != nil {
   2688 		return err
   2689 	}
   2690 
   2691 	err = c.writeBuildDir(nw)
   2692 	if err != nil {
   2693 		return err
   2694 	}
   2695 
   2696 	err = c.writeGlobalRules(nw)
   2697 	if err != nil {
   2698 		return err
   2699 	}
   2700 
   2701 	err = c.writeAllModuleActions(nw)
   2702 	if err != nil {
   2703 		return err
   2704 	}
   2705 
   2706 	err = c.writeAllSingletonActions(nw)
   2707 	if err != nil {
   2708 		return err
   2709 	}
   2710 
   2711 	return nil
   2712 }
   2713 
   2714 type pkgAssociation struct {
   2715 	PkgName string
   2716 	PkgPath string
   2717 }
   2718 
   2719 type pkgAssociationSorter struct {
   2720 	pkgs []pkgAssociation
   2721 }
   2722 
   2723 func (s *pkgAssociationSorter) Len() int {
   2724 	return len(s.pkgs)
   2725 }
   2726 
   2727 func (s *pkgAssociationSorter) Less(i, j int) bool {
   2728 	iName := s.pkgs[i].PkgName
   2729 	jName := s.pkgs[j].PkgName
   2730 	return iName < jName
   2731 }
   2732 
   2733 func (s *pkgAssociationSorter) Swap(i, j int) {
   2734 	s.pkgs[i], s.pkgs[j] = s.pkgs[j], s.pkgs[i]
   2735 }
   2736 
   2737 func (c *Context) writeBuildFileHeader(nw *ninjaWriter) error {
   2738 	headerTemplate := template.New("fileHeader")
   2739 	_, err := headerTemplate.Parse(fileHeaderTemplate)
   2740 	if err != nil {
   2741 		// This is a programming error.
   2742 		panic(err)
   2743 	}
   2744 
   2745 	var pkgs []pkgAssociation
   2746 	maxNameLen := 0
   2747 	for pkg, name := range c.pkgNames {
   2748 		pkgs = append(pkgs, pkgAssociation{
   2749 			PkgName: name,
   2750 			PkgPath: pkg.pkgPath,
   2751 		})
   2752 		if len(name) > maxNameLen {
   2753 			maxNameLen = len(name)
   2754 		}
   2755 	}
   2756 
   2757 	for i := range pkgs {
   2758 		pkgs[i].PkgName += strings.Repeat(" ", maxNameLen-len(pkgs[i].PkgName))
   2759 	}
   2760 
   2761 	sort.Sort(&pkgAssociationSorter{pkgs})
   2762 
   2763 	params := map[string]interface{}{
   2764 		"Pkgs": pkgs,
   2765 	}
   2766 
   2767 	buf := bytes.NewBuffer(nil)
   2768 	err = headerTemplate.Execute(buf, params)
   2769 	if err != nil {
   2770 		return err
   2771 	}
   2772 
   2773 	return nw.Comment(buf.String())
   2774 }
   2775 
   2776 func (c *Context) writeNinjaRequiredVersion(nw *ninjaWriter) error {
   2777 	value := fmt.Sprintf("%d.%d.%d", c.requiredNinjaMajor, c.requiredNinjaMinor,
   2778 		c.requiredNinjaMicro)
   2779 
   2780 	err := nw.Assign("ninja_required_version", value)
   2781 	if err != nil {
   2782 		return err
   2783 	}
   2784 
   2785 	return nw.BlankLine()
   2786 }
   2787 
   2788 func (c *Context) writeBuildDir(nw *ninjaWriter) error {
   2789 	if c.ninjaBuildDir != nil {
   2790 		err := nw.Assign("builddir", c.ninjaBuildDir.Value(c.pkgNames))
   2791 		if err != nil {
   2792 			return err
   2793 		}
   2794 
   2795 		err = nw.BlankLine()
   2796 		if err != nil {
   2797 			return err
   2798 		}
   2799 	}
   2800 	return nil
   2801 }
   2802 
   2803 type globalEntity interface {
   2804 	fullName(pkgNames map[*packageContext]string) string
   2805 }
   2806 
   2807 type globalEntitySorter struct {
   2808 	pkgNames map[*packageContext]string
   2809 	entities []globalEntity
   2810 }
   2811 
   2812 func (s *globalEntitySorter) Len() int {
   2813 	return len(s.entities)
   2814 }
   2815 
   2816 func (s *globalEntitySorter) Less(i, j int) bool {
   2817 	iName := s.entities[i].fullName(s.pkgNames)
   2818 	jName := s.entities[j].fullName(s.pkgNames)
   2819 	return iName < jName
   2820 }
   2821 
   2822 func (s *globalEntitySorter) Swap(i, j int) {
   2823 	s.entities[i], s.entities[j] = s.entities[j], s.entities[i]
   2824 }
   2825 
   2826 func (c *Context) writeGlobalVariables(nw *ninjaWriter) error {
   2827 	visited := make(map[Variable]bool)
   2828 
   2829 	var walk func(v Variable) error
   2830 	walk = func(v Variable) error {
   2831 		visited[v] = true
   2832 
   2833 		// First visit variables on which this variable depends.
   2834 		value := c.globalVariables[v]
   2835 		for _, dep := range value.variables {
   2836 			if !visited[dep] {
   2837 				err := walk(dep)
   2838 				if err != nil {
   2839 					return err
   2840 				}
   2841 			}
   2842 		}
   2843 
   2844 		err := nw.Assign(v.fullName(c.pkgNames), value.Value(c.pkgNames))
   2845 		if err != nil {
   2846 			return err
   2847 		}
   2848 
   2849 		err = nw.BlankLine()
   2850 		if err != nil {
   2851 			return err
   2852 		}
   2853 
   2854 		return nil
   2855 	}
   2856 
   2857 	globalVariables := make([]globalEntity, 0, len(c.globalVariables))
   2858 	for variable := range c.globalVariables {
   2859 		globalVariables = append(globalVariables, variable)
   2860 	}
   2861 
   2862 	sort.Sort(&globalEntitySorter{c.pkgNames, globalVariables})
   2863 
   2864 	for _, entity := range globalVariables {
   2865 		v := entity.(Variable)
   2866 		if !visited[v] {
   2867 			err := walk(v)
   2868 			if err != nil {
   2869 				return nil
   2870 			}
   2871 		}
   2872 	}
   2873 
   2874 	return nil
   2875 }
   2876 
   2877 func (c *Context) writeGlobalPools(nw *ninjaWriter) error {
   2878 	globalPools := make([]globalEntity, 0, len(c.globalPools))
   2879 	for pool := range c.globalPools {
   2880 		globalPools = append(globalPools, pool)
   2881 	}
   2882 
   2883 	sort.Sort(&globalEntitySorter{c.pkgNames, globalPools})
   2884 
   2885 	for _, entity := range globalPools {
   2886 		pool := entity.(Pool)
   2887 		name := pool.fullName(c.pkgNames)
   2888 		def := c.globalPools[pool]
   2889 		err := def.WriteTo(nw, name)
   2890 		if err != nil {
   2891 			return err
   2892 		}
   2893 
   2894 		err = nw.BlankLine()
   2895 		if err != nil {
   2896 			return err
   2897 		}
   2898 	}
   2899 
   2900 	return nil
   2901 }
   2902 
   2903 func (c *Context) writeGlobalRules(nw *ninjaWriter) error {
   2904 	globalRules := make([]globalEntity, 0, len(c.globalRules))
   2905 	for rule := range c.globalRules {
   2906 		globalRules = append(globalRules, rule)
   2907 	}
   2908 
   2909 	sort.Sort(&globalEntitySorter{c.pkgNames, globalRules})
   2910 
   2911 	for _, entity := range globalRules {
   2912 		rule := entity.(Rule)
   2913 		name := rule.fullName(c.pkgNames)
   2914 		def := c.globalRules[rule]
   2915 		err := def.WriteTo(nw, name, c.pkgNames)
   2916 		if err != nil {
   2917 			return err
   2918 		}
   2919 
   2920 		err = nw.BlankLine()
   2921 		if err != nil {
   2922 			return err
   2923 		}
   2924 	}
   2925 
   2926 	return nil
   2927 }
   2928 
   2929 type depSorter []depInfo
   2930 
   2931 func (s depSorter) Len() int {
   2932 	return len(s)
   2933 }
   2934 
   2935 func (s depSorter) Less(i, j int) bool {
   2936 	iName := s[i].module.Name()
   2937 	jName := s[j].module.Name()
   2938 	if iName == jName {
   2939 		iName = s[i].module.variantName
   2940 		jName = s[j].module.variantName
   2941 	}
   2942 	return iName < jName
   2943 }
   2944 
   2945 func (s depSorter) Swap(i, j int) {
   2946 	s[i], s[j] = s[j], s[i]
   2947 }
   2948 
   2949 type moduleSorter []*moduleInfo
   2950 
   2951 func (s moduleSorter) Len() int {
   2952 	return len(s)
   2953 }
   2954 
   2955 func (s moduleSorter) Less(i, j int) bool {
   2956 	iName := s[i].Name()
   2957 	jName := s[j].Name()
   2958 	if iName == jName {
   2959 		iName = s[i].variantName
   2960 		jName = s[j].variantName
   2961 	}
   2962 	return iName < jName
   2963 }
   2964 
   2965 func (s moduleSorter) Swap(i, j int) {
   2966 	s[i], s[j] = s[j], s[i]
   2967 }
   2968 
   2969 func (c *Context) writeAllModuleActions(nw *ninjaWriter) error {
   2970 	headerTemplate := template.New("moduleHeader")
   2971 	_, err := headerTemplate.Parse(moduleHeaderTemplate)
   2972 	if err != nil {
   2973 		// This is a programming error.
   2974 		panic(err)
   2975 	}
   2976 
   2977 	modules := make([]*moduleInfo, 0, len(c.moduleInfo))
   2978 	for _, module := range c.moduleInfo {
   2979 		modules = append(modules, module)
   2980 	}
   2981 	sort.Sort(moduleSorter(modules))
   2982 
   2983 	buf := bytes.NewBuffer(nil)
   2984 
   2985 	for _, module := range modules {
   2986 		if len(module.actionDefs.variables)+len(module.actionDefs.rules)+len(module.actionDefs.buildDefs) == 0 {
   2987 			continue
   2988 		}
   2989 
   2990 		buf.Reset()
   2991 
   2992 		// In order to make the bootstrap build manifest independent of the
   2993 		// build dir we need to output the Blueprints file locations in the
   2994 		// comments as paths relative to the source directory.
   2995 		relPos := module.pos
   2996 		relPos.Filename = module.relBlueprintsFile
   2997 
   2998 		// Get the name and location of the factory function for the module.
   2999 		factory := c.moduleFactories[module.typeName]
   3000 		factoryFunc := runtime.FuncForPC(reflect.ValueOf(factory).Pointer())
   3001 		factoryName := factoryFunc.Name()
   3002 
   3003 		infoMap := map[string]interface{}{
   3004 			"name":      module.Name(),
   3005 			"typeName":  module.typeName,
   3006 			"goFactory": factoryName,
   3007 			"pos":       relPos,
   3008 			"variant":   module.variantName,
   3009 		}
   3010 		err = headerTemplate.Execute(buf, infoMap)
   3011 		if err != nil {
   3012 			return err
   3013 		}
   3014 
   3015 		err = nw.Comment(buf.String())
   3016 		if err != nil {
   3017 			return err
   3018 		}
   3019 
   3020 		err = nw.BlankLine()
   3021 		if err != nil {
   3022 			return err
   3023 		}
   3024 
   3025 		err = c.writeLocalBuildActions(nw, &module.actionDefs)
   3026 		if err != nil {
   3027 			return err
   3028 		}
   3029 
   3030 		err = nw.BlankLine()
   3031 		if err != nil {
   3032 			return err
   3033 		}
   3034 	}
   3035 
   3036 	return nil
   3037 }
   3038 
   3039 func (c *Context) writeAllSingletonActions(nw *ninjaWriter) error {
   3040 	headerTemplate := template.New("singletonHeader")
   3041 	_, err := headerTemplate.Parse(singletonHeaderTemplate)
   3042 	if err != nil {
   3043 		// This is a programming error.
   3044 		panic(err)
   3045 	}
   3046 
   3047 	buf := bytes.NewBuffer(nil)
   3048 
   3049 	for _, info := range c.singletonInfo {
   3050 		if len(info.actionDefs.variables)+len(info.actionDefs.rules)+len(info.actionDefs.buildDefs) == 0 {
   3051 			continue
   3052 		}
   3053 
   3054 		// Get the name of the factory function for the module.
   3055 		factory := info.factory
   3056 		factoryFunc := runtime.FuncForPC(reflect.ValueOf(factory).Pointer())
   3057 		factoryName := factoryFunc.Name()
   3058 
   3059 		buf.Reset()
   3060 		infoMap := map[string]interface{}{
   3061 			"name":      info.name,
   3062 			"goFactory": factoryName,
   3063 		}
   3064 		err = headerTemplate.Execute(buf, infoMap)
   3065 		if err != nil {
   3066 			return err
   3067 		}
   3068 
   3069 		err = nw.Comment(buf.String())
   3070 		if err != nil {
   3071 			return err
   3072 		}
   3073 
   3074 		err = nw.BlankLine()
   3075 		if err != nil {
   3076 			return err
   3077 		}
   3078 
   3079 		err = c.writeLocalBuildActions(nw, &info.actionDefs)
   3080 		if err != nil {
   3081 			return err
   3082 		}
   3083 
   3084 		err = nw.BlankLine()
   3085 		if err != nil {
   3086 			return err
   3087 		}
   3088 	}
   3089 
   3090 	return nil
   3091 }
   3092 
   3093 func (c *Context) writeLocalBuildActions(nw *ninjaWriter,
   3094 	defs *localBuildActions) error {
   3095 
   3096 	// Write the local variable assignments.
   3097 	for _, v := range defs.variables {
   3098 		// A localVariable doesn't need the package names or config to
   3099 		// determine its name or value.
   3100 		name := v.fullName(nil)
   3101 		value, err := v.value(nil)
   3102 		if err != nil {
   3103 			panic(err)
   3104 		}
   3105 		err = nw.Assign(name, value.Value(c.pkgNames))
   3106 		if err != nil {
   3107 			return err
   3108 		}
   3109 	}
   3110 
   3111 	if len(defs.variables) > 0 {
   3112 		err := nw.BlankLine()
   3113 		if err != nil {
   3114 			return err
   3115 		}
   3116 	}
   3117 
   3118 	// Write the local rules.
   3119 	for _, r := range defs.rules {
   3120 		// A localRule doesn't need the package names or config to determine
   3121 		// its name or definition.
   3122 		name := r.fullName(nil)
   3123 		def, err := r.def(nil)
   3124 		if err != nil {
   3125 			panic(err)
   3126 		}
   3127 
   3128 		err = def.WriteTo(nw, name, c.pkgNames)
   3129 		if err != nil {
   3130 			return err
   3131 		}
   3132 
   3133 		err = nw.BlankLine()
   3134 		if err != nil {
   3135 			return err
   3136 		}
   3137 	}
   3138 
   3139 	// Write the build definitions.
   3140 	for _, buildDef := range defs.buildDefs {
   3141 		err := buildDef.WriteTo(nw, c.pkgNames)
   3142 		if err != nil {
   3143 			return err
   3144 		}
   3145 
   3146 		if len(buildDef.Args) > 0 {
   3147 			err = nw.BlankLine()
   3148 			if err != nil {
   3149 				return err
   3150 			}
   3151 		}
   3152 	}
   3153 
   3154 	return nil
   3155 }
   3156 
   3157 func beforeInModuleList(a, b *moduleInfo, list []*moduleInfo) bool {
   3158 	found := false
   3159 	if a == b {
   3160 		return false
   3161 	}
   3162 	for _, l := range list {
   3163 		if l == a {
   3164 			found = true
   3165 		} else if l == b {
   3166 			return found
   3167 		}
   3168 	}
   3169 
   3170 	missing := a
   3171 	if found {
   3172 		missing = b
   3173 	}
   3174 	panic(fmt.Errorf("element %v not found in list %v", missing, list))
   3175 }
   3176 
   3177 type panicError struct {
   3178 	panic interface{}
   3179 	stack []byte
   3180 	in    string
   3181 }
   3182 
   3183 func newPanicErrorf(panic interface{}, in string, a ...interface{}) error {
   3184 	buf := make([]byte, 4096)
   3185 	count := runtime.Stack(buf, false)
   3186 	return panicError{
   3187 		panic: panic,
   3188 		in:    fmt.Sprintf(in, a...),
   3189 		stack: buf[:count],
   3190 	}
   3191 }
   3192 
   3193 func (p panicError) Error() string {
   3194 	return fmt.Sprintf("panic in %s\n%s\n%s\n", p.in, p.panic, p.stack)
   3195 }
   3196 
   3197 func (p *panicError) addIn(in string) {
   3198 	p.in += " in " + in
   3199 }
   3200 
   3201 func funcName(f interface{}) string {
   3202 	return runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name()
   3203 }
   3204 
   3205 var fileHeaderTemplate = `******************************************************************************
   3206 ***            This file is generated and should not be edited             ***
   3207 ******************************************************************************
   3208 {{if .Pkgs}}
   3209 This file contains variables, rules, and pools with name prefixes indicating
   3210 they were generated by the following Go packages:
   3211 {{range .Pkgs}}
   3212     {{.PkgName}} [from Go package {{.PkgPath}}]{{end}}{{end}}
   3213 
   3214 `
   3215 
   3216 var moduleHeaderTemplate = `# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
   3217 Module:  {{.name}}
   3218 Variant: {{.variant}}
   3219 Type:    {{.typeName}}
   3220 Factory: {{.goFactory}}
   3221 Defined: {{.pos}}
   3222 `
   3223 
   3224 var singletonHeaderTemplate = `# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
   3225 Singleton: {{.name}}
   3226 Factory:   {{.goFactory}}
   3227 `
   3228