1*1fa6dee9SAndroid Build Coastguard Worker// Copyright 2014 Google Inc. All rights reserved. 2*1fa6dee9SAndroid Build Coastguard Worker// 3*1fa6dee9SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License"); 4*1fa6dee9SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License. 5*1fa6dee9SAndroid Build Coastguard Worker// You may obtain a copy of the License at 6*1fa6dee9SAndroid Build Coastguard Worker// 7*1fa6dee9SAndroid Build Coastguard Worker// http://www.apache.org/licenses/LICENSE-2.0 8*1fa6dee9SAndroid Build Coastguard Worker// 9*1fa6dee9SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software 10*1fa6dee9SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS, 11*1fa6dee9SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*1fa6dee9SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and 13*1fa6dee9SAndroid Build Coastguard Worker// limitations under the License. 14*1fa6dee9SAndroid Build Coastguard Worker 15*1fa6dee9SAndroid Build Coastguard Workerpackage blueprint 16*1fa6dee9SAndroid Build Coastguard Worker 17*1fa6dee9SAndroid Build Coastguard Workerimport ( 18*1fa6dee9SAndroid Build Coastguard Worker "fmt" 19*1fa6dee9SAndroid Build Coastguard Worker 20*1fa6dee9SAndroid Build Coastguard Worker "github.com/google/blueprint/pathtools" 21*1fa6dee9SAndroid Build Coastguard Worker) 22*1fa6dee9SAndroid Build Coastguard Worker 23*1fa6dee9SAndroid Build Coastguard Workertype Singleton interface { 24*1fa6dee9SAndroid Build Coastguard Worker GenerateBuildActions(SingletonContext) 25*1fa6dee9SAndroid Build Coastguard Worker} 26*1fa6dee9SAndroid Build Coastguard Worker 27*1fa6dee9SAndroid Build Coastguard Workertype SingletonContext interface { 28*1fa6dee9SAndroid Build Coastguard Worker // Config returns the config object that was passed to Context.PrepareBuildActions. 29*1fa6dee9SAndroid Build Coastguard Worker Config() interface{} 30*1fa6dee9SAndroid Build Coastguard Worker 31*1fa6dee9SAndroid Build Coastguard Worker // Name returns the name of the current singleton passed to Context.RegisterSingletonType 32*1fa6dee9SAndroid Build Coastguard Worker Name() string 33*1fa6dee9SAndroid Build Coastguard Worker 34*1fa6dee9SAndroid Build Coastguard Worker // ModuleName returns the name of the given Module. See BaseModuleContext.ModuleName for more information. 35*1fa6dee9SAndroid Build Coastguard Worker ModuleName(module Module) string 36*1fa6dee9SAndroid Build Coastguard Worker 37*1fa6dee9SAndroid Build Coastguard Worker // ModuleDir returns the directory of the given Module. See BaseModuleContext.ModuleDir for more information. 38*1fa6dee9SAndroid Build Coastguard Worker ModuleDir(module Module) string 39*1fa6dee9SAndroid Build Coastguard Worker 40*1fa6dee9SAndroid Build Coastguard Worker // ModuleSubDir returns the unique subdirectory name of the given Module. See ModuleContext.ModuleSubDir for 41*1fa6dee9SAndroid Build Coastguard Worker // more information. 42*1fa6dee9SAndroid Build Coastguard Worker ModuleSubDir(module Module) string 43*1fa6dee9SAndroid Build Coastguard Worker 44*1fa6dee9SAndroid Build Coastguard Worker // ModuleType returns the type of the given Module. See BaseModuleContext.ModuleType for more information. 45*1fa6dee9SAndroid Build Coastguard Worker ModuleType(module Module) string 46*1fa6dee9SAndroid Build Coastguard Worker 47*1fa6dee9SAndroid Build Coastguard Worker // BlueprintFile returns the path of the Blueprint file that defined the given module. 48*1fa6dee9SAndroid Build Coastguard Worker BlueprintFile(module Module) string 49*1fa6dee9SAndroid Build Coastguard Worker 50*1fa6dee9SAndroid Build Coastguard Worker // ModuleProvider returns the value, if any, for the provider for a module. If the value for the 51*1fa6dee9SAndroid Build Coastguard Worker // provider was not set it returns the zero value of the type of the provider, which means the 52*1fa6dee9SAndroid Build Coastguard Worker // return value can always be type-asserted to the type of the provider. The return value should 53*1fa6dee9SAndroid Build Coastguard Worker // always be considered read-only. It panics if called before the appropriate mutator or 54*1fa6dee9SAndroid Build Coastguard Worker // GenerateBuildActions pass for the provider on the module. 55*1fa6dee9SAndroid Build Coastguard Worker ModuleProvider(module Module, provider AnyProviderKey) (any, bool) 56*1fa6dee9SAndroid Build Coastguard Worker 57*1fa6dee9SAndroid Build Coastguard Worker // ModuleErrorf reports an error at the line number of the module type in the module definition. 58*1fa6dee9SAndroid Build Coastguard Worker ModuleErrorf(module Module, format string, args ...interface{}) 59*1fa6dee9SAndroid Build Coastguard Worker 60*1fa6dee9SAndroid Build Coastguard Worker // Errorf reports an error at the specified position of the module definition file. 61*1fa6dee9SAndroid Build Coastguard Worker Errorf(format string, args ...interface{}) 62*1fa6dee9SAndroid Build Coastguard Worker 63*1fa6dee9SAndroid Build Coastguard Worker // OtherModulePropertyErrorf reports an error on the line number of the given property of the given module 64*1fa6dee9SAndroid Build Coastguard Worker OtherModulePropertyErrorf(module Module, property string, format string, args ...interface{}) 65*1fa6dee9SAndroid Build Coastguard Worker 66*1fa6dee9SAndroid Build Coastguard Worker // Failed returns true if any errors have been reported. In most cases the singleton can continue with generating 67*1fa6dee9SAndroid Build Coastguard Worker // build rules after an error, allowing it to report additional errors in a single run, but in cases where the error 68*1fa6dee9SAndroid Build Coastguard Worker // has prevented the singleton from creating necessary data it can return early when Failed returns true. 69*1fa6dee9SAndroid Build Coastguard Worker Failed() bool 70*1fa6dee9SAndroid Build Coastguard Worker 71*1fa6dee9SAndroid Build Coastguard Worker // Variable creates a new ninja variable scoped to the singleton. It can be referenced by calls to Rule and Build 72*1fa6dee9SAndroid Build Coastguard Worker // in the same singleton. 73*1fa6dee9SAndroid Build Coastguard Worker Variable(pctx PackageContext, name, value string) 74*1fa6dee9SAndroid Build Coastguard Worker 75*1fa6dee9SAndroid Build Coastguard Worker // Rule creates a new ninja rule scoped to the singleton. It can be referenced by calls to Build in the same 76*1fa6dee9SAndroid Build Coastguard Worker // singleton. 77*1fa6dee9SAndroid Build Coastguard Worker Rule(pctx PackageContext, name string, params RuleParams, argNames ...string) Rule 78*1fa6dee9SAndroid Build Coastguard Worker 79*1fa6dee9SAndroid Build Coastguard Worker // Build creates a new ninja build statement. 80*1fa6dee9SAndroid Build Coastguard Worker Build(pctx PackageContext, params BuildParams) 81*1fa6dee9SAndroid Build Coastguard Worker 82*1fa6dee9SAndroid Build Coastguard Worker // RequireNinjaVersion sets the generated ninja manifest to require at least the specified version of ninja. 83*1fa6dee9SAndroid Build Coastguard Worker RequireNinjaVersion(major, minor, micro int) 84*1fa6dee9SAndroid Build Coastguard Worker 85*1fa6dee9SAndroid Build Coastguard Worker // SetOutDir sets the value of the top-level "builddir" Ninja variable 86*1fa6dee9SAndroid Build Coastguard Worker // that controls where Ninja stores its build log files. This value can be 87*1fa6dee9SAndroid Build Coastguard Worker // set at most one time for a single build, later calls are ignored. 88*1fa6dee9SAndroid Build Coastguard Worker SetOutDir(pctx PackageContext, value string) 89*1fa6dee9SAndroid Build Coastguard Worker 90*1fa6dee9SAndroid Build Coastguard Worker // AddSubninja adds a ninja file to include with subninja. This should likely 91*1fa6dee9SAndroid Build Coastguard Worker // only ever be used inside bootstrap to handle glob rules. 92*1fa6dee9SAndroid Build Coastguard Worker AddSubninja(file string) 93*1fa6dee9SAndroid Build Coastguard Worker 94*1fa6dee9SAndroid Build Coastguard Worker // Eval takes a string with embedded ninja variables, and returns a string 95*1fa6dee9SAndroid Build Coastguard Worker // with all of the variables recursively expanded. Any variables references 96*1fa6dee9SAndroid Build Coastguard Worker // are expanded in the scope of the PackageContext. 97*1fa6dee9SAndroid Build Coastguard Worker Eval(pctx PackageContext, ninjaStr string) (string, error) 98*1fa6dee9SAndroid Build Coastguard Worker 99*1fa6dee9SAndroid Build Coastguard Worker // VisitAllModules calls visit for each defined variant of each module in an unspecified order. 100*1fa6dee9SAndroid Build Coastguard Worker VisitAllModules(visit func(Module)) 101*1fa6dee9SAndroid Build Coastguard Worker 102*1fa6dee9SAndroid Build Coastguard Worker // VisitAllModuleProxies calls visit for each defined variant of each module in an unspecified order. 103*1fa6dee9SAndroid Build Coastguard Worker VisitAllModuleProxies(visit func(proxy ModuleProxy)) 104*1fa6dee9SAndroid Build Coastguard Worker 105*1fa6dee9SAndroid Build Coastguard Worker // VisitAllModules calls pred for each defined variant of each module in an unspecified order, and if pred returns 106*1fa6dee9SAndroid Build Coastguard Worker // true calls visit. 107*1fa6dee9SAndroid Build Coastguard Worker VisitAllModulesIf(pred func(Module) bool, visit func(Module)) 108*1fa6dee9SAndroid Build Coastguard Worker 109*1fa6dee9SAndroid Build Coastguard Worker // VisitDirectDeps calls visit for each direct dependency of the Module. If there are 110*1fa6dee9SAndroid Build Coastguard Worker // multiple direct dependencies on the same module visit will be called multiple times on 111*1fa6dee9SAndroid Build Coastguard Worker // that module and OtherModuleDependencyTag will return a different tag for each. 112*1fa6dee9SAndroid Build Coastguard Worker // 113*1fa6dee9SAndroid Build Coastguard Worker // The Module passed to the visit function should not be retained outside of the visit 114*1fa6dee9SAndroid Build Coastguard Worker // function, it may be invalidated by future mutators. 115*1fa6dee9SAndroid Build Coastguard Worker VisitDirectDeps(module Module, visit func(Module)) 116*1fa6dee9SAndroid Build Coastguard Worker 117*1fa6dee9SAndroid Build Coastguard Worker // VisitDirectDepsIf calls pred for each direct dependency of the Module, and if pred 118*1fa6dee9SAndroid Build Coastguard Worker // returns true calls visit. If there are multiple direct dependencies on the same module 119*1fa6dee9SAndroid Build Coastguard Worker // pred and visit will be called multiple times on that module and OtherModuleDependencyTag 120*1fa6dee9SAndroid Build Coastguard Worker // will return a different tag for each. 121*1fa6dee9SAndroid Build Coastguard Worker // 122*1fa6dee9SAndroid Build Coastguard Worker // The Module passed to the visit function should not be retained outside of the visit 123*1fa6dee9SAndroid Build Coastguard Worker // function, it may be invalidated by future mutators. 124*1fa6dee9SAndroid Build Coastguard Worker VisitDirectDepsIf(module Module, pred func(Module) bool, visit func(Module)) 125*1fa6dee9SAndroid Build Coastguard Worker 126*1fa6dee9SAndroid Build Coastguard Worker // VisitDepsDepthFirst calls visit for each transitive dependency, traversing the dependency tree in depth first 127*1fa6dee9SAndroid Build Coastguard Worker // order. visit will only be called once for any given module, even if there are multiple paths through the 128*1fa6dee9SAndroid Build Coastguard Worker // dependency tree to the module or multiple direct dependencies with different tags. 129*1fa6dee9SAndroid Build Coastguard Worker VisitDepsDepthFirst(module Module, visit func(Module)) 130*1fa6dee9SAndroid Build Coastguard Worker 131*1fa6dee9SAndroid Build Coastguard Worker // VisitDepsDepthFirst calls pred for each transitive dependency, and if pred returns true calls visit, traversing 132*1fa6dee9SAndroid Build Coastguard Worker // the dependency tree in depth first order. visit will only be called once for any given module, even if there are 133*1fa6dee9SAndroid Build Coastguard Worker // multiple paths through the dependency tree to the module or multiple direct dependencies with different tags. 134*1fa6dee9SAndroid Build Coastguard Worker VisitDepsDepthFirstIf(module Module, pred func(Module) bool, 135*1fa6dee9SAndroid Build Coastguard Worker visit func(Module)) 136*1fa6dee9SAndroid Build Coastguard Worker 137*1fa6dee9SAndroid Build Coastguard Worker // VisitAllModuleVariants calls visit for each variant of the given module. 138*1fa6dee9SAndroid Build Coastguard Worker VisitAllModuleVariants(module Module, visit func(Module)) 139*1fa6dee9SAndroid Build Coastguard Worker 140*1fa6dee9SAndroid Build Coastguard Worker // VisitAllModuleVariantProxies calls visit for each variant of the given module. 141*1fa6dee9SAndroid Build Coastguard Worker VisitAllModuleVariantProxies(module Module, visit func(proxy ModuleProxy)) 142*1fa6dee9SAndroid Build Coastguard Worker 143*1fa6dee9SAndroid Build Coastguard Worker // PrimaryModule returns the first variant of the given module. This can be used to perform 144*1fa6dee9SAndroid Build Coastguard Worker // // singleton actions that are only done once for all variants of a module. 145*1fa6dee9SAndroid Build Coastguard Worker PrimaryModule(module Module) Module 146*1fa6dee9SAndroid Build Coastguard Worker 147*1fa6dee9SAndroid Build Coastguard Worker // IsFinalModule returns if the given module is the last variant. This can be used to perform 148*1fa6dee9SAndroid Build Coastguard Worker // singleton actions that are only done once for all variants of a module. 149*1fa6dee9SAndroid Build Coastguard Worker IsFinalModule(module Module) bool 150*1fa6dee9SAndroid Build Coastguard Worker 151*1fa6dee9SAndroid Build Coastguard Worker // AddNinjaFileDeps adds dependencies on the specified files to the rule that creates the ninja manifest. The 152*1fa6dee9SAndroid Build Coastguard Worker // primary builder will be rerun whenever the specified files are modified. 153*1fa6dee9SAndroid Build Coastguard Worker AddNinjaFileDeps(deps ...string) 154*1fa6dee9SAndroid Build Coastguard Worker 155*1fa6dee9SAndroid Build Coastguard Worker // GlobWithDeps returns a list of files and directories that match the 156*1fa6dee9SAndroid Build Coastguard Worker // specified pattern but do not match any of the patterns in excludes. 157*1fa6dee9SAndroid Build Coastguard Worker // Any directories will have a '/' suffix. It also adds efficient 158*1fa6dee9SAndroid Build Coastguard Worker // dependencies to rerun the primary builder whenever a file matching 159*1fa6dee9SAndroid Build Coastguard Worker // the pattern as added or removed, without rerunning if a file that 160*1fa6dee9SAndroid Build Coastguard Worker // does not match the pattern is added to a searched directory. 161*1fa6dee9SAndroid Build Coastguard Worker GlobWithDeps(pattern string, excludes []string) ([]string, error) 162*1fa6dee9SAndroid Build Coastguard Worker 163*1fa6dee9SAndroid Build Coastguard Worker // Fs returns a pathtools.Filesystem that can be used to interact with files. Using the Filesystem interface allows 164*1fa6dee9SAndroid Build Coastguard Worker // the singleton to be used in build system tests that run against a mock filesystem. 165*1fa6dee9SAndroid Build Coastguard Worker Fs() pathtools.FileSystem 166*1fa6dee9SAndroid Build Coastguard Worker 167*1fa6dee9SAndroid Build Coastguard Worker // ModuleVariantsFromName returns the list of module variants named `name` in the same namespace as `referer`. 168*1fa6dee9SAndroid Build Coastguard Worker // Allows generating build actions for `referer` based on the metadata for `name` deferred until the singleton context. 169*1fa6dee9SAndroid Build Coastguard Worker ModuleVariantsFromName(referer Module, name string) []Module 170*1fa6dee9SAndroid Build Coastguard Worker 171*1fa6dee9SAndroid Build Coastguard Worker // HasMutatorFinished returns true if the given mutator has finished running. 172*1fa6dee9SAndroid Build Coastguard Worker // It will panic if given an invalid mutator name. 173*1fa6dee9SAndroid Build Coastguard Worker HasMutatorFinished(mutatorName string) bool 174*1fa6dee9SAndroid Build Coastguard Worker} 175*1fa6dee9SAndroid Build Coastguard Worker 176*1fa6dee9SAndroid Build Coastguard Workervar _ SingletonContext = (*singletonContext)(nil) 177*1fa6dee9SAndroid Build Coastguard Worker 178*1fa6dee9SAndroid Build Coastguard Workertype singletonContext struct { 179*1fa6dee9SAndroid Build Coastguard Worker name string 180*1fa6dee9SAndroid Build Coastguard Worker context *Context 181*1fa6dee9SAndroid Build Coastguard Worker config interface{} 182*1fa6dee9SAndroid Build Coastguard Worker scope *localScope 183*1fa6dee9SAndroid Build Coastguard Worker globals *liveTracker 184*1fa6dee9SAndroid Build Coastguard Worker 185*1fa6dee9SAndroid Build Coastguard Worker ninjaFileDeps []string 186*1fa6dee9SAndroid Build Coastguard Worker errs []error 187*1fa6dee9SAndroid Build Coastguard Worker 188*1fa6dee9SAndroid Build Coastguard Worker actionDefs localBuildActions 189*1fa6dee9SAndroid Build Coastguard Worker} 190*1fa6dee9SAndroid Build Coastguard Worker 191*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) Config() interface{} { 192*1fa6dee9SAndroid Build Coastguard Worker return s.config 193*1fa6dee9SAndroid Build Coastguard Worker} 194*1fa6dee9SAndroid Build Coastguard Worker 195*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) Name() string { 196*1fa6dee9SAndroid Build Coastguard Worker return s.name 197*1fa6dee9SAndroid Build Coastguard Worker} 198*1fa6dee9SAndroid Build Coastguard Worker 199*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) ModuleName(logicModule Module) string { 200*1fa6dee9SAndroid Build Coastguard Worker return s.context.ModuleName(getWrappedModule(logicModule)) 201*1fa6dee9SAndroid Build Coastguard Worker} 202*1fa6dee9SAndroid Build Coastguard Worker 203*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) ModuleDir(logicModule Module) string { 204*1fa6dee9SAndroid Build Coastguard Worker return s.context.ModuleDir(getWrappedModule(logicModule)) 205*1fa6dee9SAndroid Build Coastguard Worker} 206*1fa6dee9SAndroid Build Coastguard Worker 207*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) ModuleSubDir(logicModule Module) string { 208*1fa6dee9SAndroid Build Coastguard Worker return s.context.ModuleSubDir(getWrappedModule(logicModule)) 209*1fa6dee9SAndroid Build Coastguard Worker} 210*1fa6dee9SAndroid Build Coastguard Worker 211*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) ModuleType(logicModule Module) string { 212*1fa6dee9SAndroid Build Coastguard Worker return s.context.ModuleType(getWrappedModule(logicModule)) 213*1fa6dee9SAndroid Build Coastguard Worker} 214*1fa6dee9SAndroid Build Coastguard Worker 215*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) ModuleProvider(logicModule Module, provider AnyProviderKey) (any, bool) { 216*1fa6dee9SAndroid Build Coastguard Worker return s.context.ModuleProvider(getWrappedModule(logicModule), provider) 217*1fa6dee9SAndroid Build Coastguard Worker} 218*1fa6dee9SAndroid Build Coastguard Worker 219*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) BlueprintFile(logicModule Module) string { 220*1fa6dee9SAndroid Build Coastguard Worker return s.context.BlueprintFile(logicModule) 221*1fa6dee9SAndroid Build Coastguard Worker} 222*1fa6dee9SAndroid Build Coastguard Worker 223*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) error(err error) { 224*1fa6dee9SAndroid Build Coastguard Worker if err != nil { 225*1fa6dee9SAndroid Build Coastguard Worker s.errs = append(s.errs, err) 226*1fa6dee9SAndroid Build Coastguard Worker } 227*1fa6dee9SAndroid Build Coastguard Worker} 228*1fa6dee9SAndroid Build Coastguard Worker 229*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) ModuleErrorf(logicModule Module, format string, 230*1fa6dee9SAndroid Build Coastguard Worker args ...interface{}) { 231*1fa6dee9SAndroid Build Coastguard Worker 232*1fa6dee9SAndroid Build Coastguard Worker s.error(s.context.ModuleErrorf(logicModule, format, args...)) 233*1fa6dee9SAndroid Build Coastguard Worker} 234*1fa6dee9SAndroid Build Coastguard Worker 235*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) Errorf(format string, args ...interface{}) { 236*1fa6dee9SAndroid Build Coastguard Worker // TODO: Make this not result in the error being printed as "internal error" 237*1fa6dee9SAndroid Build Coastguard Worker s.error(fmt.Errorf(format, args...)) 238*1fa6dee9SAndroid Build Coastguard Worker} 239*1fa6dee9SAndroid Build Coastguard Worker 240*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) OtherModulePropertyErrorf(logicModule Module, property string, format string, 241*1fa6dee9SAndroid Build Coastguard Worker args ...interface{}) { 242*1fa6dee9SAndroid Build Coastguard Worker 243*1fa6dee9SAndroid Build Coastguard Worker s.error(s.context.PropertyErrorf(logicModule, property, format, args...)) 244*1fa6dee9SAndroid Build Coastguard Worker} 245*1fa6dee9SAndroid Build Coastguard Worker 246*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) Failed() bool { 247*1fa6dee9SAndroid Build Coastguard Worker return len(s.errs) > 0 248*1fa6dee9SAndroid Build Coastguard Worker} 249*1fa6dee9SAndroid Build Coastguard Worker 250*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) Variable(pctx PackageContext, name, value string) { 251*1fa6dee9SAndroid Build Coastguard Worker s.scope.ReparentTo(pctx) 252*1fa6dee9SAndroid Build Coastguard Worker 253*1fa6dee9SAndroid Build Coastguard Worker v, err := s.scope.AddLocalVariable(name, value) 254*1fa6dee9SAndroid Build Coastguard Worker if err != nil { 255*1fa6dee9SAndroid Build Coastguard Worker panic(err) 256*1fa6dee9SAndroid Build Coastguard Worker } 257*1fa6dee9SAndroid Build Coastguard Worker 258*1fa6dee9SAndroid Build Coastguard Worker s.actionDefs.variables = append(s.actionDefs.variables, v) 259*1fa6dee9SAndroid Build Coastguard Worker} 260*1fa6dee9SAndroid Build Coastguard Worker 261*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) Rule(pctx PackageContext, name string, 262*1fa6dee9SAndroid Build Coastguard Worker params RuleParams, argNames ...string) Rule { 263*1fa6dee9SAndroid Build Coastguard Worker 264*1fa6dee9SAndroid Build Coastguard Worker s.scope.ReparentTo(pctx) 265*1fa6dee9SAndroid Build Coastguard Worker 266*1fa6dee9SAndroid Build Coastguard Worker r, err := s.scope.AddLocalRule(name, ¶ms, argNames...) 267*1fa6dee9SAndroid Build Coastguard Worker if err != nil { 268*1fa6dee9SAndroid Build Coastguard Worker panic(err) 269*1fa6dee9SAndroid Build Coastguard Worker } 270*1fa6dee9SAndroid Build Coastguard Worker 271*1fa6dee9SAndroid Build Coastguard Worker s.actionDefs.rules = append(s.actionDefs.rules, r) 272*1fa6dee9SAndroid Build Coastguard Worker 273*1fa6dee9SAndroid Build Coastguard Worker return r 274*1fa6dee9SAndroid Build Coastguard Worker} 275*1fa6dee9SAndroid Build Coastguard Worker 276*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) Build(pctx PackageContext, params BuildParams) { 277*1fa6dee9SAndroid Build Coastguard Worker s.scope.ReparentTo(pctx) 278*1fa6dee9SAndroid Build Coastguard Worker 279*1fa6dee9SAndroid Build Coastguard Worker def, err := parseBuildParams(s.scope, ¶ms, map[string]string{ 280*1fa6dee9SAndroid Build Coastguard Worker "module_name": s.name, 281*1fa6dee9SAndroid Build Coastguard Worker "module_type": "singleton", 282*1fa6dee9SAndroid Build Coastguard Worker }) 283*1fa6dee9SAndroid Build Coastguard Worker if err != nil { 284*1fa6dee9SAndroid Build Coastguard Worker panic(err) 285*1fa6dee9SAndroid Build Coastguard Worker } 286*1fa6dee9SAndroid Build Coastguard Worker 287*1fa6dee9SAndroid Build Coastguard Worker s.actionDefs.buildDefs = append(s.actionDefs.buildDefs, def) 288*1fa6dee9SAndroid Build Coastguard Worker} 289*1fa6dee9SAndroid Build Coastguard Worker 290*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) Eval(pctx PackageContext, str string) (string, error) { 291*1fa6dee9SAndroid Build Coastguard Worker s.scope.ReparentTo(pctx) 292*1fa6dee9SAndroid Build Coastguard Worker 293*1fa6dee9SAndroid Build Coastguard Worker ninjaStr, err := parseNinjaString(s.scope, str) 294*1fa6dee9SAndroid Build Coastguard Worker if err != nil { 295*1fa6dee9SAndroid Build Coastguard Worker return "", err 296*1fa6dee9SAndroid Build Coastguard Worker } 297*1fa6dee9SAndroid Build Coastguard Worker 298*1fa6dee9SAndroid Build Coastguard Worker err = s.globals.addNinjaStringDeps(ninjaStr) 299*1fa6dee9SAndroid Build Coastguard Worker if err != nil { 300*1fa6dee9SAndroid Build Coastguard Worker return "", err 301*1fa6dee9SAndroid Build Coastguard Worker } 302*1fa6dee9SAndroid Build Coastguard Worker 303*1fa6dee9SAndroid Build Coastguard Worker return s.globals.Eval(ninjaStr) 304*1fa6dee9SAndroid Build Coastguard Worker} 305*1fa6dee9SAndroid Build Coastguard Worker 306*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) RequireNinjaVersion(major, minor, micro int) { 307*1fa6dee9SAndroid Build Coastguard Worker s.context.requireNinjaVersion(major, minor, micro) 308*1fa6dee9SAndroid Build Coastguard Worker} 309*1fa6dee9SAndroid Build Coastguard Worker 310*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) SetOutDir(pctx PackageContext, value string) { 311*1fa6dee9SAndroid Build Coastguard Worker s.scope.ReparentTo(pctx) 312*1fa6dee9SAndroid Build Coastguard Worker 313*1fa6dee9SAndroid Build Coastguard Worker ninjaValue, err := parseNinjaString(s.scope, value) 314*1fa6dee9SAndroid Build Coastguard Worker if err != nil { 315*1fa6dee9SAndroid Build Coastguard Worker panic(err) 316*1fa6dee9SAndroid Build Coastguard Worker } 317*1fa6dee9SAndroid Build Coastguard Worker 318*1fa6dee9SAndroid Build Coastguard Worker s.context.setOutDir(ninjaValue) 319*1fa6dee9SAndroid Build Coastguard Worker} 320*1fa6dee9SAndroid Build Coastguard Worker 321*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) AddSubninja(file string) { 322*1fa6dee9SAndroid Build Coastguard Worker s.context.subninjas = append(s.context.subninjas, file) 323*1fa6dee9SAndroid Build Coastguard Worker} 324*1fa6dee9SAndroid Build Coastguard Worker 325*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) VisitAllModules(visit func(Module)) { 326*1fa6dee9SAndroid Build Coastguard Worker var visitingModule Module 327*1fa6dee9SAndroid Build Coastguard Worker defer func() { 328*1fa6dee9SAndroid Build Coastguard Worker if r := recover(); r != nil { 329*1fa6dee9SAndroid Build Coastguard Worker panic(newPanicErrorf(r, "VisitAllModules(%s) for module %s", 330*1fa6dee9SAndroid Build Coastguard Worker funcName(visit), s.context.moduleInfo[visitingModule])) 331*1fa6dee9SAndroid Build Coastguard Worker } 332*1fa6dee9SAndroid Build Coastguard Worker }() 333*1fa6dee9SAndroid Build Coastguard Worker 334*1fa6dee9SAndroid Build Coastguard Worker s.context.VisitAllModules(func(m Module) { 335*1fa6dee9SAndroid Build Coastguard Worker visitingModule = m 336*1fa6dee9SAndroid Build Coastguard Worker visit(m) 337*1fa6dee9SAndroid Build Coastguard Worker }) 338*1fa6dee9SAndroid Build Coastguard Worker} 339*1fa6dee9SAndroid Build Coastguard Worker 340*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) VisitAllModuleProxies(visit func(proxy ModuleProxy)) { 341*1fa6dee9SAndroid Build Coastguard Worker s.VisitAllModules(visitProxyAdaptor(visit)) 342*1fa6dee9SAndroid Build Coastguard Worker} 343*1fa6dee9SAndroid Build Coastguard Worker 344*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) VisitAllModulesIf(pred func(Module) bool, 345*1fa6dee9SAndroid Build Coastguard Worker visit func(Module)) { 346*1fa6dee9SAndroid Build Coastguard Worker 347*1fa6dee9SAndroid Build Coastguard Worker s.context.VisitAllModulesIf(pred, visit) 348*1fa6dee9SAndroid Build Coastguard Worker} 349*1fa6dee9SAndroid Build Coastguard Worker 350*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) VisitDirectDeps(module Module, visit func(Module)) { 351*1fa6dee9SAndroid Build Coastguard Worker s.context.VisitDirectDeps(module, visit) 352*1fa6dee9SAndroid Build Coastguard Worker} 353*1fa6dee9SAndroid Build Coastguard Worker 354*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) VisitDirectDepsIf(module Module, pred func(Module) bool, visit func(Module)) { 355*1fa6dee9SAndroid Build Coastguard Worker s.context.VisitDirectDepsIf(module, pred, visit) 356*1fa6dee9SAndroid Build Coastguard Worker} 357*1fa6dee9SAndroid Build Coastguard Worker 358*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) VisitDepsDepthFirst(module Module, 359*1fa6dee9SAndroid Build Coastguard Worker visit func(Module)) { 360*1fa6dee9SAndroid Build Coastguard Worker 361*1fa6dee9SAndroid Build Coastguard Worker s.context.VisitDepsDepthFirst(module, visit) 362*1fa6dee9SAndroid Build Coastguard Worker} 363*1fa6dee9SAndroid Build Coastguard Worker 364*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) VisitDepsDepthFirstIf(module Module, 365*1fa6dee9SAndroid Build Coastguard Worker pred func(Module) bool, visit func(Module)) { 366*1fa6dee9SAndroid Build Coastguard Worker 367*1fa6dee9SAndroid Build Coastguard Worker s.context.VisitDepsDepthFirstIf(module, pred, visit) 368*1fa6dee9SAndroid Build Coastguard Worker} 369*1fa6dee9SAndroid Build Coastguard Worker 370*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) PrimaryModule(module Module) Module { 371*1fa6dee9SAndroid Build Coastguard Worker return s.context.PrimaryModule(module) 372*1fa6dee9SAndroid Build Coastguard Worker} 373*1fa6dee9SAndroid Build Coastguard Worker 374*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) IsFinalModule(module Module) bool { 375*1fa6dee9SAndroid Build Coastguard Worker return s.context.IsFinalModule(module) 376*1fa6dee9SAndroid Build Coastguard Worker} 377*1fa6dee9SAndroid Build Coastguard Worker 378*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) VisitAllModuleVariants(module Module, visit func(Module)) { 379*1fa6dee9SAndroid Build Coastguard Worker s.context.VisitAllModuleVariants(module, visit) 380*1fa6dee9SAndroid Build Coastguard Worker} 381*1fa6dee9SAndroid Build Coastguard Worker 382*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) VisitAllModuleVariantProxies(module Module, visit func(proxy ModuleProxy)) { 383*1fa6dee9SAndroid Build Coastguard Worker s.context.VisitAllModuleVariants(module, visitProxyAdaptor(visit)) 384*1fa6dee9SAndroid Build Coastguard Worker} 385*1fa6dee9SAndroid Build Coastguard Worker 386*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) AddNinjaFileDeps(deps ...string) { 387*1fa6dee9SAndroid Build Coastguard Worker s.ninjaFileDeps = append(s.ninjaFileDeps, deps...) 388*1fa6dee9SAndroid Build Coastguard Worker} 389*1fa6dee9SAndroid Build Coastguard Worker 390*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) GlobWithDeps(pattern string, 391*1fa6dee9SAndroid Build Coastguard Worker excludes []string) ([]string, error) { 392*1fa6dee9SAndroid Build Coastguard Worker return s.context.glob(pattern, excludes) 393*1fa6dee9SAndroid Build Coastguard Worker} 394*1fa6dee9SAndroid Build Coastguard Worker 395*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) Fs() pathtools.FileSystem { 396*1fa6dee9SAndroid Build Coastguard Worker return s.context.fs 397*1fa6dee9SAndroid Build Coastguard Worker} 398*1fa6dee9SAndroid Build Coastguard Worker 399*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) ModuleVariantsFromName(referer Module, name string) []Module { 400*1fa6dee9SAndroid Build Coastguard Worker c := s.context 401*1fa6dee9SAndroid Build Coastguard Worker 402*1fa6dee9SAndroid Build Coastguard Worker refererInfo := c.moduleInfo[referer] 403*1fa6dee9SAndroid Build Coastguard Worker if refererInfo == nil { 404*1fa6dee9SAndroid Build Coastguard Worker s.ModuleErrorf(referer, "could not find module %q", referer.Name()) 405*1fa6dee9SAndroid Build Coastguard Worker return nil 406*1fa6dee9SAndroid Build Coastguard Worker } 407*1fa6dee9SAndroid Build Coastguard Worker 408*1fa6dee9SAndroid Build Coastguard Worker moduleGroup, exists := c.nameInterface.ModuleFromName(name, refererInfo.namespace()) 409*1fa6dee9SAndroid Build Coastguard Worker if !exists { 410*1fa6dee9SAndroid Build Coastguard Worker return nil 411*1fa6dee9SAndroid Build Coastguard Worker } 412*1fa6dee9SAndroid Build Coastguard Worker result := make([]Module, 0, len(moduleGroup.modules)) 413*1fa6dee9SAndroid Build Coastguard Worker for _, moduleInfo := range moduleGroup.modules { 414*1fa6dee9SAndroid Build Coastguard Worker result = append(result, moduleInfo.logicModule) 415*1fa6dee9SAndroid Build Coastguard Worker } 416*1fa6dee9SAndroid Build Coastguard Worker return result 417*1fa6dee9SAndroid Build Coastguard Worker} 418*1fa6dee9SAndroid Build Coastguard Worker 419*1fa6dee9SAndroid Build Coastguard Workerfunc (s *singletonContext) HasMutatorFinished(mutatorName string) bool { 420*1fa6dee9SAndroid Build Coastguard Worker return s.context.HasMutatorFinished(mutatorName) 421*1fa6dee9SAndroid Build Coastguard Worker} 422*1fa6dee9SAndroid Build Coastguard Worker 423*1fa6dee9SAndroid Build Coastguard Workerfunc visitProxyAdaptor(visit func(proxy ModuleProxy)) func(module Module) { 424*1fa6dee9SAndroid Build Coastguard Worker return func(module Module) { 425*1fa6dee9SAndroid Build Coastguard Worker visit(ModuleProxy{ 426*1fa6dee9SAndroid Build Coastguard Worker module: module, 427*1fa6dee9SAndroid Build Coastguard Worker }) 428*1fa6dee9SAndroid Build Coastguard Worker } 429*1fa6dee9SAndroid Build Coastguard Worker} 430