| // Copyright 2014 Google Inc. All rights reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| package blueprint |
| |
| import ( |
| "fmt" |
| "path/filepath" |
| ) |
| |
| type Singleton interface { |
| GenerateBuildActions(SingletonContext) |
| } |
| |
| type SingletonContext interface { |
| Config() interface{} |
| |
| ModuleName(module Module) string |
| ModuleDir(module Module) string |
| BlueprintFile(module Module) string |
| |
| ModuleErrorf(module Module, format string, args ...interface{}) |
| Errorf(format string, args ...interface{}) |
| |
| Variable(pctx *PackageContext, name, value string) |
| Rule(pctx *PackageContext, name string, params RuleParams, argNames ...string) Rule |
| Build(pctx *PackageContext, params BuildParams) |
| RequireNinjaVersion(major, minor, micro int) |
| |
| // SetBuildDir sets the value of the top-level "builddir" Ninja variable |
| // that controls where Ninja stores its build log files. This value can be |
| // set at most one time for a single build. Setting it multiple times (even |
| // across different singletons) will result in a panic. |
| SetBuildDir(pctx *PackageContext, value string) |
| |
| VisitAllModules(visit func(Module)) |
| VisitAllModulesIf(pred func(Module) bool, visit func(Module)) |
| VisitDepsDepthFirst(module Module, visit func(Module)) |
| VisitDepsDepthFirstIf(module Module, pred func(Module) bool, |
| visit func(Module)) |
| |
| AddNinjaFileDeps(deps ...string) |
| } |
| |
| var _ SingletonContext = (*singletonContext)(nil) |
| |
| type singletonContext struct { |
| context *Context |
| config interface{} |
| scope *localScope |
| |
| ninjaFileDeps []string |
| errs []error |
| |
| actionDefs localBuildActions |
| } |
| |
| func (s *singletonContext) Config() interface{} { |
| return s.config |
| } |
| |
| func (s *singletonContext) ModuleName(logicModule Module) string { |
| module := s.context.moduleInfo[logicModule] |
| return module.group.properties.Name |
| } |
| |
| func (s *singletonContext) ModuleDir(logicModule Module) string { |
| module := s.context.moduleInfo[logicModule] |
| return filepath.Dir(module.group.relBlueprintsFile) |
| } |
| |
| func (s *singletonContext) BlueprintFile(logicModule Module) string { |
| module := s.context.moduleInfo[logicModule] |
| return module.group.relBlueprintsFile |
| } |
| |
| func (s *singletonContext) ModuleErrorf(logicModule Module, format string, |
| args ...interface{}) { |
| |
| module := s.context.moduleInfo[logicModule] |
| s.errs = append(s.errs, &Error{ |
| Err: fmt.Errorf(format, args...), |
| Pos: module.group.pos, |
| }) |
| } |
| |
| func (s *singletonContext) Errorf(format string, args ...interface{}) { |
| // TODO: Make this not result in the error being printed as "internal error" |
| s.errs = append(s.errs, fmt.Errorf(format, args...)) |
| } |
| |
| func (s *singletonContext) Variable(pctx *PackageContext, name, value string) { |
| s.scope.ReparentTo(pctx) |
| |
| v, err := s.scope.AddLocalVariable(name, value) |
| if err != nil { |
| panic(err) |
| } |
| |
| s.actionDefs.variables = append(s.actionDefs.variables, v) |
| } |
| |
| func (s *singletonContext) Rule(pctx *PackageContext, name string, |
| params RuleParams, argNames ...string) Rule { |
| |
| s.scope.ReparentTo(pctx) |
| |
| r, err := s.scope.AddLocalRule(name, ¶ms, argNames...) |
| if err != nil { |
| panic(err) |
| } |
| |
| s.actionDefs.rules = append(s.actionDefs.rules, r) |
| |
| return r |
| } |
| |
| func (s *singletonContext) Build(pctx *PackageContext, params BuildParams) { |
| s.scope.ReparentTo(pctx) |
| |
| def, err := parseBuildParams(s.scope, ¶ms) |
| if err != nil { |
| panic(err) |
| } |
| |
| s.actionDefs.buildDefs = append(s.actionDefs.buildDefs, def) |
| } |
| |
| func (s *singletonContext) RequireNinjaVersion(major, minor, micro int) { |
| s.context.requireNinjaVersion(major, minor, micro) |
| } |
| |
| func (s *singletonContext) SetBuildDir(pctx *PackageContext, value string) { |
| s.scope.ReparentTo(pctx) |
| |
| ninjaValue, err := parseNinjaString(s.scope, value) |
| if err != nil { |
| panic(err) |
| } |
| |
| s.context.setBuildDir(ninjaValue) |
| } |
| |
| func (s *singletonContext) VisitAllModules(visit func(Module)) { |
| s.context.visitAllModules(visit) |
| } |
| |
| func (s *singletonContext) VisitAllModulesIf(pred func(Module) bool, |
| visit func(Module)) { |
| |
| s.context.visitAllModulesIf(pred, visit) |
| } |
| |
| func (s *singletonContext) VisitDepsDepthFirst(module Module, |
| visit func(Module)) { |
| |
| s.context.visitDepsDepthFirst(s.context.moduleInfo[module], visit) |
| } |
| |
| func (s *singletonContext) VisitDepsDepthFirstIf(module Module, |
| pred func(Module) bool, visit func(Module)) { |
| |
| s.context.visitDepsDepthFirstIf(s.context.moduleInfo[module], pred, visit) |
| } |
| |
| func (s *singletonContext) AddNinjaFileDeps(deps ...string) { |
| s.ninjaFileDeps = append(s.ninjaFileDeps, deps...) |
| } |