blob: 007e180d9ef2094b5b2621c9311a902affe2e9bd [file] [log] [blame]
Colin Cross8e0c5112015-01-23 14:15:10 -08001// 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
Jamie Gennis1bc967e2014-05-27 16:34:41 -070015package blueprint
16
17import (
18 "fmt"
Jamie Gennis1bc967e2014-05-27 16:34:41 -070019)
20
21type Singleton interface {
22 GenerateBuildActions(SingletonContext)
23}
24
25type SingletonContext interface {
Jamie Gennis6eb4d242014-06-11 18:31:16 -070026 Config() interface{}
Jamie Gennis1bc967e2014-05-27 16:34:41 -070027
28 ModuleName(module Module) string
29 ModuleDir(module Module) string
Colin Cross8c602f72015-12-17 18:02:11 -080030 ModuleSubDir(module Module) string
Dan Willemsenc98e55b2016-07-25 15:51:50 -070031 ModuleType(module Module) string
Jamie Gennis1bc967e2014-05-27 16:34:41 -070032 BlueprintFile(module Module) string
33
34 ModuleErrorf(module Module, format string, args ...interface{})
35 Errorf(format string, args ...interface{})
Dan Willemsen265d92c2015-12-09 18:06:23 -080036 Failed() bool
Jamie Gennis1bc967e2014-05-27 16:34:41 -070037
Dan Willemsenaeffbf72015-11-25 15:29:32 -080038 Variable(pctx PackageContext, name, value string)
39 Rule(pctx PackageContext, name string, params RuleParams, argNames ...string) Rule
40 Build(pctx PackageContext, params BuildParams)
Jamie Gennis1bc967e2014-05-27 16:34:41 -070041 RequireNinjaVersion(major, minor, micro int)
42
Colin Crossa2599452015-11-18 16:01:01 -080043 // SetNinjaBuildDir sets the value of the top-level "builddir" Ninja variable
Jamie Gennis1bc967e2014-05-27 16:34:41 -070044 // that controls where Ninja stores its build log files. This value can be
Colin Crossa2599452015-11-18 16:01:01 -080045 // set at most one time for a single build, later calls are ignored.
Dan Willemsenaeffbf72015-11-25 15:29:32 -080046 SetNinjaBuildDir(pctx PackageContext, value string)
Jamie Gennis1bc967e2014-05-27 16:34:41 -070047
Dan Willemsen4bb62762016-01-14 15:42:54 -080048 // Eval takes a string with embedded ninja variables, and returns a string
49 // with all of the variables recursively expanded. Any variables references
50 // are expanded in the scope of the PackageContext.
51 Eval(pctx PackageContext, ninjaStr string) (string, error)
52
Jamie Gennis1bc967e2014-05-27 16:34:41 -070053 VisitAllModules(visit func(Module))
54 VisitAllModulesIf(pred func(Module) bool, visit func(Module))
Jamie Gennise98b8a92014-06-17 10:24:24 -070055 VisitDepsDepthFirst(module Module, visit func(Module))
56 VisitDepsDepthFirstIf(module Module, pred func(Module) bool,
57 visit func(Module))
Mathias Agopian5b8477d2014-06-25 17:21:54 -070058
Colin Cross24ad5872015-11-17 16:22:29 -080059 VisitAllModuleVariants(module Module, visit func(Module))
60
61 PrimaryModule(module Module) Module
62 FinalModule(module Module) Module
63
Mathias Agopian5b8477d2014-06-25 17:21:54 -070064 AddNinjaFileDeps(deps ...string)
Jamie Gennis1bc967e2014-05-27 16:34:41 -070065}
66
67var _ SingletonContext = (*singletonContext)(nil)
68
69type singletonContext struct {
70 context *Context
Jamie Gennis6eb4d242014-06-11 18:31:16 -070071 config interface{}
Jamie Gennis1bc967e2014-05-27 16:34:41 -070072 scope *localScope
Dan Willemsen4bb62762016-01-14 15:42:54 -080073 globals *liveTracker
Jamie Gennis1bc967e2014-05-27 16:34:41 -070074
Mathias Agopian5b8477d2014-06-25 17:21:54 -070075 ninjaFileDeps []string
76 errs []error
Jamie Gennis1bc967e2014-05-27 16:34:41 -070077
78 actionDefs localBuildActions
79}
80
Jamie Gennis6eb4d242014-06-11 18:31:16 -070081func (s *singletonContext) Config() interface{} {
Jamie Gennis1bc967e2014-05-27 16:34:41 -070082 return s.config
83}
84
Colin Crossbbfa51a2014-12-17 16:12:41 -080085func (s *singletonContext) ModuleName(logicModule Module) string {
Colin Cross4572edd2015-05-13 14:36:24 -070086 return s.context.ModuleName(logicModule)
Jamie Gennis1bc967e2014-05-27 16:34:41 -070087}
88
Colin Crossbbfa51a2014-12-17 16:12:41 -080089func (s *singletonContext) ModuleDir(logicModule Module) string {
Colin Cross4572edd2015-05-13 14:36:24 -070090 return s.context.ModuleDir(logicModule)
Jamie Gennis1bc967e2014-05-27 16:34:41 -070091}
92
Colin Cross8c602f72015-12-17 18:02:11 -080093func (s *singletonContext) ModuleSubDir(logicModule Module) string {
94 return s.context.ModuleSubDir(logicModule)
95}
96
Dan Willemsenc98e55b2016-07-25 15:51:50 -070097func (s *singletonContext) ModuleType(logicModule Module) string {
98 return s.context.ModuleType(logicModule)
99}
100
Colin Crossbbfa51a2014-12-17 16:12:41 -0800101func (s *singletonContext) BlueprintFile(logicModule Module) string {
Colin Cross4572edd2015-05-13 14:36:24 -0700102 return s.context.BlueprintFile(logicModule)
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700103}
104
Colin Cross0aa6a5f2016-01-07 13:43:09 -0800105func (s *singletonContext) error(err error) {
106 if err != nil {
107 s.errs = append(s.errs, err)
108 }
109}
110
Colin Crossbbfa51a2014-12-17 16:12:41 -0800111func (s *singletonContext) ModuleErrorf(logicModule Module, format string,
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700112 args ...interface{}) {
113
Colin Cross0aa6a5f2016-01-07 13:43:09 -0800114 s.error(s.context.ModuleErrorf(logicModule, format, args...))
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700115}
116
117func (s *singletonContext) Errorf(format string, args ...interface{}) {
118 // TODO: Make this not result in the error being printed as "internal error"
Colin Cross0aa6a5f2016-01-07 13:43:09 -0800119 s.error(fmt.Errorf(format, args...))
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700120}
121
Dan Willemsen265d92c2015-12-09 18:06:23 -0800122func (s *singletonContext) Failed() bool {
123 return len(s.errs) > 0
124}
125
Dan Willemsenaeffbf72015-11-25 15:29:32 -0800126func (s *singletonContext) Variable(pctx PackageContext, name, value string) {
Jamie Gennis2fb20952014-10-03 02:49:58 -0700127 s.scope.ReparentTo(pctx)
Jamie Gennis0ed63ef2014-06-30 18:07:17 -0700128
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700129 v, err := s.scope.AddLocalVariable(name, value)
130 if err != nil {
131 panic(err)
132 }
133
134 s.actionDefs.variables = append(s.actionDefs.variables, v)
135}
136
Dan Willemsenaeffbf72015-11-25 15:29:32 -0800137func (s *singletonContext) Rule(pctx PackageContext, name string,
Jamie Gennis2fb20952014-10-03 02:49:58 -0700138 params RuleParams, argNames ...string) Rule {
Jamie Genniscbc6f862014-06-05 20:00:22 -0700139
Jamie Gennis2fb20952014-10-03 02:49:58 -0700140 s.scope.ReparentTo(pctx)
Jamie Gennis0ed63ef2014-06-30 18:07:17 -0700141
Jamie Genniscbc6f862014-06-05 20:00:22 -0700142 r, err := s.scope.AddLocalRule(name, &params, argNames...)
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700143 if err != nil {
144 panic(err)
145 }
146
147 s.actionDefs.rules = append(s.actionDefs.rules, r)
148
149 return r
150}
151
Dan Willemsenaeffbf72015-11-25 15:29:32 -0800152func (s *singletonContext) Build(pctx PackageContext, params BuildParams) {
Jamie Gennis2fb20952014-10-03 02:49:58 -0700153 s.scope.ReparentTo(pctx)
Jamie Gennis0ed63ef2014-06-30 18:07:17 -0700154
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700155 def, err := parseBuildParams(s.scope, &params)
156 if err != nil {
157 panic(err)
158 }
159
160 s.actionDefs.buildDefs = append(s.actionDefs.buildDefs, def)
161}
162
Dan Willemsen4bb62762016-01-14 15:42:54 -0800163func (s *singletonContext) Eval(pctx PackageContext, str string) (string, error) {
164 s.scope.ReparentTo(pctx)
165
166 ninjaStr, err := parseNinjaString(s.scope, str)
167 if err != nil {
168 return "", err
169 }
170
171 err = s.globals.addNinjaStringDeps(ninjaStr)
172 if err != nil {
173 return "", err
174 }
175
176 return ninjaStr.Eval(s.globals.variables)
177}
178
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700179func (s *singletonContext) RequireNinjaVersion(major, minor, micro int) {
180 s.context.requireNinjaVersion(major, minor, micro)
181}
182
Dan Willemsenaeffbf72015-11-25 15:29:32 -0800183func (s *singletonContext) SetNinjaBuildDir(pctx PackageContext, value string) {
Jamie Gennis2fb20952014-10-03 02:49:58 -0700184 s.scope.ReparentTo(pctx)
Jamie Gennis7d5b2f82014-09-24 17:51:52 -0700185
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700186 ninjaValue, err := parseNinjaString(s.scope, value)
187 if err != nil {
188 panic(err)
189 }
190
Colin Crossa2599452015-11-18 16:01:01 -0800191 s.context.setNinjaBuildDir(ninjaValue)
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700192}
193
194func (s *singletonContext) VisitAllModules(visit func(Module)) {
Colin Cross4572edd2015-05-13 14:36:24 -0700195 s.context.VisitAllModules(visit)
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700196}
197
198func (s *singletonContext) VisitAllModulesIf(pred func(Module) bool,
199 visit func(Module)) {
200
Colin Cross4572edd2015-05-13 14:36:24 -0700201 s.context.VisitAllModulesIf(pred, visit)
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700202}
Jamie Gennise98b8a92014-06-17 10:24:24 -0700203
204func (s *singletonContext) VisitDepsDepthFirst(module Module,
205 visit func(Module)) {
206
Colin Cross4572edd2015-05-13 14:36:24 -0700207 s.context.VisitDepsDepthFirst(module, visit)
Jamie Gennise98b8a92014-06-17 10:24:24 -0700208}
209
210func (s *singletonContext) VisitDepsDepthFirstIf(module Module,
211 pred func(Module) bool, visit func(Module)) {
212
Colin Cross4572edd2015-05-13 14:36:24 -0700213 s.context.VisitDepsDepthFirstIf(module, pred, visit)
Jamie Gennise98b8a92014-06-17 10:24:24 -0700214}
Mathias Agopian5b8477d2014-06-25 17:21:54 -0700215
Colin Cross24ad5872015-11-17 16:22:29 -0800216func (s *singletonContext) PrimaryModule(module Module) Module {
217 return s.context.PrimaryModule(module)
218}
219
220func (s *singletonContext) FinalModule(module Module) Module {
221 return s.context.FinalModule(module)
222}
223
224func (s *singletonContext) VisitAllModuleVariants(module Module, visit func(Module)) {
225 s.context.VisitAllModuleVariants(module, visit)
226}
227
Mathias Agopian5b8477d2014-06-25 17:21:54 -0700228func (s *singletonContext) AddNinjaFileDeps(deps ...string) {
229 s.ninjaFileDeps = append(s.ninjaFileDeps, deps...)
230}