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