aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--context.go81
1 files changed, 53 insertions, 28 deletions
diff --git a/context.go b/context.go
index 76471a6..c7264a1 100644
--- a/context.go
+++ b/context.go
@@ -72,6 +72,7 @@ type Context struct {
moduleGroups []*moduleGroup
moduleInfo map[Module]*moduleInfo
modulesSorted []*moduleInfo
+ preSingletonInfo []*singletonInfo
singletonInfo []*singletonInfo
mutatorInfo []*mutatorInfo
earlyMutatorInfo []*mutatorInfo
@@ -91,6 +92,7 @@ type Context struct {
// set during PrepareBuildActions
pkgNames map[*packageContext]string
+ liveGlobals *liveTracker
globalVariables map[Variable]*ninjaString
globalPools map[Pool]*poolDef
globalRules map[Rule]*ruleDef
@@ -266,12 +268,16 @@ type mutatorInfo struct {
func newContext() *Context {
return &Context{
- moduleFactories: make(map[string]ModuleFactory),
- moduleNames: make(map[string]*moduleGroup),
- moduleInfo: make(map[Module]*moduleInfo),
- moduleNinjaNames: make(map[string]*moduleGroup),
- globs: make(map[string]GlobPath),
- fs: pathtools.OsFs,
+ moduleFactories: make(map[string]ModuleFactory),
+ moduleNames: make(map[string]*moduleGroup),
+ moduleInfo: make(map[Module]*moduleInfo),
+ moduleNinjaNames: make(map[string]*moduleGroup),
+ globs: make(map[string]GlobPath),
+ fs: pathtools.OsFs,
+ ninjaBuildDir: nil,
+ requiredNinjaMajor: 1,
+ requiredNinjaMinor: 7,
+ requiredNinjaMicro: 0,
}
}
@@ -387,6 +393,28 @@ func (c *Context) RegisterSingletonType(name string, factory SingletonFactory) {
})
}
+// RegisterPreSingletonType registers a presingleton type that will be invoked to
+// generate build actions before any Blueprint files have been read. Each registered
+// presingleton type is instantiated and invoked exactly once at the beginning of the
+// parse phase. Each registered presingleton is invoked in registration order.
+//
+// The presingleton type names given here must be unique for the context. The
+// factory function should be a named function so that its package and name can
+// be included in the generated Ninja file for debugging purposes.
+func (c *Context) RegisterPreSingletonType(name string, factory SingletonFactory) {
+ for _, s := range c.preSingletonInfo {
+ if s.name == name {
+ panic(errors.New("presingleton name is already registered"))
+ }
+ }
+
+ c.preSingletonInfo = append(c.preSingletonInfo, &singletonInfo{
+ factory: factory,
+ singleton: factory(),
+ name: name,
+ })
+}
+
func singletonPkgPath(singleton Singleton) string {
typ := reflect.TypeOf(singleton)
for typ.Kind() == reflect.Ptr {
@@ -1237,15 +1265,23 @@ func (c *Context) addModule(module *moduleInfo) []error {
// the modules depended upon are defined and that no circular dependencies
// exist.
func (c *Context) ResolveDependencies(config interface{}) (deps []string, errs []error) {
+ c.liveGlobals = newLiveTracker(config)
+
+ deps, errs = c.generateSingletonBuildActions(config, c.preSingletonInfo, c.liveGlobals)
+ if len(errs) > 0 {
+ return nil, errs
+ }
+
errs = c.updateDependencies()
if len(errs) > 0 {
return nil, errs
}
- deps, errs = c.runMutators(config)
+ mutatorDeps, errs := c.runMutators(config)
if len(errs) > 0 {
return nil, errs
}
+ deps = append(deps, mutatorDeps...)
c.cloneModules()
@@ -1762,16 +1798,12 @@ func (c *Context) PrepareBuildActions(config interface{}) (deps []string, errs [
deps = append(deps, extraDeps...)
}
- liveGlobals := newLiveTracker(config)
-
- c.initSpecialVariables()
-
- depsModules, errs := c.generateModuleBuildActions(config, liveGlobals)
+ depsModules, errs := c.generateModuleBuildActions(config, c.liveGlobals)
if len(errs) > 0 {
return nil, errs
}
- depsSingletons, errs := c.generateSingletonBuildActions(config, liveGlobals)
+ depsSingletons, errs := c.generateSingletonBuildActions(config, c.singletonInfo, c.liveGlobals)
if len(errs) > 0 {
return nil, errs
}
@@ -1780,20 +1812,20 @@ func (c *Context) PrepareBuildActions(config interface{}) (deps []string, errs [
deps = append(deps, depsSingletons...)
if c.ninjaBuildDir != nil {
- liveGlobals.addNinjaStringDeps(c.ninjaBuildDir)
+ c.liveGlobals.addNinjaStringDeps(c.ninjaBuildDir)
}
- pkgNames, depsPackages := c.makeUniquePackageNames(liveGlobals)
+ pkgNames, depsPackages := c.makeUniquePackageNames(c.liveGlobals)
deps = append(deps, depsPackages...)
// This will panic if it finds a problem since it's a programming error.
- c.checkForVariableReferenceCycles(liveGlobals.variables, pkgNames)
+ c.checkForVariableReferenceCycles(c.liveGlobals.variables, pkgNames)
c.pkgNames = pkgNames
- c.globalVariables = liveGlobals.variables
- c.globalPools = liveGlobals.pools
- c.globalRules = liveGlobals.rules
+ c.globalVariables = c.liveGlobals.variables
+ c.globalPools = c.liveGlobals.pools
+ c.globalRules = c.liveGlobals.rules
c.buildActionsReady = true
@@ -2086,13 +2118,6 @@ func spliceModules(modules []*moduleInfo, i int, newModules []*moduleInfo) ([]*m
return dest, i + spliceSize - 1
}
-func (c *Context) initSpecialVariables() {
- c.ninjaBuildDir = nil
- c.requiredNinjaMajor = 1
- c.requiredNinjaMinor = 7
- c.requiredNinjaMicro = 0
-}
-
func (c *Context) generateModuleBuildActions(config interface{},
liveGlobals *liveTracker) ([]string, []error) {
@@ -2186,12 +2211,12 @@ func (c *Context) generateModuleBuildActions(config interface{},
}
func (c *Context) generateSingletonBuildActions(config interface{},
- liveGlobals *liveTracker) ([]string, []error) {
+ singletons []*singletonInfo, liveGlobals *liveTracker) ([]string, []error) {
var deps []string
var errs []error
- for _, info := range c.singletonInfo {
+ for _, info := range singletons {
// The parent scope of the singletonContext's local scope gets overridden to be that of the
// calling Go package on a per-call basis. Since the initial parent scope doesn't matter we
// just set it to nil.