blob: 31195af7f84064b0bd354c7e83db300fda20240c [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 Crossb519a7e2017-02-01 13:21:35 -080019 "github.com/google/blueprint/pathtools"
Jamie Gennis1bc967e2014-05-27 16:34:41 -070020)
21
22type Singleton interface {
23 GenerateBuildActions(SingletonContext)
24}
25
26type SingletonContext interface {
Jamie Gennis6eb4d242014-06-11 18:31:16 -070027 Config() interface{}
Jamie Gennis1bc967e2014-05-27 16:34:41 -070028
29 ModuleName(module Module) string
30 ModuleDir(module Module) string
Colin Cross8c602f72015-12-17 18:02:11 -080031 ModuleSubDir(module Module) string
Dan Willemsenc98e55b2016-07-25 15:51:50 -070032 ModuleType(module Module) string
Jamie Gennis1bc967e2014-05-27 16:34:41 -070033 BlueprintFile(module Module) string
34
35 ModuleErrorf(module Module, format string, args ...interface{})
36 Errorf(format string, args ...interface{})
Dan Willemsen265d92c2015-12-09 18:06:23 -080037 Failed() bool
Jamie Gennis1bc967e2014-05-27 16:34:41 -070038
Dan Willemsenaeffbf72015-11-25 15:29:32 -080039 Variable(pctx PackageContext, name, value string)
40 Rule(pctx PackageContext, name string, params RuleParams, argNames ...string) Rule
41 Build(pctx PackageContext, params BuildParams)
Jamie Gennis1bc967e2014-05-27 16:34:41 -070042 RequireNinjaVersion(major, minor, micro int)
43
Colin Crossa2599452015-11-18 16:01:01 -080044 // SetNinjaBuildDir sets the value of the top-level "builddir" Ninja variable
Jamie Gennis1bc967e2014-05-27 16:34:41 -070045 // that controls where Ninja stores its build log files. This value can be
Colin Crossa2599452015-11-18 16:01:01 -080046 // set at most one time for a single build, later calls are ignored.
Dan Willemsenaeffbf72015-11-25 15:29:32 -080047 SetNinjaBuildDir(pctx PackageContext, value string)
Jamie Gennis1bc967e2014-05-27 16:34:41 -070048
Dan Willemsen4bb62762016-01-14 15:42:54 -080049 // Eval takes a string with embedded ninja variables, and returns a string
50 // with all of the variables recursively expanded. Any variables references
51 // are expanded in the scope of the PackageContext.
52 Eval(pctx PackageContext, ninjaStr string) (string, error)
53
Jamie Gennis1bc967e2014-05-27 16:34:41 -070054 VisitAllModules(visit func(Module))
55 VisitAllModulesIf(pred func(Module) bool, visit func(Module))
Jamie Gennise98b8a92014-06-17 10:24:24 -070056 VisitDepsDepthFirst(module Module, visit func(Module))
57 VisitDepsDepthFirstIf(module Module, pred func(Module) bool,
58 visit func(Module))
Mathias Agopian5b8477d2014-06-25 17:21:54 -070059
Colin Cross24ad5872015-11-17 16:22:29 -080060 VisitAllModuleVariants(module Module, visit func(Module))
61
62 PrimaryModule(module Module) Module
63 FinalModule(module Module) Module
64
Mathias Agopian5b8477d2014-06-25 17:21:54 -070065 AddNinjaFileDeps(deps ...string)
Colin Cross127d2ea2016-11-01 11:10:51 -070066
67 // GlobWithDeps returns a list of files that match the specified pattern but do not match any
68 // of the patterns in excludes. It also adds efficient dependencies to rerun the primary
69 // builder whenever a file matching the pattern as added or removed, without rerunning if a
70 // file that does not match the pattern is added to a searched directory.
71 GlobWithDeps(pattern string, excludes []string) ([]string, error)
Colin Crossb519a7e2017-02-01 13:21:35 -080072
73 Fs() pathtools.FileSystem
Jamie Gennis1bc967e2014-05-27 16:34:41 -070074}
75
76var _ SingletonContext = (*singletonContext)(nil)
77
78type singletonContext struct {
79 context *Context
Jamie Gennis6eb4d242014-06-11 18:31:16 -070080 config interface{}
Jamie Gennis1bc967e2014-05-27 16:34:41 -070081 scope *localScope
Dan Willemsen4bb62762016-01-14 15:42:54 -080082 globals *liveTracker
Jamie Gennis1bc967e2014-05-27 16:34:41 -070083
Mathias Agopian5b8477d2014-06-25 17:21:54 -070084 ninjaFileDeps []string
85 errs []error
Jamie Gennis1bc967e2014-05-27 16:34:41 -070086
87 actionDefs localBuildActions
88}
89
Jamie Gennis6eb4d242014-06-11 18:31:16 -070090func (s *singletonContext) Config() interface{} {
Jamie Gennis1bc967e2014-05-27 16:34:41 -070091 return s.config
92}
93
Colin Crossbbfa51a2014-12-17 16:12:41 -080094func (s *singletonContext) ModuleName(logicModule Module) string {
Colin Cross4572edd2015-05-13 14:36:24 -070095 return s.context.ModuleName(logicModule)
Jamie Gennis1bc967e2014-05-27 16:34:41 -070096}
97
Colin Crossbbfa51a2014-12-17 16:12:41 -080098func (s *singletonContext) ModuleDir(logicModule Module) string {
Colin Cross4572edd2015-05-13 14:36:24 -070099 return s.context.ModuleDir(logicModule)
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700100}
101
Colin Cross8c602f72015-12-17 18:02:11 -0800102func (s *singletonContext) ModuleSubDir(logicModule Module) string {
103 return s.context.ModuleSubDir(logicModule)
104}
105
Dan Willemsenc98e55b2016-07-25 15:51:50 -0700106func (s *singletonContext) ModuleType(logicModule Module) string {
107 return s.context.ModuleType(logicModule)
108}
109
Colin Crossbbfa51a2014-12-17 16:12:41 -0800110func (s *singletonContext) BlueprintFile(logicModule Module) string {
Colin Cross4572edd2015-05-13 14:36:24 -0700111 return s.context.BlueprintFile(logicModule)
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700112}
113
Colin Cross0aa6a5f2016-01-07 13:43:09 -0800114func (s *singletonContext) error(err error) {
115 if err != nil {
116 s.errs = append(s.errs, err)
117 }
118}
119
Colin Crossbbfa51a2014-12-17 16:12:41 -0800120func (s *singletonContext) ModuleErrorf(logicModule Module, format string,
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700121 args ...interface{}) {
122
Colin Cross0aa6a5f2016-01-07 13:43:09 -0800123 s.error(s.context.ModuleErrorf(logicModule, format, args...))
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700124}
125
126func (s *singletonContext) Errorf(format string, args ...interface{}) {
127 // TODO: Make this not result in the error being printed as "internal error"
Colin Cross0aa6a5f2016-01-07 13:43:09 -0800128 s.error(fmt.Errorf(format, args...))
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700129}
130
Dan Willemsen265d92c2015-12-09 18:06:23 -0800131func (s *singletonContext) Failed() bool {
132 return len(s.errs) > 0
133}
134
Dan Willemsenaeffbf72015-11-25 15:29:32 -0800135func (s *singletonContext) Variable(pctx PackageContext, name, value string) {
Jamie Gennis2fb20952014-10-03 02:49:58 -0700136 s.scope.ReparentTo(pctx)
Jamie Gennis0ed63ef2014-06-30 18:07:17 -0700137
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700138 v, err := s.scope.AddLocalVariable(name, value)
139 if err != nil {
140 panic(err)
141 }
142
143 s.actionDefs.variables = append(s.actionDefs.variables, v)
144}
145
Dan Willemsenaeffbf72015-11-25 15:29:32 -0800146func (s *singletonContext) Rule(pctx PackageContext, name string,
Jamie Gennis2fb20952014-10-03 02:49:58 -0700147 params RuleParams, argNames ...string) Rule {
Jamie Genniscbc6f862014-06-05 20:00:22 -0700148
Jamie Gennis2fb20952014-10-03 02:49:58 -0700149 s.scope.ReparentTo(pctx)
Jamie Gennis0ed63ef2014-06-30 18:07:17 -0700150
Jamie Genniscbc6f862014-06-05 20:00:22 -0700151 r, err := s.scope.AddLocalRule(name, &params, argNames...)
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700152 if err != nil {
153 panic(err)
154 }
155
156 s.actionDefs.rules = append(s.actionDefs.rules, r)
157
158 return r
159}
160
Dan Willemsenaeffbf72015-11-25 15:29:32 -0800161func (s *singletonContext) Build(pctx PackageContext, params BuildParams) {
Jamie Gennis2fb20952014-10-03 02:49:58 -0700162 s.scope.ReparentTo(pctx)
Jamie Gennis0ed63ef2014-06-30 18:07:17 -0700163
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700164 def, err := parseBuildParams(s.scope, &params)
165 if err != nil {
166 panic(err)
167 }
168
169 s.actionDefs.buildDefs = append(s.actionDefs.buildDefs, def)
170}
171
Dan Willemsen4bb62762016-01-14 15:42:54 -0800172func (s *singletonContext) Eval(pctx PackageContext, str string) (string, error) {
173 s.scope.ReparentTo(pctx)
174
175 ninjaStr, err := parseNinjaString(s.scope, str)
176 if err != nil {
177 return "", err
178 }
179
180 err = s.globals.addNinjaStringDeps(ninjaStr)
181 if err != nil {
182 return "", err
183 }
184
185 return ninjaStr.Eval(s.globals.variables)
186}
187
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700188func (s *singletonContext) RequireNinjaVersion(major, minor, micro int) {
189 s.context.requireNinjaVersion(major, minor, micro)
190}
191
Dan Willemsenaeffbf72015-11-25 15:29:32 -0800192func (s *singletonContext) SetNinjaBuildDir(pctx PackageContext, value string) {
Jamie Gennis2fb20952014-10-03 02:49:58 -0700193 s.scope.ReparentTo(pctx)
Jamie Gennis7d5b2f82014-09-24 17:51:52 -0700194
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700195 ninjaValue, err := parseNinjaString(s.scope, value)
196 if err != nil {
197 panic(err)
198 }
199
Colin Crossa2599452015-11-18 16:01:01 -0800200 s.context.setNinjaBuildDir(ninjaValue)
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700201}
202
203func (s *singletonContext) VisitAllModules(visit func(Module)) {
Colin Cross4572edd2015-05-13 14:36:24 -0700204 s.context.VisitAllModules(visit)
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700205}
206
207func (s *singletonContext) VisitAllModulesIf(pred func(Module) bool,
208 visit func(Module)) {
209
Colin Cross4572edd2015-05-13 14:36:24 -0700210 s.context.VisitAllModulesIf(pred, visit)
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700211}
Jamie Gennise98b8a92014-06-17 10:24:24 -0700212
213func (s *singletonContext) VisitDepsDepthFirst(module Module,
214 visit func(Module)) {
215
Colin Cross4572edd2015-05-13 14:36:24 -0700216 s.context.VisitDepsDepthFirst(module, visit)
Jamie Gennise98b8a92014-06-17 10:24:24 -0700217}
218
219func (s *singletonContext) VisitDepsDepthFirstIf(module Module,
220 pred func(Module) bool, visit func(Module)) {
221
Colin Cross4572edd2015-05-13 14:36:24 -0700222 s.context.VisitDepsDepthFirstIf(module, pred, visit)
Jamie Gennise98b8a92014-06-17 10:24:24 -0700223}
Mathias Agopian5b8477d2014-06-25 17:21:54 -0700224
Colin Cross24ad5872015-11-17 16:22:29 -0800225func (s *singletonContext) PrimaryModule(module Module) Module {
226 return s.context.PrimaryModule(module)
227}
228
229func (s *singletonContext) FinalModule(module Module) Module {
230 return s.context.FinalModule(module)
231}
232
233func (s *singletonContext) VisitAllModuleVariants(module Module, visit func(Module)) {
234 s.context.VisitAllModuleVariants(module, visit)
235}
236
Mathias Agopian5b8477d2014-06-25 17:21:54 -0700237func (s *singletonContext) AddNinjaFileDeps(deps ...string) {
238 s.ninjaFileDeps = append(s.ninjaFileDeps, deps...)
239}
Colin Cross127d2ea2016-11-01 11:10:51 -0700240
241func (s *singletonContext) GlobWithDeps(pattern string,
242 excludes []string) ([]string, error) {
243 return s.context.glob(pattern, excludes)
244}
Colin Crossb519a7e2017-02-01 13:21:35 -0800245
246func (s *singletonContext) Fs() pathtools.FileSystem {
247 return s.context.fs
248}