• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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	"context"
20	"encoding/json"
21	"errors"
22	"fmt"
23	"io"
24	"io/ioutil"
25	"os"
26	"path/filepath"
27	"reflect"
28	"runtime"
29	"runtime/pprof"
30	"sort"
31	"strings"
32	"sync"
33	"sync/atomic"
34	"text/scanner"
35	"text/template"
36
37	"github.com/google/blueprint/parser"
38	"github.com/google/blueprint/pathtools"
39	"github.com/google/blueprint/proptools"
40)
41
42var ErrBuildActionsNotReady = errors.New("build actions are not ready")
43
44const maxErrors = 10
45const MockModuleListFile = "bplist"
46
47// A Context contains all the state needed to parse a set of Blueprints files
48// and generate a Ninja file.  The process of generating a Ninja file proceeds
49// through a series of four phases.  Each phase corresponds with a some methods
50// on the Context object
51//
52//         Phase                            Methods
53//      ------------      -------------------------------------------
54//   1. Registration         RegisterModuleType, RegisterSingletonType
55//
56//   2. Parse                    ParseBlueprintsFiles, Parse
57//
58//   3. Generate            ResolveDependencies, PrepareBuildActions
59//
60//   4. Write                           WriteBuildFile
61//
62// The registration phase prepares the context to process Blueprints files
63// containing various types of modules.  The parse phase reads in one or more
64// Blueprints files and validates their contents against the module types that
65// have been registered.  The generate phase then analyzes the parsed Blueprints
66// contents to create an internal representation for the build actions that must
67// be performed.  This phase also performs validation of the module dependencies
68// and property values defined in the parsed Blueprints files.  Finally, the
69// write phase generates the Ninja manifest text based on the generated build
70// actions.
71type Context struct {
72	context.Context
73
74	// set at instantiation
75	moduleFactories     map[string]ModuleFactory
76	nameInterface       NameInterface
77	moduleGroups        []*moduleGroup
78	moduleInfo          map[Module]*moduleInfo
79	modulesSorted       []*moduleInfo
80	preSingletonInfo    []*singletonInfo
81	singletonInfo       []*singletonInfo
82	mutatorInfo         []*mutatorInfo
83	earlyMutatorInfo    []*mutatorInfo
84	variantMutatorNames []string
85
86	depsModified uint32 // positive if a mutator modified the dependencies
87
88	dependenciesReady bool // set to true on a successful ResolveDependencies
89	buildActionsReady bool // set to true on a successful PrepareBuildActions
90
91	// set by SetIgnoreUnknownModuleTypes
92	ignoreUnknownModuleTypes bool
93
94	// set by SetAllowMissingDependencies
95	allowMissingDependencies bool
96
97	// set during PrepareBuildActions
98	pkgNames        map[*packageContext]string
99	liveGlobals     *liveTracker
100	globalVariables map[Variable]ninjaString
101	globalPools     map[Pool]*poolDef
102	globalRules     map[Rule]*ruleDef
103
104	// set during PrepareBuildActions
105	ninjaBuildDir      ninjaString // The builddir special Ninja variable
106	requiredNinjaMajor int         // For the ninja_required_version variable
107	requiredNinjaMinor int         // For the ninja_required_version variable
108	requiredNinjaMicro int         // For the ninja_required_version variable
109
110	subninjas []string
111
112	// set lazily by sortedModuleGroups
113	cachedSortedModuleGroups []*moduleGroup
114	// cache deps modified to determine whether cachedSortedModuleGroups needs to be recalculated
115	cachedDepsModified bool
116
117	globs    map[globKey]pathtools.GlobResult
118	globLock sync.Mutex
119
120	srcDir         string
121	fs             pathtools.FileSystem
122	moduleListFile string
123
124	// Mutators indexed by the ID of the provider associated with them.  Not all mutators will
125	// have providers, and not all providers will have a mutator, or if they do the mutator may
126	// not be registered in this Context.
127	providerMutators []*mutatorInfo
128
129	// The currently running mutator
130	startedMutator *mutatorInfo
131	// True for any mutators that have already run over all modules
132	finishedMutators map[*mutatorInfo]bool
133
134	// Can be set by tests to avoid invalidating Module values after mutators.
135	skipCloneModulesAfterMutators bool
136}
137
138// An Error describes a problem that was encountered that is related to a
139// particular location in a Blueprints file.
140type BlueprintError struct {
141	Err error            // the error that occurred
142	Pos scanner.Position // the relevant Blueprints file location
143}
144
145// A ModuleError describes a problem that was encountered that is related to a
146// particular module in a Blueprints file
147type ModuleError struct {
148	BlueprintError
149	module *moduleInfo
150}
151
152// A PropertyError describes a problem that was encountered that is related to a
153// particular property in a Blueprints file
154type PropertyError struct {
155	ModuleError
156	property string
157}
158
159func (e *BlueprintError) Error() string {
160	return fmt.Sprintf("%s: %s", e.Pos, e.Err)
161}
162
163func (e *ModuleError) Error() string {
164	return fmt.Sprintf("%s: %s: %s", e.Pos, e.module, e.Err)
165}
166
167func (e *PropertyError) Error() string {
168	return fmt.Sprintf("%s: %s: %s: %s", e.Pos, e.module, e.property, e.Err)
169}
170
171type localBuildActions struct {
172	variables []*localVariable
173	rules     []*localRule
174	buildDefs []*buildDef
175}
176
177type moduleAlias struct {
178	variant variant
179	target  *moduleInfo
180}
181
182func (m *moduleAlias) alias() *moduleAlias              { return m }
183func (m *moduleAlias) module() *moduleInfo              { return nil }
184func (m *moduleAlias) moduleOrAliasTarget() *moduleInfo { return m.target }
185func (m *moduleAlias) moduleOrAliasVariant() variant    { return m.variant }
186
187func (m *moduleInfo) alias() *moduleAlias              { return nil }
188func (m *moduleInfo) module() *moduleInfo              { return m }
189func (m *moduleInfo) moduleOrAliasTarget() *moduleInfo { return m }
190func (m *moduleInfo) moduleOrAliasVariant() variant    { return m.variant }
191
192type moduleOrAlias interface {
193	alias() *moduleAlias
194	module() *moduleInfo
195	moduleOrAliasTarget() *moduleInfo
196	moduleOrAliasVariant() variant
197}
198
199type modulesOrAliases []moduleOrAlias
200
201func (l modulesOrAliases) firstModule() *moduleInfo {
202	for _, moduleOrAlias := range l {
203		if m := moduleOrAlias.module(); m != nil {
204			return m
205		}
206	}
207	panic(fmt.Errorf("no first module!"))
208}
209
210func (l modulesOrAliases) lastModule() *moduleInfo {
211	for i := range l {
212		if m := l[len(l)-1-i].module(); m != nil {
213			return m
214		}
215	}
216	panic(fmt.Errorf("no last module!"))
217}
218
219type moduleGroup struct {
220	name      string
221	ninjaName string
222
223	modules modulesOrAliases
224
225	namespace Namespace
226}
227
228func (group *moduleGroup) moduleOrAliasByVariantName(name string) moduleOrAlias {
229	for _, module := range group.modules {
230		if module.moduleOrAliasVariant().name == name {
231			return module
232		}
233	}
234	return nil
235}
236
237func (group *moduleGroup) moduleByVariantName(name string) *moduleInfo {
238	return group.moduleOrAliasByVariantName(name).module()
239}
240
241type moduleInfo struct {
242	// set during Parse
243	typeName          string
244	factory           ModuleFactory
245	relBlueprintsFile string
246	pos               scanner.Position
247	propertyPos       map[string]scanner.Position
248	createdBy         *moduleInfo
249
250	variant variant
251
252	logicModule Module
253	group       *moduleGroup
254	properties  []interface{}
255
256	// set during ResolveDependencies
257	missingDeps   []string
258	newDirectDeps []depInfo
259
260	// set during updateDependencies
261	reverseDeps []*moduleInfo
262	forwardDeps []*moduleInfo
263	directDeps  []depInfo
264
265	// used by parallelVisit
266	waitingCount int
267
268	// set during each runMutator
269	splitModules modulesOrAliases
270
271	// set during PrepareBuildActions
272	actionDefs localBuildActions
273
274	providers []interface{}
275
276	startedMutator  *mutatorInfo
277	finishedMutator *mutatorInfo
278
279	startedGenerateBuildActions  bool
280	finishedGenerateBuildActions bool
281}
282
283type variant struct {
284	name                 string
285	variations           variationMap
286	dependencyVariations variationMap
287}
288
289type depInfo struct {
290	module *moduleInfo
291	tag    DependencyTag
292}
293
294func (module *moduleInfo) Name() string {
295	// If this is called from a LoadHook (which is run before the module has been registered)
296	// then group will not be set and so the name is retrieved from logicModule.Name().
297	// Usually, using that method is not safe as it does not track renames (group.name does).
298	// However, when called from LoadHook it is safe as there is no way to rename a module
299	// until after the LoadHook has run and the module has been registered.
300	if module.group != nil {
301		return module.group.name
302	} else {
303		return module.logicModule.Name()
304	}
305}
306
307func (module *moduleInfo) String() string {
308	s := fmt.Sprintf("module %q", module.Name())
309	if module.variant.name != "" {
310		s += fmt.Sprintf(" variant %q", module.variant.name)
311	}
312	if module.createdBy != nil {
313		s += fmt.Sprintf(" (created by %s)", module.createdBy)
314	}
315
316	return s
317}
318
319func (module *moduleInfo) namespace() Namespace {
320	return module.group.namespace
321}
322
323// A Variation is a way that a variant of a module differs from other variants of the same module.
324// For example, two variants of the same module might have Variation{"arch","arm"} and
325// Variation{"arch","arm64"}
326type Variation struct {
327	// Mutator is the axis on which this variation applies, i.e. "arch" or "link"
328	Mutator string
329	// Variation is the name of the variation on the axis, i.e. "arm" or "arm64" for arch, or
330	// "shared" or "static" for link.
331	Variation string
332}
333
334// A variationMap stores a map of Mutator to Variation to specify a variant of a module.
335type variationMap map[string]string
336
337func (vm variationMap) clone() variationMap {
338	if vm == nil {
339		return nil
340	}
341	newVm := make(variationMap)
342	for k, v := range vm {
343		newVm[k] = v
344	}
345
346	return newVm
347}
348
349// Compare this variationMap to another one.  Returns true if the every entry in this map
350// exists and has the same value in the other map.
351func (vm variationMap) subsetOf(other variationMap) bool {
352	for k, v1 := range vm {
353		if v2, ok := other[k]; !ok || v1 != v2 {
354			return false
355		}
356	}
357	return true
358}
359
360func (vm variationMap) equal(other variationMap) bool {
361	return reflect.DeepEqual(vm, other)
362}
363
364type singletonInfo struct {
365	// set during RegisterSingletonType
366	factory   SingletonFactory
367	singleton Singleton
368	name      string
369
370	// set during PrepareBuildActions
371	actionDefs localBuildActions
372}
373
374type mutatorInfo struct {
375	// set during RegisterMutator
376	topDownMutator  TopDownMutator
377	bottomUpMutator BottomUpMutator
378	name            string
379	parallel        bool
380}
381
382func newContext() *Context {
383	return &Context{
384		Context:            context.Background(),
385		moduleFactories:    make(map[string]ModuleFactory),
386		nameInterface:      NewSimpleNameInterface(),
387		moduleInfo:         make(map[Module]*moduleInfo),
388		globs:              make(map[globKey]pathtools.GlobResult),
389		fs:                 pathtools.OsFs,
390		finishedMutators:   make(map[*mutatorInfo]bool),
391		ninjaBuildDir:      nil,
392		requiredNinjaMajor: 1,
393		requiredNinjaMinor: 7,
394		requiredNinjaMicro: 0,
395	}
396}
397
398// NewContext creates a new Context object.  The created context initially has
399// no module or singleton factories registered, so the RegisterModuleFactory and
400// RegisterSingletonFactory methods must be called before it can do anything
401// useful.
402func NewContext() *Context {
403	ctx := newContext()
404
405	ctx.RegisterBottomUpMutator("blueprint_deps", blueprintDepsMutator)
406
407	return ctx
408}
409
410// A ModuleFactory function creates a new Module object.  See the
411// Context.RegisterModuleType method for details about how a registered
412// ModuleFactory is used by a Context.
413type ModuleFactory func() (m Module, propertyStructs []interface{})
414
415// RegisterModuleType associates a module type name (which can appear in a
416// Blueprints file) with a Module factory function.  When the given module type
417// name is encountered in a Blueprints file during parsing, the Module factory
418// is invoked to instantiate a new Module object to handle the build action
419// generation for the module.  If a Mutator splits a module into multiple variants,
420// the factory is invoked again to create a new Module for each variant.
421//
422// The module type names given here must be unique for the context.  The factory
423// function should be a named function so that its package and name can be
424// included in the generated Ninja file for debugging purposes.
425//
426// The factory function returns two values.  The first is the newly created
427// Module object.  The second is a slice of pointers to that Module object's
428// properties structs.  Each properties struct is examined when parsing a module
429// definition of this type in a Blueprints file.  Exported fields of the
430// properties structs are automatically set to the property values specified in
431// the Blueprints file.  The properties struct field names determine the name of
432// the Blueprints file properties that are used - the Blueprints property name
433// matches that of the properties struct field name with the first letter
434// converted to lower-case.
435//
436// The fields of the properties struct must be either []string, a string, or
437// bool. The Context will panic if a Module gets instantiated with a properties
438// struct containing a field that is not one these supported types.
439//
440// Any properties that appear in the Blueprints files that are not built-in
441// module properties (such as "name" and "deps") and do not have a corresponding
442// field in the returned module properties struct result in an error during the
443// Context's parse phase.
444//
445// As an example, the follow code:
446//
447//   type myModule struct {
448//       properties struct {
449//           Foo string
450//           Bar []string
451//       }
452//   }
453//
454//   func NewMyModule() (blueprint.Module, []interface{}) {
455//       module := new(myModule)
456//       properties := &module.properties
457//       return module, []interface{}{properties}
458//   }
459//
460//   func main() {
461//       ctx := blueprint.NewContext()
462//       ctx.RegisterModuleType("my_module", NewMyModule)
463//       // ...
464//   }
465//
466// would support parsing a module defined in a Blueprints file as follows:
467//
468//   my_module {
469//       name: "myName",
470//       foo:  "my foo string",
471//       bar:  ["my", "bar", "strings"],
472//   }
473//
474// The factory function may be called from multiple goroutines.  Any accesses
475// to global variables must be synchronized.
476func (c *Context) RegisterModuleType(name string, factory ModuleFactory) {
477	if _, present := c.moduleFactories[name]; present {
478		panic(errors.New("module type name is already registered"))
479	}
480	c.moduleFactories[name] = factory
481}
482
483// A SingletonFactory function creates a new Singleton object.  See the
484// Context.RegisterSingletonType method for details about how a registered
485// SingletonFactory is used by a Context.
486type SingletonFactory func() Singleton
487
488// RegisterSingletonType registers a singleton type that will be invoked to
489// generate build actions.  Each registered singleton type is instantiated and
490// and invoked exactly once as part of the generate phase.  Each registered
491// singleton is invoked in registration order.
492//
493// The singleton type names given here must be unique for the context.  The
494// factory function should be a named function so that its package and name can
495// be included in the generated Ninja file for debugging purposes.
496func (c *Context) RegisterSingletonType(name string, factory SingletonFactory) {
497	for _, s := range c.singletonInfo {
498		if s.name == name {
499			panic(errors.New("singleton name is already registered"))
500		}
501	}
502
503	c.singletonInfo = append(c.singletonInfo, &singletonInfo{
504		factory:   factory,
505		singleton: factory(),
506		name:      name,
507	})
508}
509
510// RegisterPreSingletonType registers a presingleton type that will be invoked to
511// generate build actions before any Blueprint files have been read.  Each registered
512// presingleton type is instantiated and invoked exactly once at the beginning of the
513// parse phase.  Each registered presingleton is invoked in registration order.
514//
515// The presingleton type names given here must be unique for the context.  The
516// factory function should be a named function so that its package and name can
517// be included in the generated Ninja file for debugging purposes.
518func (c *Context) RegisterPreSingletonType(name string, factory SingletonFactory) {
519	for _, s := range c.preSingletonInfo {
520		if s.name == name {
521			panic(errors.New("presingleton name is already registered"))
522		}
523	}
524
525	c.preSingletonInfo = append(c.preSingletonInfo, &singletonInfo{
526		factory:   factory,
527		singleton: factory(),
528		name:      name,
529	})
530}
531
532func (c *Context) SetNameInterface(i NameInterface) {
533	c.nameInterface = i
534}
535
536func (c *Context) SetSrcDir(path string) {
537	c.srcDir = path
538	c.fs = pathtools.NewOsFs(path)
539}
540
541func (c *Context) SrcDir() string {
542	return c.srcDir
543}
544
545func singletonPkgPath(singleton Singleton) string {
546	typ := reflect.TypeOf(singleton)
547	for typ.Kind() == reflect.Ptr {
548		typ = typ.Elem()
549	}
550	return typ.PkgPath()
551}
552
553func singletonTypeName(singleton Singleton) string {
554	typ := reflect.TypeOf(singleton)
555	for typ.Kind() == reflect.Ptr {
556		typ = typ.Elem()
557	}
558	return typ.PkgPath() + "." + typ.Name()
559}
560
561// RegisterTopDownMutator registers a mutator that will be invoked to propagate dependency info
562// top-down between Modules.  Each registered mutator is invoked in registration order (mixing
563// TopDownMutators and BottomUpMutators) once per Module, and the invocation on any module will
564// have returned before it is in invoked on any of its dependencies.
565//
566// The mutator type names given here must be unique to all top down mutators in
567// the Context.
568//
569// Returns a MutatorHandle, on which Parallel can be called to set the mutator to visit modules in
570// parallel while maintaining ordering.
571func (c *Context) RegisterTopDownMutator(name string, mutator TopDownMutator) MutatorHandle {
572	for _, m := range c.mutatorInfo {
573		if m.name == name && m.topDownMutator != nil {
574			panic(fmt.Errorf("mutator name %s is already registered", name))
575		}
576	}
577
578	info := &mutatorInfo{
579		topDownMutator: mutator,
580		name:           name,
581	}
582
583	c.mutatorInfo = append(c.mutatorInfo, info)
584
585	return info
586}
587
588// RegisterBottomUpMutator registers a mutator that will be invoked to split Modules into variants.
589// Each registered mutator is invoked in registration order (mixing TopDownMutators and
590// BottomUpMutators) once per Module, will not be invoked on a module until the invocations on all
591// of the modules dependencies have returned.
592//
593// The mutator type names given here must be unique to all bottom up or early
594// mutators in the Context.
595//
596// Returns a MutatorHandle, on which Parallel can be called to set the mutator to visit modules in
597// parallel while maintaining ordering.
598func (c *Context) RegisterBottomUpMutator(name string, mutator BottomUpMutator) MutatorHandle {
599	for _, m := range c.variantMutatorNames {
600		if m == name {
601			panic(fmt.Errorf("mutator name %s is already registered", name))
602		}
603	}
604
605	info := &mutatorInfo{
606		bottomUpMutator: mutator,
607		name:            name,
608	}
609	c.mutatorInfo = append(c.mutatorInfo, info)
610
611	c.variantMutatorNames = append(c.variantMutatorNames, name)
612
613	return info
614}
615
616type MutatorHandle interface {
617	// Set the mutator to visit modules in parallel while maintaining ordering.  Calling any
618	// method on the mutator context is thread-safe, but the mutator must handle synchronization
619	// for any modifications to global state or any modules outside the one it was invoked on.
620	Parallel() MutatorHandle
621}
622
623func (mutator *mutatorInfo) Parallel() MutatorHandle {
624	mutator.parallel = true
625	return mutator
626}
627
628// RegisterEarlyMutator registers a mutator that will be invoked to split
629// Modules into multiple variant Modules before any dependencies have been
630// created.  Each registered mutator is invoked in registration order once
631// per Module (including each variant from previous early mutators).  Module
632// order is unpredictable.
633//
634// In order for dependencies to be satisifed in a later pass, all dependencies
635// of a module either must have an identical variant or must have no variations.
636//
637// The mutator type names given here must be unique to all bottom up or early
638// mutators in the Context.
639//
640// Deprecated, use a BottomUpMutator instead.  The only difference between
641// EarlyMutator and BottomUpMutator is that EarlyMutator runs before the
642// deprecated DynamicDependencies.
643func (c *Context) RegisterEarlyMutator(name string, mutator EarlyMutator) {
644	for _, m := range c.variantMutatorNames {
645		if m == name {
646			panic(fmt.Errorf("mutator name %s is already registered", name))
647		}
648	}
649
650	c.earlyMutatorInfo = append(c.earlyMutatorInfo, &mutatorInfo{
651		bottomUpMutator: func(mctx BottomUpMutatorContext) {
652			mutator(mctx)
653		},
654		name: name,
655	})
656
657	c.variantMutatorNames = append(c.variantMutatorNames, name)
658}
659
660// SetIgnoreUnknownModuleTypes sets the behavior of the context in the case
661// where it encounters an unknown module type while parsing Blueprints files. By
662// default, the context will report unknown module types as an error.  If this
663// method is called with ignoreUnknownModuleTypes set to true then the context
664// will silently ignore unknown module types.
665//
666// This method should generally not be used.  It exists to facilitate the
667// bootstrapping process.
668func (c *Context) SetIgnoreUnknownModuleTypes(ignoreUnknownModuleTypes bool) {
669	c.ignoreUnknownModuleTypes = ignoreUnknownModuleTypes
670}
671
672// SetAllowMissingDependencies changes the behavior of Blueprint to ignore
673// unresolved dependencies.  If the module's GenerateBuildActions calls
674// ModuleContext.GetMissingDependencies Blueprint will not emit any errors
675// for missing dependencies.
676func (c *Context) SetAllowMissingDependencies(allowMissingDependencies bool) {
677	c.allowMissingDependencies = allowMissingDependencies
678}
679
680func (c *Context) SetModuleListFile(listFile string) {
681	c.moduleListFile = listFile
682}
683
684func (c *Context) ListModulePaths(baseDir string) (paths []string, err error) {
685	reader, err := c.fs.Open(c.moduleListFile)
686	if err != nil {
687		return nil, err
688	}
689	bytes, err := ioutil.ReadAll(reader)
690	if err != nil {
691		return nil, err
692	}
693	text := string(bytes)
694
695	text = strings.Trim(text, "\n")
696	lines := strings.Split(text, "\n")
697	for i := range lines {
698		lines[i] = filepath.Join(baseDir, lines[i])
699	}
700
701	return lines, nil
702}
703
704// a fileParseContext tells the status of parsing a particular file
705type fileParseContext struct {
706	// name of file
707	fileName string
708
709	// scope to use when resolving variables
710	Scope *parser.Scope
711
712	// pointer to the one in the parent directory
713	parent *fileParseContext
714
715	// is closed once FileHandler has completed for this file
716	doneVisiting chan struct{}
717}
718
719// ParseBlueprintsFiles parses a set of Blueprints files starting with the file
720// at rootFile.  When it encounters a Blueprints file with a set of subdirs
721// listed it recursively parses any Blueprints files found in those
722// subdirectories.
723//
724// If no errors are encountered while parsing the files, the list of paths on
725// which the future output will depend is returned.  This list will include both
726// Blueprints file paths as well as directory paths for cases where wildcard
727// subdirs are found.
728func (c *Context) ParseBlueprintsFiles(rootFile string,
729	config interface{}) (deps []string, errs []error) {
730
731	baseDir := filepath.Dir(rootFile)
732	pathsToParse, err := c.ListModulePaths(baseDir)
733	if err != nil {
734		return nil, []error{err}
735	}
736	return c.ParseFileList(baseDir, pathsToParse, config)
737}
738
739func (c *Context) ParseFileList(rootDir string, filePaths []string,
740	config interface{}) (deps []string, errs []error) {
741
742	if len(filePaths) < 1 {
743		return nil, []error{fmt.Errorf("no paths provided to parse")}
744	}
745
746	c.dependenciesReady = false
747
748	type newModuleInfo struct {
749		*moduleInfo
750		deps  []string
751		added chan<- struct{}
752	}
753
754	moduleCh := make(chan newModuleInfo)
755	errsCh := make(chan []error)
756	doneCh := make(chan struct{})
757	var numErrs uint32
758	var numGoroutines int32
759
760	// handler must be reentrant
761	handleOneFile := func(file *parser.File) {
762		if atomic.LoadUint32(&numErrs) > maxErrors {
763			return
764		}
765
766		addedCh := make(chan struct{})
767
768		var scopedModuleFactories map[string]ModuleFactory
769
770		var addModule func(module *moduleInfo) []error
771		addModule = func(module *moduleInfo) []error {
772			// Run any load hooks immediately before it is sent to the moduleCh and is
773			// registered by name. This allows load hooks to set and/or modify any aspect
774			// of the module (including names) using information that is not available when
775			// the module factory is called.
776			newModules, newDeps, errs := runAndRemoveLoadHooks(c, config, module, &scopedModuleFactories)
777			if len(errs) > 0 {
778				return errs
779			}
780
781			moduleCh <- newModuleInfo{module, newDeps, addedCh}
782			<-addedCh
783			for _, n := range newModules {
784				errs = addModule(n)
785				if len(errs) > 0 {
786					return errs
787				}
788			}
789			return nil
790		}
791
792		for _, def := range file.Defs {
793			switch def := def.(type) {
794			case *parser.Module:
795				module, errs := processModuleDef(def, file.Name, c.moduleFactories, scopedModuleFactories, c.ignoreUnknownModuleTypes)
796				if len(errs) == 0 && module != nil {
797					errs = addModule(module)
798				}
799
800				if len(errs) > 0 {
801					atomic.AddUint32(&numErrs, uint32(len(errs)))
802					errsCh <- errs
803				}
804
805			case *parser.Assignment:
806				// Already handled via Scope object
807			default:
808				panic("unknown definition type")
809			}
810
811		}
812	}
813
814	atomic.AddInt32(&numGoroutines, 1)
815	go func() {
816		var errs []error
817		deps, errs = c.WalkBlueprintsFiles(rootDir, filePaths, handleOneFile)
818		if len(errs) > 0 {
819			errsCh <- errs
820		}
821		doneCh <- struct{}{}
822	}()
823
824	var hookDeps []string
825loop:
826	for {
827		select {
828		case newErrs := <-errsCh:
829			errs = append(errs, newErrs...)
830		case module := <-moduleCh:
831			newErrs := c.addModule(module.moduleInfo)
832			hookDeps = append(hookDeps, module.deps...)
833			if module.added != nil {
834				module.added <- struct{}{}
835			}
836			if len(newErrs) > 0 {
837				errs = append(errs, newErrs...)
838			}
839		case <-doneCh:
840			n := atomic.AddInt32(&numGoroutines, -1)
841			if n == 0 {
842				break loop
843			}
844		}
845	}
846
847	deps = append(deps, hookDeps...)
848	return deps, errs
849}
850
851type FileHandler func(*parser.File)
852
853// WalkBlueprintsFiles walks a set of Blueprints files starting with the given filepaths,
854// calling the given file handler on each
855//
856// When WalkBlueprintsFiles encounters a Blueprints file with a set of subdirs listed,
857// it recursively parses any Blueprints files found in those subdirectories.
858//
859// If any of the file paths is an ancestor directory of any other of file path, the ancestor
860// will be parsed and visited first.
861//
862// the file handler will be called from a goroutine, so it must be reentrant.
863//
864// If no errors are encountered while parsing the files, the list of paths on
865// which the future output will depend is returned.  This list will include both
866// Blueprints file paths as well as directory paths for cases where wildcard
867// subdirs are found.
868//
869// visitor will be called asynchronously, and will only be called once visitor for each
870// ancestor directory has completed.
871//
872// WalkBlueprintsFiles will not return until all calls to visitor have returned.
873func (c *Context) WalkBlueprintsFiles(rootDir string, filePaths []string,
874	visitor FileHandler) (deps []string, errs []error) {
875
876	// make a mapping from ancestors to their descendants to facilitate parsing ancestors first
877	descendantsMap, err := findBlueprintDescendants(filePaths)
878	if err != nil {
879		panic(err.Error())
880	}
881	blueprintsSet := make(map[string]bool)
882
883	// Channels to receive data back from openAndParse goroutines
884	blueprintsCh := make(chan fileParseContext)
885	errsCh := make(chan []error)
886	depsCh := make(chan string)
887
888	// Channel to notify main loop that a openAndParse goroutine has finished
889	doneParsingCh := make(chan fileParseContext)
890
891	// Number of outstanding goroutines to wait for
892	activeCount := 0
893	var pending []fileParseContext
894	tooManyErrors := false
895
896	// Limit concurrent calls to parseBlueprintFiles to 200
897	// Darwin has a default limit of 256 open files
898	maxActiveCount := 200
899
900	// count the number of pending calls to visitor()
901	visitorWaitGroup := sync.WaitGroup{}
902
903	startParseBlueprintsFile := func(blueprint fileParseContext) {
904		if blueprintsSet[blueprint.fileName] {
905			return
906		}
907		blueprintsSet[blueprint.fileName] = true
908		activeCount++
909		deps = append(deps, blueprint.fileName)
910		visitorWaitGroup.Add(1)
911		go func() {
912			file, blueprints, deps, errs := c.openAndParse(blueprint.fileName, blueprint.Scope, rootDir,
913				&blueprint)
914			if len(errs) > 0 {
915				errsCh <- errs
916			}
917			for _, blueprint := range blueprints {
918				blueprintsCh <- blueprint
919			}
920			for _, dep := range deps {
921				depsCh <- dep
922			}
923			doneParsingCh <- blueprint
924
925			if blueprint.parent != nil && blueprint.parent.doneVisiting != nil {
926				// wait for visitor() of parent to complete
927				<-blueprint.parent.doneVisiting
928			}
929
930			if len(errs) == 0 {
931				// process this file
932				visitor(file)
933			}
934			if blueprint.doneVisiting != nil {
935				close(blueprint.doneVisiting)
936			}
937			visitorWaitGroup.Done()
938		}()
939	}
940
941	foundParseableBlueprint := func(blueprint fileParseContext) {
942		if activeCount >= maxActiveCount {
943			pending = append(pending, blueprint)
944		} else {
945			startParseBlueprintsFile(blueprint)
946		}
947	}
948
949	startParseDescendants := func(blueprint fileParseContext) {
950		descendants, hasDescendants := descendantsMap[blueprint.fileName]
951		if hasDescendants {
952			for _, descendant := range descendants {
953				foundParseableBlueprint(fileParseContext{descendant, parser.NewScope(blueprint.Scope), &blueprint, make(chan struct{})})
954			}
955		}
956	}
957
958	// begin parsing any files that have no ancestors
959	startParseDescendants(fileParseContext{"", parser.NewScope(nil), nil, nil})
960
961loop:
962	for {
963		if len(errs) > maxErrors {
964			tooManyErrors = true
965		}
966
967		select {
968		case newErrs := <-errsCh:
969			errs = append(errs, newErrs...)
970		case dep := <-depsCh:
971			deps = append(deps, dep)
972		case blueprint := <-blueprintsCh:
973			if tooManyErrors {
974				continue
975			}
976			foundParseableBlueprint(blueprint)
977		case blueprint := <-doneParsingCh:
978			activeCount--
979			if !tooManyErrors {
980				startParseDescendants(blueprint)
981			}
982			if activeCount < maxActiveCount && len(pending) > 0 {
983				// start to process the next one from the queue
984				next := pending[len(pending)-1]
985				pending = pending[:len(pending)-1]
986				startParseBlueprintsFile(next)
987			}
988			if activeCount == 0 {
989				break loop
990			}
991		}
992	}
993
994	sort.Strings(deps)
995
996	// wait for every visitor() to complete
997	visitorWaitGroup.Wait()
998
999	return
1000}
1001
1002// MockFileSystem causes the Context to replace all reads with accesses to the provided map of
1003// filenames to contents stored as a byte slice.
1004func (c *Context) MockFileSystem(files map[string][]byte) {
1005	// look for a module list file
1006	_, ok := files[MockModuleListFile]
1007	if !ok {
1008		// no module list file specified; find every file named Blueprints
1009		pathsToParse := []string{}
1010		for candidate := range files {
1011			if filepath.Base(candidate) == "Blueprints" {
1012				pathsToParse = append(pathsToParse, candidate)
1013			}
1014		}
1015		if len(pathsToParse) < 1 {
1016			panic(fmt.Sprintf("No Blueprints files found in mock filesystem: %v\n", files))
1017		}
1018		// put the list of Blueprints files into a list file
1019		files[MockModuleListFile] = []byte(strings.Join(pathsToParse, "\n"))
1020	}
1021	c.SetModuleListFile(MockModuleListFile)
1022
1023	// mock the filesystem
1024	c.fs = pathtools.MockFs(files)
1025}
1026
1027func (c *Context) SetFs(fs pathtools.FileSystem) {
1028	c.fs = fs
1029}
1030
1031// openAndParse opens and parses a single Blueprints file, and returns the results
1032func (c *Context) openAndParse(filename string, scope *parser.Scope, rootDir string,
1033	parent *fileParseContext) (file *parser.File,
1034	subBlueprints []fileParseContext, deps []string, errs []error) {
1035
1036	f, err := c.fs.Open(filename)
1037	if err != nil {
1038		// couldn't open the file; see if we can provide a clearer error than "could not open file"
1039		stats, statErr := c.fs.Lstat(filename)
1040		if statErr == nil {
1041			isSymlink := stats.Mode()&os.ModeSymlink != 0
1042			if isSymlink {
1043				err = fmt.Errorf("could not open symlink %v : %v", filename, err)
1044				target, readlinkErr := os.Readlink(filename)
1045				if readlinkErr == nil {
1046					_, targetStatsErr := c.fs.Lstat(target)
1047					if targetStatsErr != nil {
1048						err = fmt.Errorf("could not open symlink %v; its target (%v) cannot be opened", filename, target)
1049					}
1050				}
1051			} else {
1052				err = fmt.Errorf("%v exists but could not be opened: %v", filename, err)
1053			}
1054		}
1055		return nil, nil, nil, []error{err}
1056	}
1057
1058	func() {
1059		defer func() {
1060			err = f.Close()
1061			if err != nil {
1062				errs = append(errs, err)
1063			}
1064		}()
1065		file, subBlueprints, errs = c.parseOne(rootDir, filename, f, scope, parent)
1066	}()
1067
1068	if len(errs) > 0 {
1069		return nil, nil, nil, errs
1070	}
1071
1072	for _, b := range subBlueprints {
1073		deps = append(deps, b.fileName)
1074	}
1075
1076	return file, subBlueprints, deps, nil
1077}
1078
1079// parseOne parses a single Blueprints file from the given reader, creating Module
1080// objects for each of the module definitions encountered.  If the Blueprints
1081// file contains an assignment to the "subdirs" variable, then the
1082// subdirectories listed are searched for Blueprints files returned in the
1083// subBlueprints return value.  If the Blueprints file contains an assignment
1084// to the "build" variable, then the file listed are returned in the
1085// subBlueprints return value.
1086//
1087// rootDir specifies the path to the root directory of the source tree, while
1088// filename specifies the path to the Blueprints file.  These paths are used for
1089// error reporting and for determining the module's directory.
1090func (c *Context) parseOne(rootDir, filename string, reader io.Reader,
1091	scope *parser.Scope, parent *fileParseContext) (file *parser.File, subBlueprints []fileParseContext, errs []error) {
1092
1093	relBlueprintsFile, err := filepath.Rel(rootDir, filename)
1094	if err != nil {
1095		return nil, nil, []error{err}
1096	}
1097
1098	scope.Remove("subdirs")
1099	scope.Remove("optional_subdirs")
1100	scope.Remove("build")
1101	file, errs = parser.ParseAndEval(filename, reader, scope)
1102	if len(errs) > 0 {
1103		for i, err := range errs {
1104			if parseErr, ok := err.(*parser.ParseError); ok {
1105				err = &BlueprintError{
1106					Err: parseErr.Err,
1107					Pos: parseErr.Pos,
1108				}
1109				errs[i] = err
1110			}
1111		}
1112
1113		// If there were any parse errors don't bother trying to interpret the
1114		// result.
1115		return nil, nil, errs
1116	}
1117	file.Name = relBlueprintsFile
1118
1119	build, buildPos, err := getLocalStringListFromScope(scope, "build")
1120	if err != nil {
1121		errs = append(errs, err)
1122	}
1123	for _, buildEntry := range build {
1124		if strings.Contains(buildEntry, "/") {
1125			errs = append(errs, &BlueprintError{
1126				Err: fmt.Errorf("illegal value %v. The '/' character is not permitted", buildEntry),
1127				Pos: buildPos,
1128			})
1129		}
1130	}
1131
1132	subBlueprintsName, _, err := getStringFromScope(scope, "subname")
1133	if err != nil {
1134		errs = append(errs, err)
1135	}
1136
1137	if subBlueprintsName == "" {
1138		subBlueprintsName = "Blueprints"
1139	}
1140
1141	var blueprints []string
1142
1143	newBlueprints, newErrs := c.findBuildBlueprints(filepath.Dir(filename), build, buildPos)
1144	blueprints = append(blueprints, newBlueprints...)
1145	errs = append(errs, newErrs...)
1146
1147	subBlueprintsAndScope := make([]fileParseContext, len(blueprints))
1148	for i, b := range blueprints {
1149		subBlueprintsAndScope[i] = fileParseContext{b, parser.NewScope(scope), parent, make(chan struct{})}
1150	}
1151	return file, subBlueprintsAndScope, errs
1152}
1153
1154func (c *Context) findBuildBlueprints(dir string, build []string,
1155	buildPos scanner.Position) ([]string, []error) {
1156
1157	var blueprints []string
1158	var errs []error
1159
1160	for _, file := range build {
1161		pattern := filepath.Join(dir, file)
1162		var matches []string
1163		var err error
1164
1165		matches, err = c.glob(pattern, nil)
1166
1167		if err != nil {
1168			errs = append(errs, &BlueprintError{
1169				Err: fmt.Errorf("%q: %s", pattern, err.Error()),
1170				Pos: buildPos,
1171			})
1172			continue
1173		}
1174
1175		if len(matches) == 0 {
1176			errs = append(errs, &BlueprintError{
1177				Err: fmt.Errorf("%q: not found", pattern),
1178				Pos: buildPos,
1179			})
1180		}
1181
1182		for _, foundBlueprints := range matches {
1183			if strings.HasSuffix(foundBlueprints, "/") {
1184				errs = append(errs, &BlueprintError{
1185					Err: fmt.Errorf("%q: is a directory", foundBlueprints),
1186					Pos: buildPos,
1187				})
1188			}
1189			blueprints = append(blueprints, foundBlueprints)
1190		}
1191	}
1192
1193	return blueprints, errs
1194}
1195
1196func (c *Context) findSubdirBlueprints(dir string, subdirs []string, subdirsPos scanner.Position,
1197	subBlueprintsName string, optional bool) ([]string, []error) {
1198
1199	var blueprints []string
1200	var errs []error
1201
1202	for _, subdir := range subdirs {
1203		pattern := filepath.Join(dir, subdir, subBlueprintsName)
1204		var matches []string
1205		var err error
1206
1207		matches, err = c.glob(pattern, nil)
1208
1209		if err != nil {
1210			errs = append(errs, &BlueprintError{
1211				Err: fmt.Errorf("%q: %s", pattern, err.Error()),
1212				Pos: subdirsPos,
1213			})
1214			continue
1215		}
1216
1217		if len(matches) == 0 && !optional {
1218			errs = append(errs, &BlueprintError{
1219				Err: fmt.Errorf("%q: not found", pattern),
1220				Pos: subdirsPos,
1221			})
1222		}
1223
1224		for _, subBlueprints := range matches {
1225			if strings.HasSuffix(subBlueprints, "/") {
1226				errs = append(errs, &BlueprintError{
1227					Err: fmt.Errorf("%q: is a directory", subBlueprints),
1228					Pos: subdirsPos,
1229				})
1230			}
1231			blueprints = append(blueprints, subBlueprints)
1232		}
1233	}
1234
1235	return blueprints, errs
1236}
1237
1238func getLocalStringListFromScope(scope *parser.Scope, v string) ([]string, scanner.Position, error) {
1239	if assignment, local := scope.Get(v); assignment == nil || !local {
1240		return nil, scanner.Position{}, nil
1241	} else {
1242		switch value := assignment.Value.Eval().(type) {
1243		case *parser.List:
1244			ret := make([]string, 0, len(value.Values))
1245
1246			for _, listValue := range value.Values {
1247				s, ok := listValue.(*parser.String)
1248				if !ok {
1249					// The parser should not produce this.
1250					panic("non-string value found in list")
1251				}
1252
1253				ret = append(ret, s.Value)
1254			}
1255
1256			return ret, assignment.EqualsPos, nil
1257		case *parser.Bool, *parser.String:
1258			return nil, scanner.Position{}, &BlueprintError{
1259				Err: fmt.Errorf("%q must be a list of strings", v),
1260				Pos: assignment.EqualsPos,
1261			}
1262		default:
1263			panic(fmt.Errorf("unknown value type: %d", assignment.Value.Type()))
1264		}
1265	}
1266}
1267
1268func getStringFromScope(scope *parser.Scope, v string) (string, scanner.Position, error) {
1269	if assignment, _ := scope.Get(v); assignment == nil {
1270		return "", scanner.Position{}, nil
1271	} else {
1272		switch value := assignment.Value.Eval().(type) {
1273		case *parser.String:
1274			return value.Value, assignment.EqualsPos, nil
1275		case *parser.Bool, *parser.List:
1276			return "", scanner.Position{}, &BlueprintError{
1277				Err: fmt.Errorf("%q must be a string", v),
1278				Pos: assignment.EqualsPos,
1279			}
1280		default:
1281			panic(fmt.Errorf("unknown value type: %d", assignment.Value.Type()))
1282		}
1283	}
1284}
1285
1286// Clones a build logic module by calling the factory method for its module type, and then cloning
1287// property values.  Any values stored in the module object that are not stored in properties
1288// structs will be lost.
1289func (c *Context) cloneLogicModule(origModule *moduleInfo) (Module, []interface{}) {
1290	newLogicModule, newProperties := origModule.factory()
1291
1292	if len(newProperties) != len(origModule.properties) {
1293		panic("mismatched properties array length in " + origModule.Name())
1294	}
1295
1296	for i := range newProperties {
1297		dst := reflect.ValueOf(newProperties[i])
1298		src := reflect.ValueOf(origModule.properties[i])
1299
1300		proptools.CopyProperties(dst, src)
1301	}
1302
1303	return newLogicModule, newProperties
1304}
1305
1306func newVariant(module *moduleInfo, mutatorName string, variationName string,
1307	local bool) variant {
1308
1309	newVariantName := module.variant.name
1310	if variationName != "" {
1311		if newVariantName == "" {
1312			newVariantName = variationName
1313		} else {
1314			newVariantName += "_" + variationName
1315		}
1316	}
1317
1318	newVariations := module.variant.variations.clone()
1319	if newVariations == nil {
1320		newVariations = make(variationMap)
1321	}
1322	newVariations[mutatorName] = variationName
1323
1324	newDependencyVariations := module.variant.dependencyVariations.clone()
1325	if !local {
1326		if newDependencyVariations == nil {
1327			newDependencyVariations = make(variationMap)
1328		}
1329		newDependencyVariations[mutatorName] = variationName
1330	}
1331
1332	return variant{newVariantName, newVariations, newDependencyVariations}
1333}
1334
1335func (c *Context) createVariations(origModule *moduleInfo, mutatorName string,
1336	defaultVariationName *string, variationNames []string, local bool) (modulesOrAliases, []error) {
1337
1338	if len(variationNames) == 0 {
1339		panic(fmt.Errorf("mutator %q passed zero-length variation list for module %q",
1340			mutatorName, origModule.Name()))
1341	}
1342
1343	var newModules modulesOrAliases
1344
1345	var errs []error
1346
1347	for i, variationName := range variationNames {
1348		var newLogicModule Module
1349		var newProperties []interface{}
1350
1351		if i == 0 {
1352			// Reuse the existing module for the first new variant
1353			// This both saves creating a new module, and causes the insertion in c.moduleInfo below
1354			// with logicModule as the key to replace the original entry in c.moduleInfo
1355			newLogicModule, newProperties = origModule.logicModule, origModule.properties
1356		} else {
1357			newLogicModule, newProperties = c.cloneLogicModule(origModule)
1358		}
1359
1360		m := *origModule
1361		newModule := &m
1362		newModule.directDeps = append([]depInfo(nil), origModule.directDeps...)
1363		newModule.reverseDeps = nil
1364		newModule.forwardDeps = nil
1365		newModule.logicModule = newLogicModule
1366		newModule.variant = newVariant(origModule, mutatorName, variationName, local)
1367		newModule.properties = newProperties
1368		newModule.providers = append([]interface{}(nil), origModule.providers...)
1369
1370		newModules = append(newModules, newModule)
1371
1372		newErrs := c.convertDepsToVariation(newModule, mutatorName, variationName, defaultVariationName)
1373		if len(newErrs) > 0 {
1374			errs = append(errs, newErrs...)
1375		}
1376	}
1377
1378	// Mark original variant as invalid.  Modules that depend on this module will still
1379	// depend on origModule, but we'll fix it when the mutator is called on them.
1380	origModule.logicModule = nil
1381	origModule.splitModules = newModules
1382
1383	atomic.AddUint32(&c.depsModified, 1)
1384
1385	return newModules, errs
1386}
1387
1388func (c *Context) convertDepsToVariation(module *moduleInfo,
1389	mutatorName, variationName string, defaultVariationName *string) (errs []error) {
1390
1391	for i, dep := range module.directDeps {
1392		if dep.module.logicModule == nil {
1393			var newDep *moduleInfo
1394			for _, m := range dep.module.splitModules {
1395				if m.moduleOrAliasVariant().variations[mutatorName] == variationName {
1396					newDep = m.moduleOrAliasTarget()
1397					break
1398				}
1399			}
1400			if newDep == nil && defaultVariationName != nil {
1401				// give it a second chance; match with defaultVariationName
1402				for _, m := range dep.module.splitModules {
1403					if m.moduleOrAliasVariant().variations[mutatorName] == *defaultVariationName {
1404						newDep = m.moduleOrAliasTarget()
1405						break
1406					}
1407				}
1408			}
1409			if newDep == nil {
1410				errs = append(errs, &BlueprintError{
1411					Err: fmt.Errorf("failed to find variation %q for module %q needed by %q",
1412						variationName, dep.module.Name(), module.Name()),
1413					Pos: module.pos,
1414				})
1415				continue
1416			}
1417			module.directDeps[i].module = newDep
1418		}
1419	}
1420
1421	return errs
1422}
1423
1424func (c *Context) prettyPrintVariant(variations variationMap) string {
1425	names := make([]string, 0, len(variations))
1426	for _, m := range c.variantMutatorNames {
1427		if v, ok := variations[m]; ok {
1428			names = append(names, m+":"+v)
1429		}
1430	}
1431
1432	return strings.Join(names, ",")
1433}
1434
1435func (c *Context) prettyPrintGroupVariants(group *moduleGroup) string {
1436	var variants []string
1437	for _, moduleOrAlias := range group.modules {
1438		if mod := moduleOrAlias.module(); mod != nil {
1439			variants = append(variants, c.prettyPrintVariant(mod.variant.variations))
1440		} else if alias := moduleOrAlias.alias(); alias != nil {
1441			variants = append(variants, c.prettyPrintVariant(alias.variant.variations)+
1442				" (alias to "+c.prettyPrintVariant(alias.target.variant.variations)+")")
1443		}
1444	}
1445	return strings.Join(variants, "\n  ")
1446}
1447
1448func newModule(factory ModuleFactory) *moduleInfo {
1449	logicModule, properties := factory()
1450
1451	module := &moduleInfo{
1452		logicModule: logicModule,
1453		factory:     factory,
1454	}
1455
1456	module.properties = properties
1457
1458	return module
1459}
1460
1461func processModuleDef(moduleDef *parser.Module,
1462	relBlueprintsFile string, moduleFactories, scopedModuleFactories map[string]ModuleFactory, ignoreUnknownModuleTypes bool) (*moduleInfo, []error) {
1463
1464	factory, ok := moduleFactories[moduleDef.Type]
1465	if !ok && scopedModuleFactories != nil {
1466		factory, ok = scopedModuleFactories[moduleDef.Type]
1467	}
1468	if !ok {
1469		if ignoreUnknownModuleTypes {
1470			return nil, nil
1471		}
1472
1473		return nil, []error{
1474			&BlueprintError{
1475				Err: fmt.Errorf("unrecognized module type %q", moduleDef.Type),
1476				Pos: moduleDef.TypePos,
1477			},
1478		}
1479	}
1480
1481	module := newModule(factory)
1482	module.typeName = moduleDef.Type
1483
1484	module.relBlueprintsFile = relBlueprintsFile
1485
1486	propertyMap, errs := proptools.UnpackProperties(moduleDef.Properties, module.properties...)
1487	if len(errs) > 0 {
1488		for i, err := range errs {
1489			if unpackErr, ok := err.(*proptools.UnpackError); ok {
1490				err = &BlueprintError{
1491					Err: unpackErr.Err,
1492					Pos: unpackErr.Pos,
1493				}
1494				errs[i] = err
1495			}
1496		}
1497		return nil, errs
1498	}
1499
1500	module.pos = moduleDef.TypePos
1501	module.propertyPos = make(map[string]scanner.Position)
1502	for name, propertyDef := range propertyMap {
1503		module.propertyPos[name] = propertyDef.ColonPos
1504	}
1505
1506	return module, nil
1507}
1508
1509func (c *Context) addModule(module *moduleInfo) []error {
1510	name := module.logicModule.Name()
1511	if name == "" {
1512		return []error{
1513			&BlueprintError{
1514				Err: fmt.Errorf("property 'name' is missing from a module"),
1515				Pos: module.pos,
1516			},
1517		}
1518	}
1519	c.moduleInfo[module.logicModule] = module
1520
1521	group := &moduleGroup{
1522		name:    name,
1523		modules: modulesOrAliases{module},
1524	}
1525	module.group = group
1526	namespace, errs := c.nameInterface.NewModule(
1527		newNamespaceContext(module),
1528		ModuleGroup{moduleGroup: group},
1529		module.logicModule)
1530	if len(errs) > 0 {
1531		for i := range errs {
1532			errs[i] = &BlueprintError{Err: errs[i], Pos: module.pos}
1533		}
1534		return errs
1535	}
1536	group.namespace = namespace
1537
1538	c.moduleGroups = append(c.moduleGroups, group)
1539
1540	return nil
1541}
1542
1543// ResolveDependencies checks that the dependencies specified by all of the
1544// modules defined in the parsed Blueprints files are valid.  This means that
1545// the modules depended upon are defined and that no circular dependencies
1546// exist.
1547func (c *Context) ResolveDependencies(config interface{}) (deps []string, errs []error) {
1548	return c.resolveDependencies(c.Context, config)
1549}
1550
1551func (c *Context) resolveDependencies(ctx context.Context, config interface{}) (deps []string, errs []error) {
1552	pprof.Do(ctx, pprof.Labels("blueprint", "ResolveDependencies"), func(ctx context.Context) {
1553		c.initProviders()
1554
1555		c.liveGlobals = newLiveTracker(config)
1556
1557		deps, errs = c.generateSingletonBuildActions(config, c.preSingletonInfo, c.liveGlobals)
1558		if len(errs) > 0 {
1559			return
1560		}
1561
1562		errs = c.updateDependencies()
1563		if len(errs) > 0 {
1564			return
1565		}
1566
1567		var mutatorDeps []string
1568		mutatorDeps, errs = c.runMutators(ctx, config)
1569		if len(errs) > 0 {
1570			return
1571		}
1572		deps = append(deps, mutatorDeps...)
1573
1574		if !c.skipCloneModulesAfterMutators {
1575			c.cloneModules()
1576		}
1577
1578		c.dependenciesReady = true
1579	})
1580
1581	if len(errs) > 0 {
1582		return nil, errs
1583	}
1584
1585	return deps, nil
1586}
1587
1588// Default dependencies handling.  If the module implements the (deprecated)
1589// DynamicDependerModule interface then this set consists of the union of those
1590// module names returned by its DynamicDependencies method and those added by calling
1591// AddDependencies or AddVariationDependencies on DynamicDependencyModuleContext.
1592func blueprintDepsMutator(ctx BottomUpMutatorContext) {
1593	if dynamicDepender, ok := ctx.Module().(DynamicDependerModule); ok {
1594		func() {
1595			defer func() {
1596				if r := recover(); r != nil {
1597					ctx.error(newPanicErrorf(r, "DynamicDependencies for %s", ctx.moduleInfo()))
1598				}
1599			}()
1600			dynamicDeps := dynamicDepender.DynamicDependencies(ctx)
1601
1602			if ctx.Failed() {
1603				return
1604			}
1605
1606			ctx.AddDependency(ctx.Module(), nil, dynamicDeps...)
1607		}()
1608	}
1609}
1610
1611// findExactVariantOrSingle searches the moduleGroup for a module with the same variant as module,
1612// and returns the matching module, or nil if one is not found.  A group with exactly one module
1613// is always considered matching.
1614func findExactVariantOrSingle(module *moduleInfo, possible *moduleGroup, reverse bool) *moduleInfo {
1615	found, _ := findVariant(module, possible, nil, false, reverse)
1616	if found == nil {
1617		for _, moduleOrAlias := range possible.modules {
1618			if m := moduleOrAlias.module(); m != nil {
1619				if found != nil {
1620					// more than one possible match, give up
1621					return nil
1622				}
1623				found = m
1624			}
1625		}
1626	}
1627	return found
1628}
1629
1630func (c *Context) addDependency(module *moduleInfo, tag DependencyTag, depName string) (*moduleInfo, []error) {
1631	if _, ok := tag.(BaseDependencyTag); ok {
1632		panic("BaseDependencyTag is not allowed to be used directly!")
1633	}
1634
1635	if depName == module.Name() {
1636		return nil, []error{&BlueprintError{
1637			Err: fmt.Errorf("%q depends on itself", depName),
1638			Pos: module.pos,
1639		}}
1640	}
1641
1642	possibleDeps := c.moduleGroupFromName(depName, module.namespace())
1643	if possibleDeps == nil {
1644		return nil, c.discoveredMissingDependencies(module, depName, nil)
1645	}
1646
1647	if m := findExactVariantOrSingle(module, possibleDeps, false); m != nil {
1648		module.newDirectDeps = append(module.newDirectDeps, depInfo{m, tag})
1649		atomic.AddUint32(&c.depsModified, 1)
1650		return m, nil
1651	}
1652
1653	if c.allowMissingDependencies {
1654		// Allow missing variants.
1655		return nil, c.discoveredMissingDependencies(module, depName, module.variant.dependencyVariations)
1656	}
1657
1658	return nil, []error{&BlueprintError{
1659		Err: fmt.Errorf("dependency %q of %q missing variant:\n  %s\navailable variants:\n  %s",
1660			depName, module.Name(),
1661			c.prettyPrintVariant(module.variant.dependencyVariations),
1662			c.prettyPrintGroupVariants(possibleDeps)),
1663		Pos: module.pos,
1664	}}
1665}
1666
1667func (c *Context) findReverseDependency(module *moduleInfo, destName string) (*moduleInfo, []error) {
1668	if destName == module.Name() {
1669		return nil, []error{&BlueprintError{
1670			Err: fmt.Errorf("%q depends on itself", destName),
1671			Pos: module.pos,
1672		}}
1673	}
1674
1675	possibleDeps := c.moduleGroupFromName(destName, module.namespace())
1676	if possibleDeps == nil {
1677		return nil, []error{&BlueprintError{
1678			Err: fmt.Errorf("%q has a reverse dependency on undefined module %q",
1679				module.Name(), destName),
1680			Pos: module.pos,
1681		}}
1682	}
1683
1684	if m := findExactVariantOrSingle(module, possibleDeps, true); m != nil {
1685		return m, nil
1686	}
1687
1688	if c.allowMissingDependencies {
1689		// Allow missing variants.
1690		return module, c.discoveredMissingDependencies(module, destName, module.variant.dependencyVariations)
1691	}
1692
1693	return nil, []error{&BlueprintError{
1694		Err: fmt.Errorf("reverse dependency %q of %q missing variant:\n  %s\navailable variants:\n  %s",
1695			destName, module.Name(),
1696			c.prettyPrintVariant(module.variant.dependencyVariations),
1697			c.prettyPrintGroupVariants(possibleDeps)),
1698		Pos: module.pos,
1699	}}
1700}
1701
1702func findVariant(module *moduleInfo, possibleDeps *moduleGroup, variations []Variation, far bool, reverse bool) (*moduleInfo, variationMap) {
1703	// We can't just append variant.Variant to module.dependencyVariant.variantName and
1704	// compare the strings because the result won't be in mutator registration order.
1705	// Create a new map instead, and then deep compare the maps.
1706	var newVariant variationMap
1707	if !far {
1708		if !reverse {
1709			// For forward dependency, ignore local variants by matching against
1710			// dependencyVariant which doesn't have the local variants
1711			newVariant = module.variant.dependencyVariations.clone()
1712		} else {
1713			// For reverse dependency, use all the variants
1714			newVariant = module.variant.variations.clone()
1715		}
1716	}
1717	for _, v := range variations {
1718		if newVariant == nil {
1719			newVariant = make(variationMap)
1720		}
1721		newVariant[v.Mutator] = v.Variation
1722	}
1723
1724	check := func(variant variationMap) bool {
1725		if far {
1726			return newVariant.subsetOf(variant)
1727		} else {
1728			return variant.equal(newVariant)
1729		}
1730	}
1731
1732	var foundDep *moduleInfo
1733	for _, m := range possibleDeps.modules {
1734		if check(m.moduleOrAliasVariant().variations) {
1735			foundDep = m.moduleOrAliasTarget()
1736			break
1737		}
1738	}
1739
1740	return foundDep, newVariant
1741}
1742
1743func (c *Context) addVariationDependency(module *moduleInfo, variations []Variation,
1744	tag DependencyTag, depName string, far bool) (*moduleInfo, []error) {
1745	if _, ok := tag.(BaseDependencyTag); ok {
1746		panic("BaseDependencyTag is not allowed to be used directly!")
1747	}
1748
1749	possibleDeps := c.moduleGroupFromName(depName, module.namespace())
1750	if possibleDeps == nil {
1751		return nil, c.discoveredMissingDependencies(module, depName, nil)
1752	}
1753
1754	foundDep, newVariant := findVariant(module, possibleDeps, variations, far, false)
1755
1756	if foundDep == nil {
1757		if c.allowMissingDependencies {
1758			// Allow missing variants.
1759			return nil, c.discoveredMissingDependencies(module, depName, newVariant)
1760		}
1761		return nil, []error{&BlueprintError{
1762			Err: fmt.Errorf("dependency %q of %q missing variant:\n  %s\navailable variants:\n  %s",
1763				depName, module.Name(),
1764				c.prettyPrintVariant(newVariant),
1765				c.prettyPrintGroupVariants(possibleDeps)),
1766			Pos: module.pos,
1767		}}
1768	}
1769
1770	if module == foundDep {
1771		return nil, []error{&BlueprintError{
1772			Err: fmt.Errorf("%q depends on itself", depName),
1773			Pos: module.pos,
1774		}}
1775	}
1776	// AddVariationDependency allows adding a dependency on itself, but only if
1777	// that module is earlier in the module list than this one, since we always
1778	// run GenerateBuildActions in order for the variants of a module
1779	if foundDep.group == module.group && beforeInModuleList(module, foundDep, module.group.modules) {
1780		return nil, []error{&BlueprintError{
1781			Err: fmt.Errorf("%q depends on later version of itself", depName),
1782			Pos: module.pos,
1783		}}
1784	}
1785	module.newDirectDeps = append(module.newDirectDeps, depInfo{foundDep, tag})
1786	atomic.AddUint32(&c.depsModified, 1)
1787	return foundDep, nil
1788}
1789
1790func (c *Context) addInterVariantDependency(origModule *moduleInfo, tag DependencyTag,
1791	from, to Module) *moduleInfo {
1792	if _, ok := tag.(BaseDependencyTag); ok {
1793		panic("BaseDependencyTag is not allowed to be used directly!")
1794	}
1795
1796	var fromInfo, toInfo *moduleInfo
1797	for _, moduleOrAlias := range origModule.splitModules {
1798		if m := moduleOrAlias.module(); m != nil {
1799			if m.logicModule == from {
1800				fromInfo = m
1801			}
1802			if m.logicModule == to {
1803				toInfo = m
1804				if fromInfo != nil {
1805					panic(fmt.Errorf("%q depends on later version of itself", origModule.Name()))
1806				}
1807			}
1808		}
1809	}
1810
1811	if fromInfo == nil || toInfo == nil {
1812		panic(fmt.Errorf("AddInterVariantDependency called for module %q on invalid variant",
1813			origModule.Name()))
1814	}
1815
1816	fromInfo.newDirectDeps = append(fromInfo.newDirectDeps, depInfo{toInfo, tag})
1817	atomic.AddUint32(&c.depsModified, 1)
1818	return toInfo
1819}
1820
1821// findBlueprintDescendants returns a map linking parent Blueprints files to child Blueprints files
1822// For example, if paths = []string{"a/b/c/Android.bp", "a/Blueprints"},
1823// then descendants = {"":[]string{"a/Blueprints"}, "a/Blueprints":[]string{"a/b/c/Android.bp"}}
1824func findBlueprintDescendants(paths []string) (descendants map[string][]string, err error) {
1825	// make mapping from dir path to file path
1826	filesByDir := make(map[string]string, len(paths))
1827	for _, path := range paths {
1828		dir := filepath.Dir(path)
1829		_, alreadyFound := filesByDir[dir]
1830		if alreadyFound {
1831			return nil, fmt.Errorf("Found two Blueprint files in directory %v : %v and %v", dir, filesByDir[dir], path)
1832		}
1833		filesByDir[dir] = path
1834	}
1835
1836	findAncestor := func(childFile string) (ancestor string) {
1837		prevAncestorDir := filepath.Dir(childFile)
1838		for {
1839			ancestorDir := filepath.Dir(prevAncestorDir)
1840			if ancestorDir == prevAncestorDir {
1841				// reached the root dir without any matches; assign this as a descendant of ""
1842				return ""
1843			}
1844
1845			ancestorFile, ancestorExists := filesByDir[ancestorDir]
1846			if ancestorExists {
1847				return ancestorFile
1848			}
1849			prevAncestorDir = ancestorDir
1850		}
1851	}
1852	// generate the descendants map
1853	descendants = make(map[string][]string, len(filesByDir))
1854	for _, childFile := range filesByDir {
1855		ancestorFile := findAncestor(childFile)
1856		descendants[ancestorFile] = append(descendants[ancestorFile], childFile)
1857	}
1858	return descendants, nil
1859}
1860
1861type visitOrderer interface {
1862	// returns the number of modules that this module needs to wait for
1863	waitCount(module *moduleInfo) int
1864	// returns the list of modules that are waiting for this module
1865	propagate(module *moduleInfo) []*moduleInfo
1866	// visit modules in order
1867	visit(modules []*moduleInfo, visit func(*moduleInfo, chan<- pauseSpec) bool)
1868}
1869
1870type unorderedVisitorImpl struct{}
1871
1872func (unorderedVisitorImpl) waitCount(module *moduleInfo) int {
1873	return 0
1874}
1875
1876func (unorderedVisitorImpl) propagate(module *moduleInfo) []*moduleInfo {
1877	return nil
1878}
1879
1880func (unorderedVisitorImpl) visit(modules []*moduleInfo, visit func(*moduleInfo, chan<- pauseSpec) bool) {
1881	for _, module := range modules {
1882		if visit(module, nil) {
1883			return
1884		}
1885	}
1886}
1887
1888type bottomUpVisitorImpl struct{}
1889
1890func (bottomUpVisitorImpl) waitCount(module *moduleInfo) int {
1891	return len(module.forwardDeps)
1892}
1893
1894func (bottomUpVisitorImpl) propagate(module *moduleInfo) []*moduleInfo {
1895	return module.reverseDeps
1896}
1897
1898func (bottomUpVisitorImpl) visit(modules []*moduleInfo, visit func(*moduleInfo, chan<- pauseSpec) bool) {
1899	for _, module := range modules {
1900		if visit(module, nil) {
1901			return
1902		}
1903	}
1904}
1905
1906type topDownVisitorImpl struct{}
1907
1908func (topDownVisitorImpl) waitCount(module *moduleInfo) int {
1909	return len(module.reverseDeps)
1910}
1911
1912func (topDownVisitorImpl) propagate(module *moduleInfo) []*moduleInfo {
1913	return module.forwardDeps
1914}
1915
1916func (topDownVisitorImpl) visit(modules []*moduleInfo, visit func(*moduleInfo, chan<- pauseSpec) bool) {
1917	for i := 0; i < len(modules); i++ {
1918		module := modules[len(modules)-1-i]
1919		if visit(module, nil) {
1920			return
1921		}
1922	}
1923}
1924
1925var (
1926	bottomUpVisitor bottomUpVisitorImpl
1927	topDownVisitor  topDownVisitorImpl
1928)
1929
1930// pauseSpec describes a pause that a module needs to occur until another module has been visited,
1931// at which point the unpause channel will be closed.
1932type pauseSpec struct {
1933	paused  *moduleInfo
1934	until   *moduleInfo
1935	unpause unpause
1936}
1937
1938type unpause chan struct{}
1939
1940const parallelVisitLimit = 1000
1941
1942// Calls visit on each module, guaranteeing that visit is not called on a module until visit on all
1943// of its dependencies has finished.  A visit function can write a pauseSpec to the pause channel
1944// to wait for another dependency to be visited.  If a visit function returns true to cancel
1945// while another visitor is paused, the paused visitor will never be resumed and its goroutine
1946// will stay paused forever.
1947func parallelVisit(modules []*moduleInfo, order visitOrderer, limit int,
1948	visit func(module *moduleInfo, pause chan<- pauseSpec) bool) []error {
1949
1950	doneCh := make(chan *moduleInfo)
1951	cancelCh := make(chan bool)
1952	pauseCh := make(chan pauseSpec)
1953	cancel := false
1954
1955	var backlog []*moduleInfo      // Visitors that are ready to start but backlogged due to limit.
1956	var unpauseBacklog []pauseSpec // Visitors that are ready to unpause but backlogged due to limit.
1957
1958	active := 0  // Number of visitors running, not counting paused visitors.
1959	visited := 0 // Number of finished visitors.
1960
1961	pauseMap := make(map[*moduleInfo][]pauseSpec)
1962
1963	for _, module := range modules {
1964		module.waitingCount = order.waitCount(module)
1965	}
1966
1967	// Call the visitor on a module if there are fewer active visitors than the parallelism
1968	// limit, otherwise add it to the backlog.
1969	startOrBacklog := func(module *moduleInfo) {
1970		if active < limit {
1971			active++
1972			go func() {
1973				ret := visit(module, pauseCh)
1974				if ret {
1975					cancelCh <- true
1976				}
1977				doneCh <- module
1978			}()
1979		} else {
1980			backlog = append(backlog, module)
1981		}
1982	}
1983
1984	// Unpause the already-started but paused  visitor on a module if there are fewer active
1985	// visitors than the parallelism limit, otherwise add it to the backlog.
1986	unpauseOrBacklog := func(pauseSpec pauseSpec) {
1987		if active < limit {
1988			active++
1989			close(pauseSpec.unpause)
1990		} else {
1991			unpauseBacklog = append(unpauseBacklog, pauseSpec)
1992		}
1993	}
1994
1995	// Start any modules in the backlog up to the parallelism limit.  Unpause paused modules first
1996	// since they may already be holding resources.
1997	unpauseOrStartFromBacklog := func() {
1998		for active < limit && len(unpauseBacklog) > 0 {
1999			unpause := unpauseBacklog[0]
2000			unpauseBacklog = unpauseBacklog[1:]
2001			unpauseOrBacklog(unpause)
2002		}
2003		for active < limit && len(backlog) > 0 {
2004			toVisit := backlog[0]
2005			backlog = backlog[1:]
2006			startOrBacklog(toVisit)
2007		}
2008	}
2009
2010	toVisit := len(modules)
2011
2012	// Start or backlog any modules that are not waiting for any other modules.
2013	for _, module := range modules {
2014		if module.waitingCount == 0 {
2015			startOrBacklog(module)
2016		}
2017	}
2018
2019	for active > 0 {
2020		select {
2021		case <-cancelCh:
2022			cancel = true
2023			backlog = nil
2024		case doneModule := <-doneCh:
2025			active--
2026			if !cancel {
2027				// Mark this module as done.
2028				doneModule.waitingCount = -1
2029				visited++
2030
2031				// Unpause or backlog any modules that were waiting for this one.
2032				if unpauses, ok := pauseMap[doneModule]; ok {
2033					delete(pauseMap, doneModule)
2034					for _, unpause := range unpauses {
2035						unpauseOrBacklog(unpause)
2036					}
2037				}
2038
2039				// Start any backlogged modules up to limit.
2040				unpauseOrStartFromBacklog()
2041
2042				// Decrement waitingCount on the next modules in the tree based
2043				// on propagation order, and start or backlog them if they are
2044				// ready to start.
2045				for _, module := range order.propagate(doneModule) {
2046					module.waitingCount--
2047					if module.waitingCount == 0 {
2048						startOrBacklog(module)
2049					}
2050				}
2051			}
2052		case pauseSpec := <-pauseCh:
2053			if pauseSpec.until.waitingCount == -1 {
2054				// Module being paused for is already finished, resume immediately.
2055				close(pauseSpec.unpause)
2056			} else {
2057				// Register for unpausing.
2058				pauseMap[pauseSpec.until] = append(pauseMap[pauseSpec.until], pauseSpec)
2059
2060				// Don't count paused visitors as active so that this can't deadlock
2061				// if 1000 visitors are paused simultaneously.
2062				active--
2063				unpauseOrStartFromBacklog()
2064			}
2065		}
2066	}
2067
2068	if !cancel {
2069		// Invariant check: no backlogged modules, these weren't waiting on anything except
2070		// the parallelism limit so they should have run.
2071		if len(backlog) > 0 {
2072			panic(fmt.Errorf("parallelVisit finished with %d backlogged visitors", len(backlog)))
2073		}
2074
2075		// Invariant check: no backlogged paused modules, these weren't waiting on anything
2076		// except the parallelism limit so they should have run.
2077		if len(unpauseBacklog) > 0 {
2078			panic(fmt.Errorf("parallelVisit finished with %d backlogged unpaused visitors", len(unpauseBacklog)))
2079		}
2080
2081		if len(pauseMap) > 0 {
2082			// Probably a deadlock due to a newly added dependency cycle. Start from each module in
2083			// the order of the input modules list and perform a depth-first search for the module
2084			// it is paused on, ignoring modules that are marked as done.  Note this traverses from
2085			// modules to the modules that would have been unblocked when that module finished, i.e
2086			// the reverse of the visitOrderer.
2087
2088			// In order to reduce duplicated work, once a module has been checked and determined
2089			// not to be part of a cycle add it and everything that depends on it to the checked
2090			// map.
2091			checked := make(map[*moduleInfo]struct{})
2092
2093			var check func(module, end *moduleInfo) []*moduleInfo
2094			check = func(module, end *moduleInfo) []*moduleInfo {
2095				if module.waitingCount == -1 {
2096					// This module was finished, it can't be part of a loop.
2097					return nil
2098				}
2099				if module == end {
2100					// This module is the end of the loop, start rolling up the cycle.
2101					return []*moduleInfo{module}
2102				}
2103
2104				if _, alreadyChecked := checked[module]; alreadyChecked {
2105					return nil
2106				}
2107
2108				for _, dep := range order.propagate(module) {
2109					cycle := check(dep, end)
2110					if cycle != nil {
2111						return append([]*moduleInfo{module}, cycle...)
2112					}
2113				}
2114				for _, depPauseSpec := range pauseMap[module] {
2115					cycle := check(depPauseSpec.paused, end)
2116					if cycle != nil {
2117						return append([]*moduleInfo{module}, cycle...)
2118					}
2119				}
2120
2121				checked[module] = struct{}{}
2122				return nil
2123			}
2124
2125			// Iterate over the modules list instead of pauseMap to provide deterministic ordering.
2126			for _, module := range modules {
2127				for _, pauseSpec := range pauseMap[module] {
2128					cycle := check(pauseSpec.paused, pauseSpec.until)
2129					if len(cycle) > 0 {
2130						return cycleError(cycle)
2131					}
2132				}
2133			}
2134		}
2135
2136		// Invariant check: if there was no deadlock and no cancellation every module
2137		// should have been visited.
2138		if visited != toVisit {
2139			panic(fmt.Errorf("parallelVisit ran %d visitors, expected %d", visited, toVisit))
2140		}
2141
2142		// Invariant check: if there was no deadlock and no cancellation  every module
2143		// should have been visited, so there is nothing left to be paused on.
2144		if len(pauseMap) > 0 {
2145			panic(fmt.Errorf("parallelVisit finished with %d paused visitors", len(pauseMap)))
2146		}
2147	}
2148
2149	return nil
2150}
2151
2152func cycleError(cycle []*moduleInfo) (errs []error) {
2153	// The cycle list is in reverse order because all the 'check' calls append
2154	// their own module to the list.
2155	errs = append(errs, &BlueprintError{
2156		Err: fmt.Errorf("encountered dependency cycle:"),
2157		Pos: cycle[len(cycle)-1].pos,
2158	})
2159
2160	// Iterate backwards through the cycle list.
2161	curModule := cycle[0]
2162	for i := len(cycle) - 1; i >= 0; i-- {
2163		nextModule := cycle[i]
2164		errs = append(errs, &BlueprintError{
2165			Err: fmt.Errorf("    %s depends on %s",
2166				curModule, nextModule),
2167			Pos: curModule.pos,
2168		})
2169		curModule = nextModule
2170	}
2171
2172	return errs
2173}
2174
2175// updateDependencies recursively walks the module dependency graph and updates
2176// additional fields based on the dependencies.  It builds a sorted list of modules
2177// such that dependencies of a module always appear first, and populates reverse
2178// dependency links and counts of total dependencies.  It also reports errors when
2179// it encounters dependency cycles.  This should called after resolveDependencies,
2180// as well as after any mutator pass has called addDependency
2181func (c *Context) updateDependencies() (errs []error) {
2182	c.cachedDepsModified = true
2183	visited := make(map[*moduleInfo]bool)  // modules that were already checked
2184	checking := make(map[*moduleInfo]bool) // modules actively being checked
2185
2186	sorted := make([]*moduleInfo, 0, len(c.moduleInfo))
2187
2188	var check func(group *moduleInfo) []*moduleInfo
2189
2190	check = func(module *moduleInfo) []*moduleInfo {
2191		visited[module] = true
2192		checking[module] = true
2193		defer delete(checking, module)
2194
2195		// Reset the forward and reverse deps without reducing their capacity to avoid reallocation.
2196		module.reverseDeps = module.reverseDeps[:0]
2197		module.forwardDeps = module.forwardDeps[:0]
2198
2199		// Add an implicit dependency ordering on all earlier modules in the same module group
2200		for _, dep := range module.group.modules {
2201			if dep == module {
2202				break
2203			}
2204			if depModule := dep.module(); depModule != nil {
2205				module.forwardDeps = append(module.forwardDeps, depModule)
2206			}
2207		}
2208
2209	outer:
2210		for _, dep := range module.directDeps {
2211			// use a loop to check for duplicates, average number of directDeps measured to be 9.5.
2212			for _, exists := range module.forwardDeps {
2213				if dep.module == exists {
2214					continue outer
2215				}
2216			}
2217			module.forwardDeps = append(module.forwardDeps, dep.module)
2218		}
2219
2220		for _, dep := range module.forwardDeps {
2221			if checking[dep] {
2222				// This is a cycle.
2223				return []*moduleInfo{dep, module}
2224			}
2225
2226			if !visited[dep] {
2227				cycle := check(dep)
2228				if cycle != nil {
2229					if cycle[0] == module {
2230						// We are the "start" of the cycle, so we're responsible
2231						// for generating the errors.
2232						errs = append(errs, cycleError(cycle)...)
2233
2234						// We can continue processing this module's children to
2235						// find more cycles.  Since all the modules that were
2236						// part of the found cycle were marked as visited we
2237						// won't run into that cycle again.
2238					} else {
2239						// We're not the "start" of the cycle, so we just append
2240						// our module to the list and return it.
2241						return append(cycle, module)
2242					}
2243				}
2244			}
2245
2246			dep.reverseDeps = append(dep.reverseDeps, module)
2247		}
2248
2249		sorted = append(sorted, module)
2250
2251		return nil
2252	}
2253
2254	for _, module := range c.moduleInfo {
2255		if !visited[module] {
2256			cycle := check(module)
2257			if cycle != nil {
2258				if cycle[len(cycle)-1] != module {
2259					panic("inconceivable!")
2260				}
2261				errs = append(errs, cycleError(cycle)...)
2262			}
2263		}
2264	}
2265
2266	c.modulesSorted = sorted
2267
2268	return
2269}
2270
2271type jsonVariationMap map[string]string
2272
2273type jsonModuleName struct {
2274	Name                 string
2275	Variations           jsonVariationMap
2276	DependencyVariations jsonVariationMap
2277}
2278
2279type jsonDep struct {
2280	jsonModuleName
2281	Tag string
2282}
2283
2284type jsonModule struct {
2285	jsonModuleName
2286	Deps      []jsonDep
2287	Type      string
2288	Blueprint string
2289}
2290
2291func toJsonVariationMap(vm variationMap) jsonVariationMap {
2292	return jsonVariationMap(vm)
2293}
2294
2295func jsonModuleNameFromModuleInfo(m *moduleInfo) *jsonModuleName {
2296	return &jsonModuleName{
2297		Name:                 m.Name(),
2298		Variations:           toJsonVariationMap(m.variant.variations),
2299		DependencyVariations: toJsonVariationMap(m.variant.dependencyVariations),
2300	}
2301}
2302
2303func jsonModuleFromModuleInfo(m *moduleInfo) *jsonModule {
2304	return &jsonModule{
2305		jsonModuleName: *jsonModuleNameFromModuleInfo(m),
2306		Deps:           make([]jsonDep, 0),
2307		Type:           m.typeName,
2308		Blueprint:      m.relBlueprintsFile,
2309	}
2310}
2311
2312func (c *Context) PrintJSONGraph(w io.Writer) {
2313	modules := make([]*jsonModule, 0)
2314	for _, m := range c.modulesSorted {
2315		jm := jsonModuleFromModuleInfo(m)
2316		for _, d := range m.directDeps {
2317			jm.Deps = append(jm.Deps, jsonDep{
2318				jsonModuleName: *jsonModuleNameFromModuleInfo(d.module),
2319				Tag:            fmt.Sprintf("%T %+v", d.tag, d.tag),
2320			})
2321		}
2322
2323		modules = append(modules, jm)
2324	}
2325
2326	json.NewEncoder(w).Encode(modules)
2327}
2328
2329// PrepareBuildActions generates an internal representation of all the build
2330// actions that need to be performed.  This process involves invoking the
2331// GenerateBuildActions method on each of the Module objects created during the
2332// parse phase and then on each of the registered Singleton objects.
2333//
2334// If the ResolveDependencies method has not already been called it is called
2335// automatically by this method.
2336//
2337// The config argument is made available to all of the Module and Singleton
2338// objects via the Config method on the ModuleContext and SingletonContext
2339// objects passed to GenerateBuildActions.  It is also passed to the functions
2340// specified via PoolFunc, RuleFunc, and VariableFunc so that they can compute
2341// config-specific values.
2342//
2343// The returned deps is a list of the ninja files dependencies that were added
2344// by the modules and singletons via the ModuleContext.AddNinjaFileDeps(),
2345// SingletonContext.AddNinjaFileDeps(), and PackageContext.AddNinjaFileDeps()
2346// methods.
2347
2348func (c *Context) PrepareBuildActions(config interface{}) (deps []string, errs []error) {
2349	pprof.Do(c.Context, pprof.Labels("blueprint", "PrepareBuildActions"), func(ctx context.Context) {
2350		c.buildActionsReady = false
2351
2352		if !c.dependenciesReady {
2353			var extraDeps []string
2354			extraDeps, errs = c.resolveDependencies(ctx, config)
2355			if len(errs) > 0 {
2356				return
2357			}
2358			deps = append(deps, extraDeps...)
2359		}
2360
2361		var depsModules []string
2362		depsModules, errs = c.generateModuleBuildActions(config, c.liveGlobals)
2363		if len(errs) > 0 {
2364			return
2365		}
2366
2367		var depsSingletons []string
2368		depsSingletons, errs = c.generateSingletonBuildActions(config, c.singletonInfo, c.liveGlobals)
2369		if len(errs) > 0 {
2370			return
2371		}
2372
2373		deps = append(deps, depsModules...)
2374		deps = append(deps, depsSingletons...)
2375
2376		if c.ninjaBuildDir != nil {
2377			err := c.liveGlobals.addNinjaStringDeps(c.ninjaBuildDir)
2378			if err != nil {
2379				errs = []error{err}
2380				return
2381			}
2382		}
2383
2384		pkgNames, depsPackages := c.makeUniquePackageNames(c.liveGlobals)
2385
2386		deps = append(deps, depsPackages...)
2387
2388		c.memoizeFullNames(c.liveGlobals, pkgNames)
2389
2390		// This will panic if it finds a problem since it's a programming error.
2391		c.checkForVariableReferenceCycles(c.liveGlobals.variables, pkgNames)
2392
2393		c.pkgNames = pkgNames
2394		c.globalVariables = c.liveGlobals.variables
2395		c.globalPools = c.liveGlobals.pools
2396		c.globalRules = c.liveGlobals.rules
2397
2398		c.buildActionsReady = true
2399	})
2400
2401	if len(errs) > 0 {
2402		return nil, errs
2403	}
2404
2405	return deps, nil
2406}
2407
2408func (c *Context) runMutators(ctx context.Context, config interface{}) (deps []string, errs []error) {
2409	var mutators []*mutatorInfo
2410
2411	pprof.Do(ctx, pprof.Labels("blueprint", "runMutators"), func(ctx context.Context) {
2412		mutators = append(mutators, c.earlyMutatorInfo...)
2413		mutators = append(mutators, c.mutatorInfo...)
2414
2415		for _, mutator := range mutators {
2416			pprof.Do(ctx, pprof.Labels("mutator", mutator.name), func(context.Context) {
2417				var newDeps []string
2418				if mutator.topDownMutator != nil {
2419					newDeps, errs = c.runMutator(config, mutator, topDownMutator)
2420				} else if mutator.bottomUpMutator != nil {
2421					newDeps, errs = c.runMutator(config, mutator, bottomUpMutator)
2422				} else {
2423					panic("no mutator set on " + mutator.name)
2424				}
2425				if len(errs) > 0 {
2426					return
2427				}
2428				deps = append(deps, newDeps...)
2429			})
2430			if len(errs) > 0 {
2431				return
2432			}
2433		}
2434	})
2435
2436	if len(errs) > 0 {
2437		return nil, errs
2438	}
2439
2440	return deps, nil
2441}
2442
2443type mutatorDirection interface {
2444	run(mutator *mutatorInfo, ctx *mutatorContext)
2445	orderer() visitOrderer
2446	fmt.Stringer
2447}
2448
2449type bottomUpMutatorImpl struct{}
2450
2451func (bottomUpMutatorImpl) run(mutator *mutatorInfo, ctx *mutatorContext) {
2452	mutator.bottomUpMutator(ctx)
2453}
2454
2455func (bottomUpMutatorImpl) orderer() visitOrderer {
2456	return bottomUpVisitor
2457}
2458
2459func (bottomUpMutatorImpl) String() string {
2460	return "bottom up mutator"
2461}
2462
2463type topDownMutatorImpl struct{}
2464
2465func (topDownMutatorImpl) run(mutator *mutatorInfo, ctx *mutatorContext) {
2466	mutator.topDownMutator(ctx)
2467}
2468
2469func (topDownMutatorImpl) orderer() visitOrderer {
2470	return topDownVisitor
2471}
2472
2473func (topDownMutatorImpl) String() string {
2474	return "top down mutator"
2475}
2476
2477var (
2478	topDownMutator  topDownMutatorImpl
2479	bottomUpMutator bottomUpMutatorImpl
2480)
2481
2482type reverseDep struct {
2483	module *moduleInfo
2484	dep    depInfo
2485}
2486
2487func (c *Context) runMutator(config interface{}, mutator *mutatorInfo,
2488	direction mutatorDirection) (deps []string, errs []error) {
2489
2490	newModuleInfo := make(map[Module]*moduleInfo)
2491	for k, v := range c.moduleInfo {
2492		newModuleInfo[k] = v
2493	}
2494
2495	type globalStateChange struct {
2496		reverse    []reverseDep
2497		rename     []rename
2498		replace    []replace
2499		newModules []*moduleInfo
2500		deps       []string
2501	}
2502
2503	reverseDeps := make(map[*moduleInfo][]depInfo)
2504	var rename []rename
2505	var replace []replace
2506	var newModules []*moduleInfo
2507
2508	errsCh := make(chan []error)
2509	globalStateCh := make(chan globalStateChange)
2510	newVariationsCh := make(chan modulesOrAliases)
2511	done := make(chan bool)
2512
2513	c.depsModified = 0
2514
2515	visit := func(module *moduleInfo, pause chan<- pauseSpec) bool {
2516		if module.splitModules != nil {
2517			panic("split module found in sorted module list")
2518		}
2519
2520		mctx := &mutatorContext{
2521			baseModuleContext: baseModuleContext{
2522				context: c,
2523				config:  config,
2524				module:  module,
2525			},
2526			name:    mutator.name,
2527			pauseCh: pause,
2528		}
2529
2530		module.startedMutator = mutator
2531
2532		func() {
2533			defer func() {
2534				if r := recover(); r != nil {
2535					in := fmt.Sprintf("%s %q for %s", direction, mutator.name, module)
2536					if err, ok := r.(panicError); ok {
2537						err.addIn(in)
2538						mctx.error(err)
2539					} else {
2540						mctx.error(newPanicErrorf(r, in))
2541					}
2542				}
2543			}()
2544			direction.run(mutator, mctx)
2545		}()
2546
2547		module.finishedMutator = mutator
2548
2549		if len(mctx.errs) > 0 {
2550			errsCh <- mctx.errs
2551			return true
2552		}
2553
2554		if len(mctx.newVariations) > 0 {
2555			newVariationsCh <- mctx.newVariations
2556		}
2557
2558		if len(mctx.reverseDeps) > 0 || len(mctx.replace) > 0 || len(mctx.rename) > 0 || len(mctx.newModules) > 0 || len(mctx.ninjaFileDeps) > 0 {
2559			globalStateCh <- globalStateChange{
2560				reverse:    mctx.reverseDeps,
2561				replace:    mctx.replace,
2562				rename:     mctx.rename,
2563				newModules: mctx.newModules,
2564				deps:       mctx.ninjaFileDeps,
2565			}
2566		}
2567
2568		return false
2569	}
2570
2571	// Process errs and reverseDeps in a single goroutine
2572	go func() {
2573		for {
2574			select {
2575			case newErrs := <-errsCh:
2576				errs = append(errs, newErrs...)
2577			case globalStateChange := <-globalStateCh:
2578				for _, r := range globalStateChange.reverse {
2579					reverseDeps[r.module] = append(reverseDeps[r.module], r.dep)
2580				}
2581				replace = append(replace, globalStateChange.replace...)
2582				rename = append(rename, globalStateChange.rename...)
2583				newModules = append(newModules, globalStateChange.newModules...)
2584				deps = append(deps, globalStateChange.deps...)
2585			case newVariations := <-newVariationsCh:
2586				for _, moduleOrAlias := range newVariations {
2587					if m := moduleOrAlias.module(); m != nil {
2588						newModuleInfo[m.logicModule] = m
2589					}
2590				}
2591			case <-done:
2592				return
2593			}
2594		}
2595	}()
2596
2597	c.startedMutator = mutator
2598
2599	var visitErrs []error
2600	if mutator.parallel {
2601		visitErrs = parallelVisit(c.modulesSorted, direction.orderer(), parallelVisitLimit, visit)
2602	} else {
2603		direction.orderer().visit(c.modulesSorted, visit)
2604	}
2605
2606	if len(visitErrs) > 0 {
2607		return nil, visitErrs
2608	}
2609
2610	c.finishedMutators[mutator] = true
2611
2612	done <- true
2613
2614	if len(errs) > 0 {
2615		return nil, errs
2616	}
2617
2618	c.moduleInfo = newModuleInfo
2619
2620	for _, group := range c.moduleGroups {
2621		for i := 0; i < len(group.modules); i++ {
2622			module := group.modules[i].module()
2623			if module == nil {
2624				// Existing alias, skip it
2625				continue
2626			}
2627
2628			// Update module group to contain newly split variants
2629			if module.splitModules != nil {
2630				group.modules, i = spliceModules(group.modules, i, module.splitModules)
2631			}
2632
2633			// Fix up any remaining dependencies on modules that were split into variants
2634			// by replacing them with the first variant
2635			for j, dep := range module.directDeps {
2636				if dep.module.logicModule == nil {
2637					module.directDeps[j].module = dep.module.splitModules.firstModule()
2638				}
2639			}
2640
2641			if module.createdBy != nil && module.createdBy.logicModule == nil {
2642				module.createdBy = module.createdBy.splitModules.firstModule()
2643			}
2644
2645			// Add in any new direct dependencies that were added by the mutator
2646			module.directDeps = append(module.directDeps, module.newDirectDeps...)
2647			module.newDirectDeps = nil
2648		}
2649
2650		findAliasTarget := func(variant variant) *moduleInfo {
2651			for _, moduleOrAlias := range group.modules {
2652				if alias := moduleOrAlias.alias(); alias != nil {
2653					if alias.variant.variations.equal(variant.variations) {
2654						return alias.target
2655					}
2656				}
2657			}
2658			return nil
2659		}
2660
2661		// Forward or delete any dangling aliases.
2662		// Use a manual loop instead of range because len(group.modules) can
2663		// change inside the loop
2664		for i := 0; i < len(group.modules); i++ {
2665			if alias := group.modules[i].alias(); alias != nil {
2666				if alias.target.logicModule == nil {
2667					newTarget := findAliasTarget(alias.target.variant)
2668					if newTarget != nil {
2669						alias.target = newTarget
2670					} else {
2671						// The alias was left dangling, remove it.
2672						group.modules = append(group.modules[:i], group.modules[i+1:]...)
2673						i--
2674					}
2675				}
2676			}
2677		}
2678	}
2679
2680	// Add in any new reverse dependencies that were added by the mutator
2681	for module, deps := range reverseDeps {
2682		sort.Sort(depSorter(deps))
2683		module.directDeps = append(module.directDeps, deps...)
2684		c.depsModified++
2685	}
2686
2687	for _, module := range newModules {
2688		errs = c.addModule(module)
2689		if len(errs) > 0 {
2690			return nil, errs
2691		}
2692		atomic.AddUint32(&c.depsModified, 1)
2693	}
2694
2695	errs = c.handleRenames(rename)
2696	if len(errs) > 0 {
2697		return nil, errs
2698	}
2699
2700	errs = c.handleReplacements(replace)
2701	if len(errs) > 0 {
2702		return nil, errs
2703	}
2704
2705	if c.depsModified > 0 {
2706		errs = c.updateDependencies()
2707		if len(errs) > 0 {
2708			return nil, errs
2709		}
2710	}
2711
2712	return deps, errs
2713}
2714
2715// Replaces every build logic module with a clone of itself.  Prevents introducing problems where
2716// a mutator sets a non-property member variable on a module, which works until a later mutator
2717// creates variants of that module.
2718func (c *Context) cloneModules() {
2719	type update struct {
2720		orig  Module
2721		clone *moduleInfo
2722	}
2723	ch := make(chan update)
2724	doneCh := make(chan bool)
2725	go func() {
2726		errs := parallelVisit(c.modulesSorted, unorderedVisitorImpl{}, parallelVisitLimit,
2727			func(m *moduleInfo, pause chan<- pauseSpec) bool {
2728				origLogicModule := m.logicModule
2729				m.logicModule, m.properties = c.cloneLogicModule(m)
2730				ch <- update{origLogicModule, m}
2731				return false
2732			})
2733		if len(errs) > 0 {
2734			panic(errs)
2735		}
2736		doneCh <- true
2737	}()
2738
2739	done := false
2740	for !done {
2741		select {
2742		case <-doneCh:
2743			done = true
2744		case update := <-ch:
2745			delete(c.moduleInfo, update.orig)
2746			c.moduleInfo[update.clone.logicModule] = update.clone
2747		}
2748	}
2749}
2750
2751// Removes modules[i] from the list and inserts newModules... where it was located, returning
2752// the new slice and the index of the last inserted element
2753func spliceModules(modules modulesOrAliases, i int, newModules modulesOrAliases) (modulesOrAliases, int) {
2754	spliceSize := len(newModules)
2755	newLen := len(modules) + spliceSize - 1
2756	var dest modulesOrAliases
2757	if cap(modules) >= len(modules)-1+len(newModules) {
2758		// We can fit the splice in the existing capacity, do everything in place
2759		dest = modules[:newLen]
2760	} else {
2761		dest = make(modulesOrAliases, newLen)
2762		copy(dest, modules[:i])
2763	}
2764
2765	// Move the end of the slice over by spliceSize-1
2766	copy(dest[i+spliceSize:], modules[i+1:])
2767
2768	// Copy the new modules into the slice
2769	copy(dest[i:], newModules)
2770
2771	return dest, i + spliceSize - 1
2772}
2773
2774func (c *Context) generateModuleBuildActions(config interface{},
2775	liveGlobals *liveTracker) ([]string, []error) {
2776
2777	var deps []string
2778	var errs []error
2779
2780	cancelCh := make(chan struct{})
2781	errsCh := make(chan []error)
2782	depsCh := make(chan []string)
2783
2784	go func() {
2785		for {
2786			select {
2787			case <-cancelCh:
2788				close(cancelCh)
2789				return
2790			case newErrs := <-errsCh:
2791				errs = append(errs, newErrs...)
2792			case newDeps := <-depsCh:
2793				deps = append(deps, newDeps...)
2794
2795			}
2796		}
2797	}()
2798
2799	visitErrs := parallelVisit(c.modulesSorted, bottomUpVisitor, parallelVisitLimit,
2800		func(module *moduleInfo, pause chan<- pauseSpec) bool {
2801			uniqueName := c.nameInterface.UniqueName(newNamespaceContext(module), module.group.name)
2802			sanitizedName := toNinjaName(uniqueName)
2803
2804			prefix := moduleNamespacePrefix(sanitizedName + "_" + module.variant.name)
2805
2806			// The parent scope of the moduleContext's local scope gets overridden to be that of the
2807			// calling Go package on a per-call basis.  Since the initial parent scope doesn't matter we
2808			// just set it to nil.
2809			scope := newLocalScope(nil, prefix)
2810
2811			mctx := &moduleContext{
2812				baseModuleContext: baseModuleContext{
2813					context: c,
2814					config:  config,
2815					module:  module,
2816				},
2817				scope:              scope,
2818				handledMissingDeps: module.missingDeps == nil,
2819			}
2820
2821			mctx.module.startedGenerateBuildActions = true
2822
2823			func() {
2824				defer func() {
2825					if r := recover(); r != nil {
2826						in := fmt.Sprintf("GenerateBuildActions for %s", module)
2827						if err, ok := r.(panicError); ok {
2828							err.addIn(in)
2829							mctx.error(err)
2830						} else {
2831							mctx.error(newPanicErrorf(r, in))
2832						}
2833					}
2834				}()
2835				mctx.module.logicModule.GenerateBuildActions(mctx)
2836			}()
2837
2838			mctx.module.finishedGenerateBuildActions = true
2839
2840			if len(mctx.errs) > 0 {
2841				errsCh <- mctx.errs
2842				return true
2843			}
2844
2845			if module.missingDeps != nil && !mctx.handledMissingDeps {
2846				var errs []error
2847				for _, depName := range module.missingDeps {
2848					errs = append(errs, c.missingDependencyError(module, depName))
2849				}
2850				errsCh <- errs
2851				return true
2852			}
2853
2854			depsCh <- mctx.ninjaFileDeps
2855
2856			newErrs := c.processLocalBuildActions(&module.actionDefs,
2857				&mctx.actionDefs, liveGlobals)
2858			if len(newErrs) > 0 {
2859				errsCh <- newErrs
2860				return true
2861			}
2862			return false
2863		})
2864
2865	cancelCh <- struct{}{}
2866	<-cancelCh
2867
2868	errs = append(errs, visitErrs...)
2869
2870	return deps, errs
2871}
2872
2873func (c *Context) generateSingletonBuildActions(config interface{},
2874	singletons []*singletonInfo, liveGlobals *liveTracker) ([]string, []error) {
2875
2876	var deps []string
2877	var errs []error
2878
2879	for _, info := range singletons {
2880		// The parent scope of the singletonContext's local scope gets overridden to be that of the
2881		// calling Go package on a per-call basis.  Since the initial parent scope doesn't matter we
2882		// just set it to nil.
2883		scope := newLocalScope(nil, singletonNamespacePrefix(info.name))
2884
2885		sctx := &singletonContext{
2886			name:    info.name,
2887			context: c,
2888			config:  config,
2889			scope:   scope,
2890			globals: liveGlobals,
2891		}
2892
2893		func() {
2894			defer func() {
2895				if r := recover(); r != nil {
2896					in := fmt.Sprintf("GenerateBuildActions for singleton %s", info.name)
2897					if err, ok := r.(panicError); ok {
2898						err.addIn(in)
2899						sctx.error(err)
2900					} else {
2901						sctx.error(newPanicErrorf(r, in))
2902					}
2903				}
2904			}()
2905			info.singleton.GenerateBuildActions(sctx)
2906		}()
2907
2908		if len(sctx.errs) > 0 {
2909			errs = append(errs, sctx.errs...)
2910			if len(errs) > maxErrors {
2911				break
2912			}
2913			continue
2914		}
2915
2916		deps = append(deps, sctx.ninjaFileDeps...)
2917
2918		newErrs := c.processLocalBuildActions(&info.actionDefs,
2919			&sctx.actionDefs, liveGlobals)
2920		errs = append(errs, newErrs...)
2921		if len(errs) > maxErrors {
2922			break
2923		}
2924	}
2925
2926	return deps, errs
2927}
2928
2929func (c *Context) processLocalBuildActions(out, in *localBuildActions,
2930	liveGlobals *liveTracker) []error {
2931
2932	var errs []error
2933
2934	// First we go through and add everything referenced by the module's
2935	// buildDefs to the live globals set.  This will end up adding the live
2936	// locals to the set as well, but we'll take them out after.
2937	for _, def := range in.buildDefs {
2938		err := liveGlobals.AddBuildDefDeps(def)
2939		if err != nil {
2940			errs = append(errs, err)
2941		}
2942	}
2943
2944	if len(errs) > 0 {
2945		return errs
2946	}
2947
2948	out.buildDefs = append(out.buildDefs, in.buildDefs...)
2949
2950	// We use the now-incorrect set of live "globals" to determine which local
2951	// definitions are live.  As we go through copying those live locals to the
2952	// moduleGroup we remove them from the live globals set.
2953	for _, v := range in.variables {
2954		isLive := liveGlobals.RemoveVariableIfLive(v)
2955		if isLive {
2956			out.variables = append(out.variables, v)
2957		}
2958	}
2959
2960	for _, r := range in.rules {
2961		isLive := liveGlobals.RemoveRuleIfLive(r)
2962		if isLive {
2963			out.rules = append(out.rules, r)
2964		}
2965	}
2966
2967	return nil
2968}
2969
2970func (c *Context) walkDeps(topModule *moduleInfo, allowDuplicates bool,
2971	visitDown func(depInfo, *moduleInfo) bool, visitUp func(depInfo, *moduleInfo)) {
2972
2973	visited := make(map[*moduleInfo]bool)
2974	var visiting *moduleInfo
2975
2976	defer func() {
2977		if r := recover(); r != nil {
2978			panic(newPanicErrorf(r, "WalkDeps(%s, %s, %s) for dependency %s",
2979				topModule, funcName(visitDown), funcName(visitUp), visiting))
2980		}
2981	}()
2982
2983	var walk func(module *moduleInfo)
2984	walk = func(module *moduleInfo) {
2985		for _, dep := range module.directDeps {
2986			if allowDuplicates || !visited[dep.module] {
2987				visiting = dep.module
2988				recurse := true
2989				if visitDown != nil {
2990					recurse = visitDown(dep, module)
2991				}
2992				if recurse && !visited[dep.module] {
2993					walk(dep.module)
2994					visited[dep.module] = true
2995				}
2996				if visitUp != nil {
2997					visitUp(dep, module)
2998				}
2999			}
3000		}
3001	}
3002
3003	walk(topModule)
3004}
3005
3006type replace struct {
3007	from, to  *moduleInfo
3008	predicate ReplaceDependencyPredicate
3009}
3010
3011type rename struct {
3012	group *moduleGroup
3013	name  string
3014}
3015
3016func (c *Context) moduleMatchingVariant(module *moduleInfo, name string) *moduleInfo {
3017	group := c.moduleGroupFromName(name, module.namespace())
3018
3019	if group == nil {
3020		return nil
3021	}
3022
3023	for _, m := range group.modules {
3024		if module.variant.name == m.moduleOrAliasVariant().name {
3025			return m.moduleOrAliasTarget()
3026		}
3027	}
3028
3029	return nil
3030}
3031
3032func (c *Context) handleRenames(renames []rename) []error {
3033	var errs []error
3034	for _, rename := range renames {
3035		group, name := rename.group, rename.name
3036		if name == group.name || len(group.modules) < 1 {
3037			continue
3038		}
3039
3040		errs = append(errs, c.nameInterface.Rename(group.name, rename.name, group.namespace)...)
3041	}
3042
3043	return errs
3044}
3045
3046func (c *Context) handleReplacements(replacements []replace) []error {
3047	var errs []error
3048	changedDeps := false
3049	for _, replace := range replacements {
3050		for _, m := range replace.from.reverseDeps {
3051			for i, d := range m.directDeps {
3052				if d.module == replace.from {
3053					// If the replacement has a predicate then check it.
3054					if replace.predicate == nil || replace.predicate(m.logicModule, d.tag, d.module.logicModule) {
3055						m.directDeps[i].module = replace.to
3056						changedDeps = true
3057					}
3058				}
3059			}
3060		}
3061
3062	}
3063
3064	if changedDeps {
3065		atomic.AddUint32(&c.depsModified, 1)
3066	}
3067	return errs
3068}
3069
3070func (c *Context) discoveredMissingDependencies(module *moduleInfo, depName string, depVariations variationMap) (errs []error) {
3071	if depVariations != nil {
3072		depName = depName + "{" + c.prettyPrintVariant(depVariations) + "}"
3073	}
3074	if c.allowMissingDependencies {
3075		module.missingDeps = append(module.missingDeps, depName)
3076		return nil
3077	}
3078	return []error{c.missingDependencyError(module, depName)}
3079}
3080
3081func (c *Context) missingDependencyError(module *moduleInfo, depName string) (errs error) {
3082	err := c.nameInterface.MissingDependencyError(module.Name(), module.namespace(), depName)
3083
3084	return &BlueprintError{
3085		Err: err,
3086		Pos: module.pos,
3087	}
3088}
3089
3090func (c *Context) moduleGroupFromName(name string, namespace Namespace) *moduleGroup {
3091	group, exists := c.nameInterface.ModuleFromName(name, namespace)
3092	if exists {
3093		return group.moduleGroup
3094	}
3095	return nil
3096}
3097
3098func (c *Context) sortedModuleGroups() []*moduleGroup {
3099	if c.cachedSortedModuleGroups == nil || c.cachedDepsModified {
3100		unwrap := func(wrappers []ModuleGroup) []*moduleGroup {
3101			result := make([]*moduleGroup, 0, len(wrappers))
3102			for _, group := range wrappers {
3103				result = append(result, group.moduleGroup)
3104			}
3105			return result
3106		}
3107
3108		c.cachedSortedModuleGroups = unwrap(c.nameInterface.AllModules())
3109		c.cachedDepsModified = false
3110	}
3111
3112	return c.cachedSortedModuleGroups
3113}
3114
3115func (c *Context) visitAllModules(visit func(Module)) {
3116	var module *moduleInfo
3117
3118	defer func() {
3119		if r := recover(); r != nil {
3120			panic(newPanicErrorf(r, "VisitAllModules(%s) for %s",
3121				funcName(visit), module))
3122		}
3123	}()
3124
3125	for _, moduleGroup := range c.sortedModuleGroups() {
3126		for _, moduleOrAlias := range moduleGroup.modules {
3127			if module = moduleOrAlias.module(); module != nil {
3128				visit(module.logicModule)
3129			}
3130		}
3131	}
3132}
3133
3134func (c *Context) visitAllModulesIf(pred func(Module) bool,
3135	visit func(Module)) {
3136
3137	var module *moduleInfo
3138
3139	defer func() {
3140		if r := recover(); r != nil {
3141			panic(newPanicErrorf(r, "VisitAllModulesIf(%s, %s) for %s",
3142				funcName(pred), funcName(visit), module))
3143		}
3144	}()
3145
3146	for _, moduleGroup := range c.sortedModuleGroups() {
3147		for _, moduleOrAlias := range moduleGroup.modules {
3148			if module = moduleOrAlias.module(); module != nil {
3149				if pred(module.logicModule) {
3150					visit(module.logicModule)
3151				}
3152			}
3153		}
3154	}
3155}
3156
3157func (c *Context) visitAllModuleVariants(module *moduleInfo,
3158	visit func(Module)) {
3159
3160	var variant *moduleInfo
3161
3162	defer func() {
3163		if r := recover(); r != nil {
3164			panic(newPanicErrorf(r, "VisitAllModuleVariants(%s, %s) for %s",
3165				module, funcName(visit), variant))
3166		}
3167	}()
3168
3169	for _, moduleOrAlias := range module.group.modules {
3170		if variant = moduleOrAlias.module(); variant != nil {
3171			visit(variant.logicModule)
3172		}
3173	}
3174}
3175
3176func (c *Context) requireNinjaVersion(major, minor, micro int) {
3177	if major != 1 {
3178		panic("ninja version with major version != 1 not supported")
3179	}
3180	if c.requiredNinjaMinor < minor {
3181		c.requiredNinjaMinor = minor
3182		c.requiredNinjaMicro = micro
3183	}
3184	if c.requiredNinjaMinor == minor && c.requiredNinjaMicro < micro {
3185		c.requiredNinjaMicro = micro
3186	}
3187}
3188
3189func (c *Context) setNinjaBuildDir(value ninjaString) {
3190	if c.ninjaBuildDir == nil {
3191		c.ninjaBuildDir = value
3192	}
3193}
3194
3195func (c *Context) makeUniquePackageNames(
3196	liveGlobals *liveTracker) (map[*packageContext]string, []string) {
3197
3198	pkgs := make(map[string]*packageContext)
3199	pkgNames := make(map[*packageContext]string)
3200	longPkgNames := make(map[*packageContext]bool)
3201
3202	processPackage := func(pctx *packageContext) {
3203		if pctx == nil {
3204			// This is a built-in rule and has no package.
3205			return
3206		}
3207		if _, ok := pkgNames[pctx]; ok {
3208			// We've already processed this package.
3209			return
3210		}
3211
3212		otherPkg, present := pkgs[pctx.shortName]
3213		if present {
3214			// Short name collision.  Both this package and the one that's
3215			// already there need to use their full names.  We leave the short
3216			// name in pkgNames for now so future collisions still get caught.
3217			longPkgNames[pctx] = true
3218			longPkgNames[otherPkg] = true
3219		} else {
3220			// No collision so far.  Tentatively set the package's name to be
3221			// its short name.
3222			pkgNames[pctx] = pctx.shortName
3223			pkgs[pctx.shortName] = pctx
3224		}
3225	}
3226
3227	// We try to give all packages their short name, but when we get collisions
3228	// we need to use the full unique package name.
3229	for v, _ := range liveGlobals.variables {
3230		processPackage(v.packageContext())
3231	}
3232	for p, _ := range liveGlobals.pools {
3233		processPackage(p.packageContext())
3234	}
3235	for r, _ := range liveGlobals.rules {
3236		processPackage(r.packageContext())
3237	}
3238
3239	// Add the packages that had collisions using their full unique names.  This
3240	// will overwrite any short names that were added in the previous step.
3241	for pctx := range longPkgNames {
3242		pkgNames[pctx] = pctx.fullName
3243	}
3244
3245	// Create deps list from calls to PackageContext.AddNinjaFileDeps
3246	deps := []string{}
3247	for _, pkg := range pkgs {
3248		deps = append(deps, pkg.ninjaFileDeps...)
3249	}
3250
3251	return pkgNames, deps
3252}
3253
3254// memoizeFullNames stores the full name of each live global variable, rule and pool since each is
3255// guaranteed to be used at least twice, once in the definition and once for each usage, and many
3256// are used much more than once.
3257func (c *Context) memoizeFullNames(liveGlobals *liveTracker, pkgNames map[*packageContext]string) {
3258	for v := range liveGlobals.variables {
3259		v.memoizeFullName(pkgNames)
3260	}
3261	for r := range liveGlobals.rules {
3262		r.memoizeFullName(pkgNames)
3263	}
3264	for p := range liveGlobals.pools {
3265		p.memoizeFullName(pkgNames)
3266	}
3267}
3268
3269func (c *Context) checkForVariableReferenceCycles(
3270	variables map[Variable]ninjaString, pkgNames map[*packageContext]string) {
3271
3272	visited := make(map[Variable]bool)  // variables that were already checked
3273	checking := make(map[Variable]bool) // variables actively being checked
3274
3275	var check func(v Variable) []Variable
3276
3277	check = func(v Variable) []Variable {
3278		visited[v] = true
3279		checking[v] = true
3280		defer delete(checking, v)
3281
3282		value := variables[v]
3283		for _, dep := range value.Variables() {
3284			if checking[dep] {
3285				// This is a cycle.
3286				return []Variable{dep, v}
3287			}
3288
3289			if !visited[dep] {
3290				cycle := check(dep)
3291				if cycle != nil {
3292					if cycle[0] == v {
3293						// We are the "start" of the cycle, so we're responsible
3294						// for generating the errors.  The cycle list is in
3295						// reverse order because all the 'check' calls append
3296						// their own module to the list.
3297						msgs := []string{"detected variable reference cycle:"}
3298
3299						// Iterate backwards through the cycle list.
3300						curName := v.fullName(pkgNames)
3301						curValue := value.Value(pkgNames)
3302						for i := len(cycle) - 1; i >= 0; i-- {
3303							next := cycle[i]
3304							nextName := next.fullName(pkgNames)
3305							nextValue := variables[next].Value(pkgNames)
3306
3307							msgs = append(msgs, fmt.Sprintf(
3308								"    %q depends on %q", curName, nextName))
3309							msgs = append(msgs, fmt.Sprintf(
3310								"    [%s = %s]", curName, curValue))
3311
3312							curName = nextName
3313							curValue = nextValue
3314						}
3315
3316						// Variable reference cycles are a programming error,
3317						// not the fault of the Blueprint file authors.
3318						panic(strings.Join(msgs, "\n"))
3319					} else {
3320						// We're not the "start" of the cycle, so we just append
3321						// our module to the list and return it.
3322						return append(cycle, v)
3323					}
3324				}
3325			}
3326		}
3327
3328		return nil
3329	}
3330
3331	for v := range variables {
3332		if !visited[v] {
3333			cycle := check(v)
3334			if cycle != nil {
3335				panic("inconceivable!")
3336			}
3337		}
3338	}
3339}
3340
3341// AllTargets returns a map all the build target names to the rule used to build
3342// them.  This is the same information that is output by running 'ninja -t
3343// targets all'.  If this is called before PrepareBuildActions successfully
3344// completes then ErrbuildActionsNotReady is returned.
3345func (c *Context) AllTargets() (map[string]string, error) {
3346	if !c.buildActionsReady {
3347		return nil, ErrBuildActionsNotReady
3348	}
3349
3350	targets := map[string]string{}
3351
3352	// Collect all the module build targets.
3353	for _, module := range c.moduleInfo {
3354		for _, buildDef := range module.actionDefs.buildDefs {
3355			ruleName := buildDef.Rule.fullName(c.pkgNames)
3356			for _, output := range append(buildDef.Outputs, buildDef.ImplicitOutputs...) {
3357				outputValue, err := output.Eval(c.globalVariables)
3358				if err != nil {
3359					return nil, err
3360				}
3361				targets[outputValue] = ruleName
3362			}
3363		}
3364	}
3365
3366	// Collect all the singleton build targets.
3367	for _, info := range c.singletonInfo {
3368		for _, buildDef := range info.actionDefs.buildDefs {
3369			ruleName := buildDef.Rule.fullName(c.pkgNames)
3370			for _, output := range append(buildDef.Outputs, buildDef.ImplicitOutputs...) {
3371				outputValue, err := output.Eval(c.globalVariables)
3372				if err != nil {
3373					return nil, err
3374				}
3375				targets[outputValue] = ruleName
3376			}
3377		}
3378	}
3379
3380	return targets, nil
3381}
3382
3383func (c *Context) NinjaBuildDir() (string, error) {
3384	if c.ninjaBuildDir != nil {
3385		return c.ninjaBuildDir.Eval(c.globalVariables)
3386	} else {
3387		return "", nil
3388	}
3389}
3390
3391// ModuleTypePropertyStructs returns a mapping from module type name to a list of pointers to
3392// property structs returned by the factory for that module type.
3393func (c *Context) ModuleTypePropertyStructs() map[string][]interface{} {
3394	ret := make(map[string][]interface{})
3395	for moduleType, factory := range c.moduleFactories {
3396		_, ret[moduleType] = factory()
3397	}
3398
3399	return ret
3400}
3401
3402func (c *Context) ModuleTypeFactories() map[string]ModuleFactory {
3403	ret := make(map[string]ModuleFactory)
3404	for k, v := range c.moduleFactories {
3405		ret[k] = v
3406	}
3407	return ret
3408}
3409
3410func (c *Context) ModuleName(logicModule Module) string {
3411	module := c.moduleInfo[logicModule]
3412	return module.Name()
3413}
3414
3415func (c *Context) ModuleDir(logicModule Module) string {
3416	return filepath.Dir(c.BlueprintFile(logicModule))
3417}
3418
3419func (c *Context) ModuleSubDir(logicModule Module) string {
3420	module := c.moduleInfo[logicModule]
3421	return module.variant.name
3422}
3423
3424func (c *Context) ModuleType(logicModule Module) string {
3425	module := c.moduleInfo[logicModule]
3426	return module.typeName
3427}
3428
3429// ModuleProvider returns the value, if any, for the provider for a module.  If the value for the
3430// provider was not set it returns the zero value of the type of the provider, which means the
3431// return value can always be type-asserted to the type of the provider.  The return value should
3432// always be considered read-only.  It panics if called before the appropriate mutator or
3433// GenerateBuildActions pass for the provider on the module.  The value returned may be a deep
3434// copy of the value originally passed to SetProvider.
3435func (c *Context) ModuleProvider(logicModule Module, provider ProviderKey) interface{} {
3436	module := c.moduleInfo[logicModule]
3437	value, _ := c.provider(module, provider)
3438	return value
3439}
3440
3441// ModuleHasProvider returns true if the provider for the given module has been set.
3442func (c *Context) ModuleHasProvider(logicModule Module, provider ProviderKey) bool {
3443	module := c.moduleInfo[logicModule]
3444	_, ok := c.provider(module, provider)
3445	return ok
3446}
3447
3448func (c *Context) BlueprintFile(logicModule Module) string {
3449	module := c.moduleInfo[logicModule]
3450	return module.relBlueprintsFile
3451}
3452
3453func (c *Context) ModuleErrorf(logicModule Module, format string,
3454	args ...interface{}) error {
3455
3456	module := c.moduleInfo[logicModule]
3457	return &BlueprintError{
3458		Err: fmt.Errorf(format, args...),
3459		Pos: module.pos,
3460	}
3461}
3462
3463func (c *Context) VisitAllModules(visit func(Module)) {
3464	c.visitAllModules(visit)
3465}
3466
3467func (c *Context) VisitAllModulesIf(pred func(Module) bool,
3468	visit func(Module)) {
3469
3470	c.visitAllModulesIf(pred, visit)
3471}
3472
3473func (c *Context) VisitDirectDeps(module Module, visit func(Module)) {
3474	topModule := c.moduleInfo[module]
3475
3476	var visiting *moduleInfo
3477
3478	defer func() {
3479		if r := recover(); r != nil {
3480			panic(newPanicErrorf(r, "VisitDirectDeps(%s, %s) for dependency %s",
3481				topModule, funcName(visit), visiting))
3482		}
3483	}()
3484
3485	for _, dep := range topModule.directDeps {
3486		visiting = dep.module
3487		visit(dep.module.logicModule)
3488	}
3489}
3490
3491func (c *Context) VisitDirectDepsIf(module Module, pred func(Module) bool, visit func(Module)) {
3492	topModule := c.moduleInfo[module]
3493
3494	var visiting *moduleInfo
3495
3496	defer func() {
3497		if r := recover(); r != nil {
3498			panic(newPanicErrorf(r, "VisitDirectDepsIf(%s, %s, %s) for dependency %s",
3499				topModule, funcName(pred), funcName(visit), visiting))
3500		}
3501	}()
3502
3503	for _, dep := range topModule.directDeps {
3504		visiting = dep.module
3505		if pred(dep.module.logicModule) {
3506			visit(dep.module.logicModule)
3507		}
3508	}
3509}
3510
3511func (c *Context) VisitDepsDepthFirst(module Module, visit func(Module)) {
3512	topModule := c.moduleInfo[module]
3513
3514	var visiting *moduleInfo
3515
3516	defer func() {
3517		if r := recover(); r != nil {
3518			panic(newPanicErrorf(r, "VisitDepsDepthFirst(%s, %s) for dependency %s",
3519				topModule, funcName(visit), visiting))
3520		}
3521	}()
3522
3523	c.walkDeps(topModule, false, nil, func(dep depInfo, parent *moduleInfo) {
3524		visiting = dep.module
3525		visit(dep.module.logicModule)
3526	})
3527}
3528
3529func (c *Context) VisitDepsDepthFirstIf(module Module, pred func(Module) bool, visit func(Module)) {
3530	topModule := c.moduleInfo[module]
3531
3532	var visiting *moduleInfo
3533
3534	defer func() {
3535		if r := recover(); r != nil {
3536			panic(newPanicErrorf(r, "VisitDepsDepthFirstIf(%s, %s, %s) for dependency %s",
3537				topModule, funcName(pred), funcName(visit), visiting))
3538		}
3539	}()
3540
3541	c.walkDeps(topModule, false, nil, func(dep depInfo, parent *moduleInfo) {
3542		if pred(dep.module.logicModule) {
3543			visiting = dep.module
3544			visit(dep.module.logicModule)
3545		}
3546	})
3547}
3548
3549func (c *Context) PrimaryModule(module Module) Module {
3550	return c.moduleInfo[module].group.modules.firstModule().logicModule
3551}
3552
3553func (c *Context) FinalModule(module Module) Module {
3554	return c.moduleInfo[module].group.modules.lastModule().logicModule
3555}
3556
3557func (c *Context) VisitAllModuleVariants(module Module,
3558	visit func(Module)) {
3559
3560	c.visitAllModuleVariants(c.moduleInfo[module], visit)
3561}
3562
3563// Singletons returns a list of all registered Singletons.
3564func (c *Context) Singletons() []Singleton {
3565	var ret []Singleton
3566	for _, s := range c.singletonInfo {
3567		ret = append(ret, s.singleton)
3568	}
3569	return ret
3570}
3571
3572// SingletonName returns the name that the given singleton was registered with.
3573func (c *Context) SingletonName(singleton Singleton) string {
3574	for _, s := range c.singletonInfo {
3575		if s.singleton == singleton {
3576			return s.name
3577		}
3578	}
3579	return ""
3580}
3581
3582// WriteBuildFile writes the Ninja manifeset text for the generated build
3583// actions to w.  If this is called before PrepareBuildActions successfully
3584// completes then ErrBuildActionsNotReady is returned.
3585func (c *Context) WriteBuildFile(w io.StringWriter) error {
3586	var err error
3587	pprof.Do(c.Context, pprof.Labels("blueprint", "WriteBuildFile"), func(ctx context.Context) {
3588		if !c.buildActionsReady {
3589			err = ErrBuildActionsNotReady
3590			return
3591		}
3592
3593		nw := newNinjaWriter(w)
3594
3595		err = c.writeBuildFileHeader(nw)
3596		if err != nil {
3597			return
3598		}
3599
3600		err = c.writeNinjaRequiredVersion(nw)
3601		if err != nil {
3602			return
3603		}
3604
3605		err = c.writeSubninjas(nw)
3606		if err != nil {
3607			return
3608		}
3609
3610		// TODO: Group the globals by package.
3611
3612		err = c.writeGlobalVariables(nw)
3613		if err != nil {
3614			return
3615		}
3616
3617		err = c.writeGlobalPools(nw)
3618		if err != nil {
3619			return
3620		}
3621
3622		err = c.writeBuildDir(nw)
3623		if err != nil {
3624			return
3625		}
3626
3627		err = c.writeGlobalRules(nw)
3628		if err != nil {
3629			return
3630		}
3631
3632		err = c.writeAllModuleActions(nw)
3633		if err != nil {
3634			return
3635		}
3636
3637		err = c.writeAllSingletonActions(nw)
3638		if err != nil {
3639			return
3640		}
3641	})
3642
3643	if err != nil {
3644		return err
3645	}
3646
3647	return nil
3648}
3649
3650type pkgAssociation struct {
3651	PkgName string
3652	PkgPath string
3653}
3654
3655type pkgAssociationSorter struct {
3656	pkgs []pkgAssociation
3657}
3658
3659func (s *pkgAssociationSorter) Len() int {
3660	return len(s.pkgs)
3661}
3662
3663func (s *pkgAssociationSorter) Less(i, j int) bool {
3664	iName := s.pkgs[i].PkgName
3665	jName := s.pkgs[j].PkgName
3666	return iName < jName
3667}
3668
3669func (s *pkgAssociationSorter) Swap(i, j int) {
3670	s.pkgs[i], s.pkgs[j] = s.pkgs[j], s.pkgs[i]
3671}
3672
3673func (c *Context) writeBuildFileHeader(nw *ninjaWriter) error {
3674	headerTemplate := template.New("fileHeader")
3675	_, err := headerTemplate.Parse(fileHeaderTemplate)
3676	if err != nil {
3677		// This is a programming error.
3678		panic(err)
3679	}
3680
3681	var pkgs []pkgAssociation
3682	maxNameLen := 0
3683	for pkg, name := range c.pkgNames {
3684		pkgs = append(pkgs, pkgAssociation{
3685			PkgName: name,
3686			PkgPath: pkg.pkgPath,
3687		})
3688		if len(name) > maxNameLen {
3689			maxNameLen = len(name)
3690		}
3691	}
3692
3693	for i := range pkgs {
3694		pkgs[i].PkgName += strings.Repeat(" ", maxNameLen-len(pkgs[i].PkgName))
3695	}
3696
3697	sort.Sort(&pkgAssociationSorter{pkgs})
3698
3699	params := map[string]interface{}{
3700		"Pkgs": pkgs,
3701	}
3702
3703	buf := bytes.NewBuffer(nil)
3704	err = headerTemplate.Execute(buf, params)
3705	if err != nil {
3706		return err
3707	}
3708
3709	return nw.Comment(buf.String())
3710}
3711
3712func (c *Context) writeNinjaRequiredVersion(nw *ninjaWriter) error {
3713	value := fmt.Sprintf("%d.%d.%d", c.requiredNinjaMajor, c.requiredNinjaMinor,
3714		c.requiredNinjaMicro)
3715
3716	err := nw.Assign("ninja_required_version", value)
3717	if err != nil {
3718		return err
3719	}
3720
3721	return nw.BlankLine()
3722}
3723
3724func (c *Context) writeSubninjas(nw *ninjaWriter) error {
3725	for _, subninja := range c.subninjas {
3726		err := nw.Subninja(subninja)
3727		if err != nil {
3728			return err
3729		}
3730	}
3731	return nw.BlankLine()
3732}
3733
3734func (c *Context) writeBuildDir(nw *ninjaWriter) error {
3735	if c.ninjaBuildDir != nil {
3736		err := nw.Assign("builddir", c.ninjaBuildDir.Value(c.pkgNames))
3737		if err != nil {
3738			return err
3739		}
3740
3741		err = nw.BlankLine()
3742		if err != nil {
3743			return err
3744		}
3745	}
3746	return nil
3747}
3748
3749type globalEntity interface {
3750	fullName(pkgNames map[*packageContext]string) string
3751}
3752
3753type globalEntitySorter struct {
3754	pkgNames map[*packageContext]string
3755	entities []globalEntity
3756}
3757
3758func (s *globalEntitySorter) Len() int {
3759	return len(s.entities)
3760}
3761
3762func (s *globalEntitySorter) Less(i, j int) bool {
3763	iName := s.entities[i].fullName(s.pkgNames)
3764	jName := s.entities[j].fullName(s.pkgNames)
3765	return iName < jName
3766}
3767
3768func (s *globalEntitySorter) Swap(i, j int) {
3769	s.entities[i], s.entities[j] = s.entities[j], s.entities[i]
3770}
3771
3772func (c *Context) writeGlobalVariables(nw *ninjaWriter) error {
3773	visited := make(map[Variable]bool)
3774
3775	var walk func(v Variable) error
3776	walk = func(v Variable) error {
3777		visited[v] = true
3778
3779		// First visit variables on which this variable depends.
3780		value := c.globalVariables[v]
3781		for _, dep := range value.Variables() {
3782			if !visited[dep] {
3783				err := walk(dep)
3784				if err != nil {
3785					return err
3786				}
3787			}
3788		}
3789
3790		err := nw.Assign(v.fullName(c.pkgNames), value.Value(c.pkgNames))
3791		if err != nil {
3792			return err
3793		}
3794
3795		err = nw.BlankLine()
3796		if err != nil {
3797			return err
3798		}
3799
3800		return nil
3801	}
3802
3803	globalVariables := make([]globalEntity, 0, len(c.globalVariables))
3804	for variable := range c.globalVariables {
3805		globalVariables = append(globalVariables, variable)
3806	}
3807
3808	sort.Sort(&globalEntitySorter{c.pkgNames, globalVariables})
3809
3810	for _, entity := range globalVariables {
3811		v := entity.(Variable)
3812		if !visited[v] {
3813			err := walk(v)
3814			if err != nil {
3815				return nil
3816			}
3817		}
3818	}
3819
3820	return nil
3821}
3822
3823func (c *Context) writeGlobalPools(nw *ninjaWriter) error {
3824	globalPools := make([]globalEntity, 0, len(c.globalPools))
3825	for pool := range c.globalPools {
3826		globalPools = append(globalPools, pool)
3827	}
3828
3829	sort.Sort(&globalEntitySorter{c.pkgNames, globalPools})
3830
3831	for _, entity := range globalPools {
3832		pool := entity.(Pool)
3833		name := pool.fullName(c.pkgNames)
3834		def := c.globalPools[pool]
3835		err := def.WriteTo(nw, name)
3836		if err != nil {
3837			return err
3838		}
3839
3840		err = nw.BlankLine()
3841		if err != nil {
3842			return err
3843		}
3844	}
3845
3846	return nil
3847}
3848
3849func (c *Context) writeGlobalRules(nw *ninjaWriter) error {
3850	globalRules := make([]globalEntity, 0, len(c.globalRules))
3851	for rule := range c.globalRules {
3852		globalRules = append(globalRules, rule)
3853	}
3854
3855	sort.Sort(&globalEntitySorter{c.pkgNames, globalRules})
3856
3857	for _, entity := range globalRules {
3858		rule := entity.(Rule)
3859		name := rule.fullName(c.pkgNames)
3860		def := c.globalRules[rule]
3861		err := def.WriteTo(nw, name, c.pkgNames)
3862		if err != nil {
3863			return err
3864		}
3865
3866		err = nw.BlankLine()
3867		if err != nil {
3868			return err
3869		}
3870	}
3871
3872	return nil
3873}
3874
3875type depSorter []depInfo
3876
3877func (s depSorter) Len() int {
3878	return len(s)
3879}
3880
3881func (s depSorter) Less(i, j int) bool {
3882	iName := s[i].module.Name()
3883	jName := s[j].module.Name()
3884	if iName == jName {
3885		iName = s[i].module.variant.name
3886		jName = s[j].module.variant.name
3887	}
3888	return iName < jName
3889}
3890
3891func (s depSorter) Swap(i, j int) {
3892	s[i], s[j] = s[j], s[i]
3893}
3894
3895type moduleSorter struct {
3896	modules       []*moduleInfo
3897	nameInterface NameInterface
3898}
3899
3900func (s moduleSorter) Len() int {
3901	return len(s.modules)
3902}
3903
3904func (s moduleSorter) Less(i, j int) bool {
3905	iMod := s.modules[i]
3906	jMod := s.modules[j]
3907	iName := s.nameInterface.UniqueName(newNamespaceContext(iMod), iMod.group.name)
3908	jName := s.nameInterface.UniqueName(newNamespaceContext(jMod), jMod.group.name)
3909	if iName == jName {
3910		iVariantName := s.modules[i].variant.name
3911		jVariantName := s.modules[j].variant.name
3912		if iVariantName == jVariantName {
3913			panic(fmt.Sprintf("duplicate module name: %s %s: %#v and %#v\n",
3914				iName, iVariantName, iMod.variant.variations, jMod.variant.variations))
3915		} else {
3916			return iVariantName < jVariantName
3917		}
3918	} else {
3919		return iName < jName
3920	}
3921}
3922
3923func (s moduleSorter) Swap(i, j int) {
3924	s.modules[i], s.modules[j] = s.modules[j], s.modules[i]
3925}
3926
3927func (c *Context) writeAllModuleActions(nw *ninjaWriter) error {
3928	headerTemplate := template.New("moduleHeader")
3929	_, err := headerTemplate.Parse(moduleHeaderTemplate)
3930	if err != nil {
3931		// This is a programming error.
3932		panic(err)
3933	}
3934
3935	modules := make([]*moduleInfo, 0, len(c.moduleInfo))
3936	for _, module := range c.moduleInfo {
3937		modules = append(modules, module)
3938	}
3939	sort.Sort(moduleSorter{modules, c.nameInterface})
3940
3941	buf := bytes.NewBuffer(nil)
3942
3943	for _, module := range modules {
3944		if len(module.actionDefs.variables)+len(module.actionDefs.rules)+len(module.actionDefs.buildDefs) == 0 {
3945			continue
3946		}
3947
3948		buf.Reset()
3949
3950		// In order to make the bootstrap build manifest independent of the
3951		// build dir we need to output the Blueprints file locations in the
3952		// comments as paths relative to the source directory.
3953		relPos := module.pos
3954		relPos.Filename = module.relBlueprintsFile
3955
3956		// Get the name and location of the factory function for the module.
3957		factoryFunc := runtime.FuncForPC(reflect.ValueOf(module.factory).Pointer())
3958		factoryName := factoryFunc.Name()
3959
3960		infoMap := map[string]interface{}{
3961			"name":      module.Name(),
3962			"typeName":  module.typeName,
3963			"goFactory": factoryName,
3964			"pos":       relPos,
3965			"variant":   module.variant.name,
3966		}
3967		err = headerTemplate.Execute(buf, infoMap)
3968		if err != nil {
3969			return err
3970		}
3971
3972		err = nw.Comment(buf.String())
3973		if err != nil {
3974			return err
3975		}
3976
3977		err = nw.BlankLine()
3978		if err != nil {
3979			return err
3980		}
3981
3982		err = c.writeLocalBuildActions(nw, &module.actionDefs)
3983		if err != nil {
3984			return err
3985		}
3986
3987		err = nw.BlankLine()
3988		if err != nil {
3989			return err
3990		}
3991	}
3992
3993	return nil
3994}
3995
3996func (c *Context) writeAllSingletonActions(nw *ninjaWriter) error {
3997	headerTemplate := template.New("singletonHeader")
3998	_, err := headerTemplate.Parse(singletonHeaderTemplate)
3999	if err != nil {
4000		// This is a programming error.
4001		panic(err)
4002	}
4003
4004	buf := bytes.NewBuffer(nil)
4005
4006	for _, info := range c.singletonInfo {
4007		if len(info.actionDefs.variables)+len(info.actionDefs.rules)+len(info.actionDefs.buildDefs) == 0 {
4008			continue
4009		}
4010
4011		// Get the name of the factory function for the module.
4012		factory := info.factory
4013		factoryFunc := runtime.FuncForPC(reflect.ValueOf(factory).Pointer())
4014		factoryName := factoryFunc.Name()
4015
4016		buf.Reset()
4017		infoMap := map[string]interface{}{
4018			"name":      info.name,
4019			"goFactory": factoryName,
4020		}
4021		err = headerTemplate.Execute(buf, infoMap)
4022		if err != nil {
4023			return err
4024		}
4025
4026		err = nw.Comment(buf.String())
4027		if err != nil {
4028			return err
4029		}
4030
4031		err = nw.BlankLine()
4032		if err != nil {
4033			return err
4034		}
4035
4036		err = c.writeLocalBuildActions(nw, &info.actionDefs)
4037		if err != nil {
4038			return err
4039		}
4040
4041		err = nw.BlankLine()
4042		if err != nil {
4043			return err
4044		}
4045	}
4046
4047	return nil
4048}
4049
4050func (c *Context) writeLocalBuildActions(nw *ninjaWriter,
4051	defs *localBuildActions) error {
4052
4053	// Write the local variable assignments.
4054	for _, v := range defs.variables {
4055		// A localVariable doesn't need the package names or config to
4056		// determine its name or value.
4057		name := v.fullName(nil)
4058		value, err := v.value(nil)
4059		if err != nil {
4060			panic(err)
4061		}
4062		err = nw.Assign(name, value.Value(c.pkgNames))
4063		if err != nil {
4064			return err
4065		}
4066	}
4067
4068	if len(defs.variables) > 0 {
4069		err := nw.BlankLine()
4070		if err != nil {
4071			return err
4072		}
4073	}
4074
4075	// Write the local rules.
4076	for _, r := range defs.rules {
4077		// A localRule doesn't need the package names or config to determine
4078		// its name or definition.
4079		name := r.fullName(nil)
4080		def, err := r.def(nil)
4081		if err != nil {
4082			panic(err)
4083		}
4084
4085		err = def.WriteTo(nw, name, c.pkgNames)
4086		if err != nil {
4087			return err
4088		}
4089
4090		err = nw.BlankLine()
4091		if err != nil {
4092			return err
4093		}
4094	}
4095
4096	// Write the build definitions.
4097	for _, buildDef := range defs.buildDefs {
4098		err := buildDef.WriteTo(nw, c.pkgNames)
4099		if err != nil {
4100			return err
4101		}
4102
4103		if len(buildDef.Args) > 0 {
4104			err = nw.BlankLine()
4105			if err != nil {
4106				return err
4107			}
4108		}
4109	}
4110
4111	return nil
4112}
4113
4114func beforeInModuleList(a, b *moduleInfo, list modulesOrAliases) bool {
4115	found := false
4116	if a == b {
4117		return false
4118	}
4119	for _, l := range list {
4120		if l.module() == a {
4121			found = true
4122		} else if l.module() == b {
4123			return found
4124		}
4125	}
4126
4127	missing := a
4128	if found {
4129		missing = b
4130	}
4131	panic(fmt.Errorf("element %v not found in list %v", missing, list))
4132}
4133
4134type panicError struct {
4135	panic interface{}
4136	stack []byte
4137	in    string
4138}
4139
4140func newPanicErrorf(panic interface{}, in string, a ...interface{}) error {
4141	buf := make([]byte, 4096)
4142	count := runtime.Stack(buf, false)
4143	return panicError{
4144		panic: panic,
4145		in:    fmt.Sprintf(in, a...),
4146		stack: buf[:count],
4147	}
4148}
4149
4150func (p panicError) Error() string {
4151	return fmt.Sprintf("panic in %s\n%s\n%s\n", p.in, p.panic, p.stack)
4152}
4153
4154func (p *panicError) addIn(in string) {
4155	p.in += " in " + in
4156}
4157
4158func funcName(f interface{}) string {
4159	return runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name()
4160}
4161
4162var fileHeaderTemplate = `******************************************************************************
4163***            This file is generated and should not be edited             ***
4164******************************************************************************
4165{{if .Pkgs}}
4166This file contains variables, rules, and pools with name prefixes indicating
4167they were generated by the following Go packages:
4168{{range .Pkgs}}
4169    {{.PkgName}} [from Go package {{.PkgPath}}]{{end}}{{end}}
4170
4171`
4172
4173var moduleHeaderTemplate = `# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
4174Module:  {{.name}}
4175Variant: {{.variant}}
4176Type:    {{.typeName}}
4177Factory: {{.goFactory}}
4178Defined: {{.pos}}
4179`
4180
4181var singletonHeaderTemplate = `# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
4182Singleton: {{.name}}
4183Factory:   {{.goFactory}}
4184`
4185