blob: 1426ff93c4f9fba6439c0d904f0d1024959b4b73 [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"
19 "path/filepath"
20)
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
31 BlueprintFile(module Module) string
32
33 ModuleErrorf(module Module, format string, args ...interface{})
34 Errorf(format string, args ...interface{})
35
Jamie Gennis2fb20952014-10-03 02:49:58 -070036 Variable(pctx *PackageContext, name, value string)
37 Rule(pctx *PackageContext, name string, params RuleParams, argNames ...string) Rule
38 Build(pctx *PackageContext, params BuildParams)
Jamie Gennis1bc967e2014-05-27 16:34:41 -070039 RequireNinjaVersion(major, minor, micro int)
40
41 // SetBuildDir sets the value of the top-level "builddir" Ninja variable
42 // that controls where Ninja stores its build log files. This value can be
43 // set at most one time for a single build. Setting it multiple times (even
44 // across different singletons) will result in a panic.
Jamie Gennis2fb20952014-10-03 02:49:58 -070045 SetBuildDir(pctx *PackageContext, value string)
Jamie Gennis1bc967e2014-05-27 16:34:41 -070046
47 VisitAllModules(visit func(Module))
48 VisitAllModulesIf(pred func(Module) bool, visit func(Module))
Jamie Gennise98b8a92014-06-17 10:24:24 -070049 VisitDepsDepthFirst(module Module, visit func(Module))
50 VisitDepsDepthFirstIf(module Module, pred func(Module) bool,
51 visit func(Module))
Mathias Agopian5b8477d2014-06-25 17:21:54 -070052
53 AddNinjaFileDeps(deps ...string)
Jamie Gennis1bc967e2014-05-27 16:34:41 -070054}
55
56var _ SingletonContext = (*singletonContext)(nil)
57
58type singletonContext struct {
59 context *Context
Jamie Gennis6eb4d242014-06-11 18:31:16 -070060 config interface{}
Jamie Gennis1bc967e2014-05-27 16:34:41 -070061 scope *localScope
62
Mathias Agopian5b8477d2014-06-25 17:21:54 -070063 ninjaFileDeps []string
64 errs []error
Jamie Gennis1bc967e2014-05-27 16:34:41 -070065
66 actionDefs localBuildActions
67}
68
Jamie Gennis6eb4d242014-06-11 18:31:16 -070069func (s *singletonContext) Config() interface{} {
Jamie Gennis1bc967e2014-05-27 16:34:41 -070070 return s.config
71}
72
Colin Crossbbfa51a2014-12-17 16:12:41 -080073func (s *singletonContext) ModuleName(logicModule Module) string {
74 module := s.context.moduleInfo[logicModule]
75 return module.group.properties.Name
Jamie Gennis1bc967e2014-05-27 16:34:41 -070076}
77
Colin Crossbbfa51a2014-12-17 16:12:41 -080078func (s *singletonContext) ModuleDir(logicModule Module) string {
79 module := s.context.moduleInfo[logicModule]
80 return filepath.Dir(module.group.relBlueprintsFile)
Jamie Gennis1bc967e2014-05-27 16:34:41 -070081}
82
Colin Crossbbfa51a2014-12-17 16:12:41 -080083func (s *singletonContext) BlueprintFile(logicModule Module) string {
84 module := s.context.moduleInfo[logicModule]
85 return module.group.relBlueprintsFile
Jamie Gennis1bc967e2014-05-27 16:34:41 -070086}
87
Colin Crossbbfa51a2014-12-17 16:12:41 -080088func (s *singletonContext) ModuleErrorf(logicModule Module, format string,
Jamie Gennis1bc967e2014-05-27 16:34:41 -070089 args ...interface{}) {
90
Colin Crossbbfa51a2014-12-17 16:12:41 -080091 module := s.context.moduleInfo[logicModule]
Jamie Gennis1bc967e2014-05-27 16:34:41 -070092 s.errs = append(s.errs, &Error{
93 Err: fmt.Errorf(format, args...),
Colin Crossbbfa51a2014-12-17 16:12:41 -080094 Pos: module.group.pos,
Jamie Gennis1bc967e2014-05-27 16:34:41 -070095 })
96}
97
98func (s *singletonContext) Errorf(format string, args ...interface{}) {
99 // TODO: Make this not result in the error being printed as "internal error"
100 s.errs = append(s.errs, fmt.Errorf(format, args...))
101}
102
Jamie Gennis2fb20952014-10-03 02:49:58 -0700103func (s *singletonContext) Variable(pctx *PackageContext, name, value string) {
104 s.scope.ReparentTo(pctx)
Jamie Gennis0ed63ef2014-06-30 18:07:17 -0700105
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700106 v, err := s.scope.AddLocalVariable(name, value)
107 if err != nil {
108 panic(err)
109 }
110
111 s.actionDefs.variables = append(s.actionDefs.variables, v)
112}
113
Jamie Gennis2fb20952014-10-03 02:49:58 -0700114func (s *singletonContext) Rule(pctx *PackageContext, name string,
115 params RuleParams, argNames ...string) Rule {
Jamie Genniscbc6f862014-06-05 20:00:22 -0700116
Jamie Gennis2fb20952014-10-03 02:49:58 -0700117 s.scope.ReparentTo(pctx)
Jamie Gennis0ed63ef2014-06-30 18:07:17 -0700118
Jamie Genniscbc6f862014-06-05 20:00:22 -0700119 r, err := s.scope.AddLocalRule(name, &params, argNames...)
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700120 if err != nil {
121 panic(err)
122 }
123
124 s.actionDefs.rules = append(s.actionDefs.rules, r)
125
126 return r
127}
128
Jamie Gennis2fb20952014-10-03 02:49:58 -0700129func (s *singletonContext) Build(pctx *PackageContext, params BuildParams) {
130 s.scope.ReparentTo(pctx)
Jamie Gennis0ed63ef2014-06-30 18:07:17 -0700131
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700132 def, err := parseBuildParams(s.scope, &params)
133 if err != nil {
134 panic(err)
135 }
136
137 s.actionDefs.buildDefs = append(s.actionDefs.buildDefs, def)
138}
139
140func (s *singletonContext) RequireNinjaVersion(major, minor, micro int) {
141 s.context.requireNinjaVersion(major, minor, micro)
142}
143
Jamie Gennis2fb20952014-10-03 02:49:58 -0700144func (s *singletonContext) SetBuildDir(pctx *PackageContext, value string) {
145 s.scope.ReparentTo(pctx)
Jamie Gennis7d5b2f82014-09-24 17:51:52 -0700146
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700147 ninjaValue, err := parseNinjaString(s.scope, value)
148 if err != nil {
149 panic(err)
150 }
151
152 s.context.setBuildDir(ninjaValue)
153}
154
155func (s *singletonContext) VisitAllModules(visit func(Module)) {
156 s.context.visitAllModules(visit)
157}
158
159func (s *singletonContext) VisitAllModulesIf(pred func(Module) bool,
160 visit func(Module)) {
161
162 s.context.visitAllModulesIf(pred, visit)
163}
Jamie Gennise98b8a92014-06-17 10:24:24 -0700164
165func (s *singletonContext) VisitDepsDepthFirst(module Module,
166 visit func(Module)) {
167
Colin Crossbbfa51a2014-12-17 16:12:41 -0800168 s.context.visitDepsDepthFirst(s.context.moduleInfo[module], visit)
Jamie Gennise98b8a92014-06-17 10:24:24 -0700169}
170
171func (s *singletonContext) VisitDepsDepthFirstIf(module Module,
172 pred func(Module) bool, visit func(Module)) {
173
Colin Crossbbfa51a2014-12-17 16:12:41 -0800174 s.context.visitDepsDepthFirstIf(s.context.moduleInfo[module], pred, visit)
Jamie Gennise98b8a92014-06-17 10:24:24 -0700175}
Mathias Agopian5b8477d2014-06-25 17:21:54 -0700176
177func (s *singletonContext) AddNinjaFileDeps(deps ...string) {
178 s.ninjaFileDeps = append(s.ninjaFileDeps, deps...)
179}