blob: de5bae74a1e79319c2bfcecbcd996a69abd54c70 [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"
Colin Crossc5816202017-12-11 14:39:10 -080019
Colin Crossb519a7e2017-02-01 13:21:35 -080020 "github.com/google/blueprint/pathtools"
Jamie Gennis1bc967e2014-05-27 16:34:41 -070021)
22
23type Singleton interface {
24 GenerateBuildActions(SingletonContext)
25}
26
27type SingletonContext interface {
Jamie Gennis6eb4d242014-06-11 18:31:16 -070028 Config() interface{}
Jamie Gennis1bc967e2014-05-27 16:34:41 -070029
Colin Cross9226d6c2019-02-25 18:07:44 -080030 Name() string
31
Jamie Gennis1bc967e2014-05-27 16:34:41 -070032 ModuleName(module Module) string
33 ModuleDir(module Module) string
Colin Cross8c602f72015-12-17 18:02:11 -080034 ModuleSubDir(module Module) string
Dan Willemsenc98e55b2016-07-25 15:51:50 -070035 ModuleType(module Module) string
Jamie Gennis1bc967e2014-05-27 16:34:41 -070036 BlueprintFile(module Module) string
37
38 ModuleErrorf(module Module, format string, args ...interface{})
39 Errorf(format string, args ...interface{})
Dan Willemsen265d92c2015-12-09 18:06:23 -080040 Failed() bool
Jamie Gennis1bc967e2014-05-27 16:34:41 -070041
Dan Willemsenaeffbf72015-11-25 15:29:32 -080042 Variable(pctx PackageContext, name, value string)
43 Rule(pctx PackageContext, name string, params RuleParams, argNames ...string) Rule
44 Build(pctx PackageContext, params BuildParams)
Jamie Gennis1bc967e2014-05-27 16:34:41 -070045 RequireNinjaVersion(major, minor, micro int)
46
Colin Crossa2599452015-11-18 16:01:01 -080047 // SetNinjaBuildDir sets the value of the top-level "builddir" Ninja variable
Jamie Gennis1bc967e2014-05-27 16:34:41 -070048 // that controls where Ninja stores its build log files. This value can be
Colin Crossa2599452015-11-18 16:01:01 -080049 // set at most one time for a single build, later calls are ignored.
Dan Willemsenaeffbf72015-11-25 15:29:32 -080050 SetNinjaBuildDir(pctx PackageContext, value string)
Jamie Gennis1bc967e2014-05-27 16:34:41 -070051
Dan Willemsenab223a52018-07-05 21:56:59 -070052 // AddSubninja adds a ninja file to include with subninja. This should likely
53 // only ever be used inside bootstrap to handle glob rules.
54 AddSubninja(file string)
55
Dan Willemsen4bb62762016-01-14 15:42:54 -080056 // Eval takes a string with embedded ninja variables, and returns a string
57 // with all of the variables recursively expanded. Any variables references
58 // are expanded in the scope of the PackageContext.
59 Eval(pctx PackageContext, ninjaStr string) (string, error)
60
Jamie Gennis1bc967e2014-05-27 16:34:41 -070061 VisitAllModules(visit func(Module))
62 VisitAllModulesIf(pred func(Module) bool, visit func(Module))
Jamie Gennise98b8a92014-06-17 10:24:24 -070063 VisitDepsDepthFirst(module Module, visit func(Module))
64 VisitDepsDepthFirstIf(module Module, pred func(Module) bool,
65 visit func(Module))
Mathias Agopian5b8477d2014-06-25 17:21:54 -070066
Colin Cross24ad5872015-11-17 16:22:29 -080067 VisitAllModuleVariants(module Module, visit func(Module))
68
69 PrimaryModule(module Module) Module
70 FinalModule(module Module) Module
71
Mathias Agopian5b8477d2014-06-25 17:21:54 -070072 AddNinjaFileDeps(deps ...string)
Colin Cross127d2ea2016-11-01 11:10:51 -070073
Dan Willemsenb6c90232018-02-23 14:49:45 -080074 // GlobWithDeps returns a list of files and directories that match the
75 // specified pattern but do not match any of the patterns in excludes.
76 // Any directories will have a '/' suffix. It also adds efficient
77 // dependencies to rerun the primary builder whenever a file matching
78 // the pattern as added or removed, without rerunning if a file that
79 // does not match the pattern is added to a searched directory.
Colin Cross127d2ea2016-11-01 11:10:51 -070080 GlobWithDeps(pattern string, excludes []string) ([]string, error)
Colin Crossb519a7e2017-02-01 13:21:35 -080081
82 Fs() pathtools.FileSystem
Jamie Gennis1bc967e2014-05-27 16:34:41 -070083}
84
85var _ SingletonContext = (*singletonContext)(nil)
86
87type singletonContext struct {
Colin Cross9226d6c2019-02-25 18:07:44 -080088 name string
Jamie Gennis1bc967e2014-05-27 16:34:41 -070089 context *Context
Jamie Gennis6eb4d242014-06-11 18:31:16 -070090 config interface{}
Jamie Gennis1bc967e2014-05-27 16:34:41 -070091 scope *localScope
Dan Willemsen4bb62762016-01-14 15:42:54 -080092 globals *liveTracker
Jamie Gennis1bc967e2014-05-27 16:34:41 -070093
Mathias Agopian5b8477d2014-06-25 17:21:54 -070094 ninjaFileDeps []string
95 errs []error
Jamie Gennis1bc967e2014-05-27 16:34:41 -070096
97 actionDefs localBuildActions
98}
99
Jamie Gennis6eb4d242014-06-11 18:31:16 -0700100func (s *singletonContext) Config() interface{} {
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700101 return s.config
102}
103
Colin Cross9226d6c2019-02-25 18:07:44 -0800104func (s *singletonContext) Name() string {
105 return s.name
106}
107
Colin Crossbbfa51a2014-12-17 16:12:41 -0800108func (s *singletonContext) ModuleName(logicModule Module) string {
Colin Cross4572edd2015-05-13 14:36:24 -0700109 return s.context.ModuleName(logicModule)
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700110}
111
Colin Crossbbfa51a2014-12-17 16:12:41 -0800112func (s *singletonContext) ModuleDir(logicModule Module) string {
Colin Cross4572edd2015-05-13 14:36:24 -0700113 return s.context.ModuleDir(logicModule)
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700114}
115
Colin Cross8c602f72015-12-17 18:02:11 -0800116func (s *singletonContext) ModuleSubDir(logicModule Module) string {
117 return s.context.ModuleSubDir(logicModule)
118}
119
Dan Willemsenc98e55b2016-07-25 15:51:50 -0700120func (s *singletonContext) ModuleType(logicModule Module) string {
121 return s.context.ModuleType(logicModule)
122}
123
Colin Crossbbfa51a2014-12-17 16:12:41 -0800124func (s *singletonContext) BlueprintFile(logicModule Module) string {
Colin Cross4572edd2015-05-13 14:36:24 -0700125 return s.context.BlueprintFile(logicModule)
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700126}
127
Colin Cross0aa6a5f2016-01-07 13:43:09 -0800128func (s *singletonContext) error(err error) {
129 if err != nil {
130 s.errs = append(s.errs, err)
131 }
132}
133
Colin Crossbbfa51a2014-12-17 16:12:41 -0800134func (s *singletonContext) ModuleErrorf(logicModule Module, format string,
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700135 args ...interface{}) {
136
Colin Cross0aa6a5f2016-01-07 13:43:09 -0800137 s.error(s.context.ModuleErrorf(logicModule, format, args...))
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700138}
139
140func (s *singletonContext) Errorf(format string, args ...interface{}) {
141 // TODO: Make this not result in the error being printed as "internal error"
Colin Cross0aa6a5f2016-01-07 13:43:09 -0800142 s.error(fmt.Errorf(format, args...))
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700143}
144
Dan Willemsen265d92c2015-12-09 18:06:23 -0800145func (s *singletonContext) Failed() bool {
146 return len(s.errs) > 0
147}
148
Dan Willemsenaeffbf72015-11-25 15:29:32 -0800149func (s *singletonContext) Variable(pctx PackageContext, name, value string) {
Jamie Gennis2fb20952014-10-03 02:49:58 -0700150 s.scope.ReparentTo(pctx)
Jamie Gennis0ed63ef2014-06-30 18:07:17 -0700151
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700152 v, err := s.scope.AddLocalVariable(name, value)
153 if err != nil {
154 panic(err)
155 }
156
157 s.actionDefs.variables = append(s.actionDefs.variables, v)
158}
159
Dan Willemsenaeffbf72015-11-25 15:29:32 -0800160func (s *singletonContext) Rule(pctx PackageContext, name string,
Jamie Gennis2fb20952014-10-03 02:49:58 -0700161 params RuleParams, argNames ...string) Rule {
Jamie Genniscbc6f862014-06-05 20:00:22 -0700162
Jamie Gennis2fb20952014-10-03 02:49:58 -0700163 s.scope.ReparentTo(pctx)
Jamie Gennis0ed63ef2014-06-30 18:07:17 -0700164
Jamie Genniscbc6f862014-06-05 20:00:22 -0700165 r, err := s.scope.AddLocalRule(name, &params, argNames...)
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700166 if err != nil {
167 panic(err)
168 }
169
170 s.actionDefs.rules = append(s.actionDefs.rules, r)
171
172 return r
173}
174
Dan Willemsenaeffbf72015-11-25 15:29:32 -0800175func (s *singletonContext) Build(pctx PackageContext, params BuildParams) {
Jamie Gennis2fb20952014-10-03 02:49:58 -0700176 s.scope.ReparentTo(pctx)
Jamie Gennis0ed63ef2014-06-30 18:07:17 -0700177
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700178 def, err := parseBuildParams(s.scope, &params)
179 if err != nil {
180 panic(err)
181 }
182
183 s.actionDefs.buildDefs = append(s.actionDefs.buildDefs, def)
184}
185
Dan Willemsen4bb62762016-01-14 15:42:54 -0800186func (s *singletonContext) Eval(pctx PackageContext, str string) (string, error) {
187 s.scope.ReparentTo(pctx)
188
189 ninjaStr, err := parseNinjaString(s.scope, str)
190 if err != nil {
191 return "", err
192 }
193
194 err = s.globals.addNinjaStringDeps(ninjaStr)
195 if err != nil {
196 return "", err
197 }
198
199 return ninjaStr.Eval(s.globals.variables)
200}
201
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700202func (s *singletonContext) RequireNinjaVersion(major, minor, micro int) {
203 s.context.requireNinjaVersion(major, minor, micro)
204}
205
Dan Willemsenaeffbf72015-11-25 15:29:32 -0800206func (s *singletonContext) SetNinjaBuildDir(pctx PackageContext, value string) {
Jamie Gennis2fb20952014-10-03 02:49:58 -0700207 s.scope.ReparentTo(pctx)
Jamie Gennis7d5b2f82014-09-24 17:51:52 -0700208
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700209 ninjaValue, err := parseNinjaString(s.scope, value)
210 if err != nil {
211 panic(err)
212 }
213
Colin Crossa2599452015-11-18 16:01:01 -0800214 s.context.setNinjaBuildDir(ninjaValue)
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700215}
216
Dan Willemsenab223a52018-07-05 21:56:59 -0700217func (s *singletonContext) AddSubninja(file string) {
218 s.context.subninjas = append(s.context.subninjas, file)
219}
220
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700221func (s *singletonContext) VisitAllModules(visit func(Module)) {
Colin Cross7f90d172018-09-19 13:37:29 -0700222 var visitingModule Module
223 defer func() {
224 if r := recover(); r != nil {
225 panic(newPanicErrorf(r, "VisitAllModules(%s) for module %s",
Colin Cross818af3b2019-03-25 15:04:09 -0700226 funcName(visit), s.context.moduleInfo[visitingModule]))
Colin Cross7f90d172018-09-19 13:37:29 -0700227 }
228 }()
229
230 s.context.VisitAllModules(func(m Module) {
231 visitingModule = m
232 visit(m)
233 })
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700234}
235
236func (s *singletonContext) VisitAllModulesIf(pred func(Module) bool,
237 visit func(Module)) {
238
Colin Cross4572edd2015-05-13 14:36:24 -0700239 s.context.VisitAllModulesIf(pred, visit)
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700240}
Jamie Gennise98b8a92014-06-17 10:24:24 -0700241
242func (s *singletonContext) VisitDepsDepthFirst(module Module,
243 visit func(Module)) {
244
Colin Cross4572edd2015-05-13 14:36:24 -0700245 s.context.VisitDepsDepthFirst(module, visit)
Jamie Gennise98b8a92014-06-17 10:24:24 -0700246}
247
248func (s *singletonContext) VisitDepsDepthFirstIf(module Module,
249 pred func(Module) bool, visit func(Module)) {
250
Colin Cross4572edd2015-05-13 14:36:24 -0700251 s.context.VisitDepsDepthFirstIf(module, pred, visit)
Jamie Gennise98b8a92014-06-17 10:24:24 -0700252}
Mathias Agopian5b8477d2014-06-25 17:21:54 -0700253
Colin Cross24ad5872015-11-17 16:22:29 -0800254func (s *singletonContext) PrimaryModule(module Module) Module {
255 return s.context.PrimaryModule(module)
256}
257
258func (s *singletonContext) FinalModule(module Module) Module {
259 return s.context.FinalModule(module)
260}
261
262func (s *singletonContext) VisitAllModuleVariants(module Module, visit func(Module)) {
263 s.context.VisitAllModuleVariants(module, visit)
264}
265
Mathias Agopian5b8477d2014-06-25 17:21:54 -0700266func (s *singletonContext) AddNinjaFileDeps(deps ...string) {
267 s.ninjaFileDeps = append(s.ninjaFileDeps, deps...)
268}
Colin Cross127d2ea2016-11-01 11:10:51 -0700269
270func (s *singletonContext) GlobWithDeps(pattern string,
271 excludes []string) ([]string, error) {
272 return s.context.glob(pattern, excludes)
273}
Colin Crossb519a7e2017-02-01 13:21:35 -0800274
275func (s *singletonContext) Fs() pathtools.FileSystem {
276 return s.context.fs
277}