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 "fmt" 19) 20 21type Singleton interface { 22 GenerateBuildActions(SingletonContext) 23} 24 25type SingletonContext interface { 26 Config() interface{} 27 28 ModuleName(module Module) string 29 ModuleDir(module Module) string 30 ModuleSubDir(module Module) string 31 BlueprintFile(module Module) string 32 33 ModuleErrorf(module Module, format string, args ...interface{}) 34 Errorf(format string, args ...interface{}) 35 Failed() bool 36 37 Variable(pctx PackageContext, name, value string) 38 Rule(pctx PackageContext, name string, params RuleParams, argNames ...string) Rule 39 Build(pctx PackageContext, params BuildParams) 40 RequireNinjaVersion(major, minor, micro int) 41 42 // SetNinjaBuildDir sets the value of the top-level "builddir" Ninja variable 43 // that controls where Ninja stores its build log files. This value can be 44 // set at most one time for a single build, later calls are ignored. 45 SetNinjaBuildDir(pctx PackageContext, value string) 46 47 VisitAllModules(visit func(Module)) 48 VisitAllModulesIf(pred func(Module) bool, visit func(Module)) 49 VisitDepsDepthFirst(module Module, visit func(Module)) 50 VisitDepsDepthFirstIf(module Module, pred func(Module) bool, 51 visit func(Module)) 52 53 VisitAllModuleVariants(module Module, visit func(Module)) 54 55 PrimaryModule(module Module) Module 56 FinalModule(module Module) Module 57 58 AddNinjaFileDeps(deps ...string) 59} 60 61var _ SingletonContext = (*singletonContext)(nil) 62 63type singletonContext struct { 64 context *Context 65 config interface{} 66 scope *localScope 67 68 ninjaFileDeps []string 69 errs []error 70 71 actionDefs localBuildActions 72} 73 74func (s *singletonContext) Config() interface{} { 75 return s.config 76} 77 78func (s *singletonContext) ModuleName(logicModule Module) string { 79 return s.context.ModuleName(logicModule) 80} 81 82func (s *singletonContext) ModuleDir(logicModule Module) string { 83 return s.context.ModuleDir(logicModule) 84} 85 86func (s *singletonContext) ModuleSubDir(logicModule Module) string { 87 return s.context.ModuleSubDir(logicModule) 88} 89 90func (s *singletonContext) BlueprintFile(logicModule Module) string { 91 return s.context.BlueprintFile(logicModule) 92} 93 94func (s *singletonContext) error(err error) { 95 if err != nil { 96 s.errs = append(s.errs, err) 97 } 98} 99 100func (s *singletonContext) ModuleErrorf(logicModule Module, format string, 101 args ...interface{}) { 102 103 s.error(s.context.ModuleErrorf(logicModule, format, args...)) 104} 105 106func (s *singletonContext) Errorf(format string, args ...interface{}) { 107 // TODO: Make this not result in the error being printed as "internal error" 108 s.error(fmt.Errorf(format, args...)) 109} 110 111func (s *singletonContext) Failed() bool { 112 return len(s.errs) > 0 113} 114 115func (s *singletonContext) Variable(pctx PackageContext, name, value string) { 116 s.scope.ReparentTo(pctx) 117 118 v, err := s.scope.AddLocalVariable(name, value) 119 if err != nil { 120 panic(err) 121 } 122 123 s.actionDefs.variables = append(s.actionDefs.variables, v) 124} 125 126func (s *singletonContext) Rule(pctx PackageContext, name string, 127 params RuleParams, argNames ...string) Rule { 128 129 s.scope.ReparentTo(pctx) 130 131 r, err := s.scope.AddLocalRule(name, ¶ms, argNames...) 132 if err != nil { 133 panic(err) 134 } 135 136 s.actionDefs.rules = append(s.actionDefs.rules, r) 137 138 return r 139} 140 141func (s *singletonContext) Build(pctx PackageContext, params BuildParams) { 142 s.scope.ReparentTo(pctx) 143 144 def, err := parseBuildParams(s.scope, ¶ms) 145 if err != nil { 146 panic(err) 147 } 148 149 s.actionDefs.buildDefs = append(s.actionDefs.buildDefs, def) 150} 151 152func (s *singletonContext) RequireNinjaVersion(major, minor, micro int) { 153 s.context.requireNinjaVersion(major, minor, micro) 154} 155 156func (s *singletonContext) SetNinjaBuildDir(pctx PackageContext, value string) { 157 s.scope.ReparentTo(pctx) 158 159 ninjaValue, err := parseNinjaString(s.scope, value) 160 if err != nil { 161 panic(err) 162 } 163 164 s.context.setNinjaBuildDir(ninjaValue) 165} 166 167func (s *singletonContext) VisitAllModules(visit func(Module)) { 168 s.context.VisitAllModules(visit) 169} 170 171func (s *singletonContext) VisitAllModulesIf(pred func(Module) bool, 172 visit func(Module)) { 173 174 s.context.VisitAllModulesIf(pred, visit) 175} 176 177func (s *singletonContext) VisitDepsDepthFirst(module Module, 178 visit func(Module)) { 179 180 s.context.VisitDepsDepthFirst(module, visit) 181} 182 183func (s *singletonContext) VisitDepsDepthFirstIf(module Module, 184 pred func(Module) bool, visit func(Module)) { 185 186 s.context.VisitDepsDepthFirstIf(module, pred, visit) 187} 188 189func (s *singletonContext) PrimaryModule(module Module) Module { 190 return s.context.PrimaryModule(module) 191} 192 193func (s *singletonContext) FinalModule(module Module) Module { 194 return s.context.FinalModule(module) 195} 196 197func (s *singletonContext) VisitAllModuleVariants(module Module, visit func(Module)) { 198 s.context.VisitAllModuleVariants(module, visit) 199} 200 201func (s *singletonContext) AddNinjaFileDeps(deps ...string) { 202 s.ninjaFileDeps = append(s.ninjaFileDeps, deps...) 203} 204