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 15 package blueprint 16 17 import ( 18 "fmt" 19 ) 20 21 type Singleton interface { 22 GenerateBuildActions(SingletonContext) 23 } 24 25 type 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 61 var _ SingletonContext = (*singletonContext)(nil) 62 63 type singletonContext struct { 64 context *Context 65 config interface{} 66 scope *localScope 67 68 ninjaFileDeps []string 69 errs []error 70 71 actionDefs localBuildActions 72 } 73 74 func (s *singletonContext) Config() interface{} { 75 return s.config 76 } 77 78 func (s *singletonContext) ModuleName(logicModule Module) string { 79 return s.context.ModuleName(logicModule) 80 } 81 82 func (s *singletonContext) ModuleDir(logicModule Module) string { 83 return s.context.ModuleDir(logicModule) 84 } 85 86 func (s *singletonContext) ModuleSubDir(logicModule Module) string { 87 return s.context.ModuleSubDir(logicModule) 88 } 89 90 func (s *singletonContext) BlueprintFile(logicModule Module) string { 91 return s.context.BlueprintFile(logicModule) 92 } 93 94 func (s *singletonContext) error(err error) { 95 if err != nil { 96 s.errs = append(s.errs, err) 97 } 98 } 99 100 func (s *singletonContext) ModuleErrorf(logicModule Module, format string, 101 args ...interface{}) { 102 103 s.error(s.context.ModuleErrorf(logicModule, format, args...)) 104 } 105 106 func (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 111 func (s *singletonContext) Failed() bool { 112 return len(s.errs) > 0 113 } 114 115 func (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 126 func (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 141 func (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 152 func (s *singletonContext) RequireNinjaVersion(major, minor, micro int) { 153 s.context.requireNinjaVersion(major, minor, micro) 154 } 155 156 func (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 167 func (s *singletonContext) VisitAllModules(visit func(Module)) { 168 s.context.VisitAllModules(visit) 169 } 170 171 func (s *singletonContext) VisitAllModulesIf(pred func(Module) bool, 172 visit func(Module)) { 173 174 s.context.VisitAllModulesIf(pred, visit) 175 } 176 177 func (s *singletonContext) VisitDepsDepthFirst(module Module, 178 visit func(Module)) { 179 180 s.context.VisitDepsDepthFirst(module, visit) 181 } 182 183 func (s *singletonContext) VisitDepsDepthFirstIf(module Module, 184 pred func(Module) bool, visit func(Module)) { 185 186 s.context.VisitDepsDepthFirstIf(module, pred, visit) 187 } 188 189 func (s *singletonContext) PrimaryModule(module Module) Module { 190 return s.context.PrimaryModule(module) 191 } 192 193 func (s *singletonContext) FinalModule(module Module) Module { 194 return s.context.FinalModule(module) 195 } 196 197 func (s *singletonContext) VisitAllModuleVariants(module Module, visit func(Module)) { 198 s.context.VisitAllModuleVariants(module, visit) 199 } 200 201 func (s *singletonContext) AddNinjaFileDeps(deps ...string) { 202 s.ninjaFileDeps = append(s.ninjaFileDeps, deps...) 203 } 204