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