blob: 7ff96c9d5509cee09a75da33703921d5d4ef0f2c [file] [log] [blame]
Colin Cross0875c522017-11-28 17:34:01 -08001// Copyright 2017 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
15package android
16
17import (
18 "github.com/google/blueprint"
Colin Cross0875c522017-11-28 17:34:01 -080019)
20
21// SingletonContext
22type SingletonContext interface {
Colin Crossaabf6792017-11-29 00:27:14 -080023 Config() Config
Colin Cross65494b92019-02-07 14:25:51 -080024 DeviceConfig() DeviceConfig
Colin Cross0875c522017-11-28 17:34:01 -080025
26 ModuleName(module blueprint.Module) string
27 ModuleDir(module blueprint.Module) string
28 ModuleSubDir(module blueprint.Module) string
29 ModuleType(module blueprint.Module) string
30 BlueprintFile(module blueprint.Module) string
31
Colin Crossd27e7b82020-07-02 11:38:17 -070032 // ModuleProvider returns the value, if any, for the provider for a module. If the value for the
33 // provider was not set it returns the zero value of the type of the provider, which means the
34 // return value can always be type-asserted to the type of the provider. The return value should
35 // always be considered read-only. It panics if called before the appropriate mutator or
36 // GenerateBuildActions pass for the provider on the module.
37 ModuleProvider(module blueprint.Module, provider blueprint.ProviderKey) interface{}
38
39 // ModuleHasProvider returns true if the provider for the given module has been set.
40 ModuleHasProvider(module blueprint.Module, provider blueprint.ProviderKey) bool
41
Colin Cross0875c522017-11-28 17:34:01 -080042 ModuleErrorf(module blueprint.Module, format string, args ...interface{})
43 Errorf(format string, args ...interface{})
44 Failed() bool
45
46 Variable(pctx PackageContext, name, value string)
Colin Cross59014392017-12-12 11:05:06 -080047 Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule
Colin Cross0875c522017-11-28 17:34:01 -080048 Build(pctx PackageContext, params BuildParams)
Colin Crossc3d87d32020-06-04 13:25:17 -070049
50 // Phony creates a Make-style phony rule, a rule with no commands that can depend on other
51 // phony rules or real files. Phony can be called on the same name multiple times to add
52 // additional dependencies.
53 Phony(name string, deps ...Path)
54
Colin Cross0875c522017-11-28 17:34:01 -080055 RequireNinjaVersion(major, minor, micro int)
56
Lukacs T. Berkifbaf7252021-08-19 09:36:42 +020057 // SetOutDir sets the value of the top-level "builddir" Ninja variable
Colin Cross0875c522017-11-28 17:34:01 -080058 // that controls where Ninja stores its build log files. This value can be
59 // set at most one time for a single build, later calls are ignored.
Lukacs T. Berkifbaf7252021-08-19 09:36:42 +020060 SetOutDir(pctx PackageContext, value string)
Colin Cross0875c522017-11-28 17:34:01 -080061
62 // Eval takes a string with embedded ninja variables, and returns a string
63 // with all of the variables recursively expanded. Any variables references
64 // are expanded in the scope of the PackageContext.
65 Eval(pctx PackageContext, ninjaStr string) (string, error)
66
Colin Cross2465c3d2018-09-28 10:19:18 -070067 VisitAllModulesBlueprint(visit func(blueprint.Module))
Colin Cross0875c522017-11-28 17:34:01 -080068 VisitAllModules(visit func(Module))
69 VisitAllModulesIf(pred func(Module) bool, visit func(Module))
Mitch Phillips3a7a31b2019-10-16 15:00:12 -070070
71 VisitDirectDeps(module Module, visit func(Module))
72 VisitDirectDepsIf(module Module, pred func(Module) bool, visit func(Module))
73
Colin Cross6b753602018-06-21 13:03:07 -070074 // Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
Colin Cross0875c522017-11-28 17:34:01 -080075 VisitDepsDepthFirst(module Module, visit func(Module))
Colin Cross6b753602018-06-21 13:03:07 -070076 // Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
Colin Cross0875c522017-11-28 17:34:01 -080077 VisitDepsDepthFirstIf(module Module, pred func(Module) bool,
78 visit func(Module))
79
80 VisitAllModuleVariants(module Module, visit func(Module))
81
82 PrimaryModule(module Module) Module
83 FinalModule(module Module) Module
84
85 AddNinjaFileDeps(deps ...string)
86
87 // GlobWithDeps returns a list of files that match the specified pattern but do not match any
88 // of the patterns in excludes. It also adds efficient dependencies to rerun the primary
89 // builder whenever a file matching the pattern as added or removed, without rerunning if a
90 // file that does not match the pattern is added to a searched directory.
91 GlobWithDeps(pattern string, excludes []string) ([]string, error)
Colin Cross0875c522017-11-28 17:34:01 -080092}
93
94type singletonAdaptor struct {
95 Singleton
Colin Cross4c83e5c2019-02-25 14:54:28 -080096
97 buildParams []BuildParams
98 ruleParams map[blueprint.Rule]blueprint.RuleParams
Colin Cross0875c522017-11-28 17:34:01 -080099}
100
Colin Cross4c83e5c2019-02-25 14:54:28 -0800101var _ testBuildProvider = (*singletonAdaptor)(nil)
102
103func (s *singletonAdaptor) GenerateBuildActions(ctx blueprint.SingletonContext) {
104 sctx := &singletonContextAdaptor{SingletonContext: ctx}
105 if sctx.Config().captureBuild {
106 sctx.ruleParams = make(map[blueprint.Rule]blueprint.RuleParams)
107 }
108
109 s.Singleton.GenerateBuildActions(sctx)
110
111 s.buildParams = sctx.buildParams
112 s.ruleParams = sctx.ruleParams
113}
114
115func (s *singletonAdaptor) BuildParamsForTests() []BuildParams {
116 return s.buildParams
117}
118
119func (s *singletonAdaptor) RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams {
120 return s.ruleParams
Colin Cross0875c522017-11-28 17:34:01 -0800121}
122
123type Singleton interface {
124 GenerateBuildActions(SingletonContext)
125}
126
127type singletonContextAdaptor struct {
128 blueprint.SingletonContext
Colin Cross4c83e5c2019-02-25 14:54:28 -0800129
130 buildParams []BuildParams
131 ruleParams map[blueprint.Rule]blueprint.RuleParams
Colin Cross0875c522017-11-28 17:34:01 -0800132}
133
Colin Cross4c83e5c2019-02-25 14:54:28 -0800134func (s *singletonContextAdaptor) Config() Config {
Colin Crossaabf6792017-11-29 00:27:14 -0800135 return s.SingletonContext.Config().(Config)
136}
137
Colin Cross4c83e5c2019-02-25 14:54:28 -0800138func (s *singletonContextAdaptor) DeviceConfig() DeviceConfig {
Colin Cross65494b92019-02-07 14:25:51 -0800139 return DeviceConfig{s.Config().deviceConfig}
140}
141
Colin Cross4c83e5c2019-02-25 14:54:28 -0800142func (s *singletonContextAdaptor) Variable(pctx PackageContext, name, value string) {
Colin Cross0875c522017-11-28 17:34:01 -0800143 s.SingletonContext.Variable(pctx.PackageContext, name, value)
144}
145
Colin Cross4c83e5c2019-02-25 14:54:28 -0800146func (s *singletonContextAdaptor) Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule {
Ramy Medhat944839a2020-03-31 22:14:52 -0400147 if s.Config().UseRemoteBuild() {
148 if params.Pool == nil {
149 // When USE_GOMA=true or USE_RBE=true are set and the rule is not supported by goma/RBE, restrict
150 // jobs to the local parallelism value
151 params.Pool = localPool
152 } else if params.Pool == remotePool {
153 // remotePool is a fake pool used to identify rule that are supported for remoting. If the rule's
154 // pool is the remotePool, replace with nil so that ninja runs it at NINJA_REMOTE_NUM_JOBS
155 // parallelism.
156 params.Pool = nil
157 }
Colin Cross2e2dbc22019-09-25 13:31:46 -0700158 }
Colin Cross4c83e5c2019-02-25 14:54:28 -0800159 rule := s.SingletonContext.Rule(pctx.PackageContext, name, params, argNames...)
160 if s.Config().captureBuild {
161 s.ruleParams[rule] = params
162 }
163 return rule
Colin Cross0875c522017-11-28 17:34:01 -0800164}
165
Colin Cross4c83e5c2019-02-25 14:54:28 -0800166func (s *singletonContextAdaptor) Build(pctx PackageContext, params BuildParams) {
167 if s.Config().captureBuild {
168 s.buildParams = append(s.buildParams, params)
169 }
Colin Cross0875c522017-11-28 17:34:01 -0800170 bparams := convertBuildParams(params)
Jingwen Chence679d22020-09-23 04:30:02 +0000171 err := validateBuildParams(bparams)
172 if err != nil {
173 s.Errorf("%s: build parameter validation failed: %s", s.Name(), err.Error())
174 }
Colin Cross0875c522017-11-28 17:34:01 -0800175 s.SingletonContext.Build(pctx.PackageContext, bparams)
176
177}
178
Colin Crossc3d87d32020-06-04 13:25:17 -0700179func (s *singletonContextAdaptor) Phony(name string, deps ...Path) {
180 addPhony(s.Config(), name, deps...)
181}
182
Lukacs T. Berkifbaf7252021-08-19 09:36:42 +0200183func (s *singletonContextAdaptor) SetOutDir(pctx PackageContext, value string) {
184 s.SingletonContext.SetOutDir(pctx.PackageContext, value)
Colin Cross0875c522017-11-28 17:34:01 -0800185}
186
Colin Cross4c83e5c2019-02-25 14:54:28 -0800187func (s *singletonContextAdaptor) Eval(pctx PackageContext, ninjaStr string) (string, error) {
Colin Cross0875c522017-11-28 17:34:01 -0800188 return s.SingletonContext.Eval(pctx.PackageContext, ninjaStr)
189}
190
191// visitAdaptor wraps a visit function that takes an android.Module parameter into
192// a function that takes an blueprint.Module parameter and only calls the visit function if the
193// blueprint.Module is an android.Module.
194func visitAdaptor(visit func(Module)) func(blueprint.Module) {
195 return func(module blueprint.Module) {
196 if aModule, ok := module.(Module); ok {
197 visit(aModule)
198 }
199 }
200}
201
202// predAdaptor wraps a pred function that takes an android.Module parameter
203// into a function that takes an blueprint.Module parameter and only calls the visit function if the
204// blueprint.Module is an android.Module, otherwise returns false.
205func predAdaptor(pred func(Module) bool) func(blueprint.Module) bool {
206 return func(module blueprint.Module) bool {
207 if aModule, ok := module.(Module); ok {
208 return pred(aModule)
209 } else {
210 return false
211 }
212 }
213}
214
Colin Cross4c83e5c2019-02-25 14:54:28 -0800215func (s *singletonContextAdaptor) VisitAllModulesBlueprint(visit func(blueprint.Module)) {
Colin Cross2465c3d2018-09-28 10:19:18 -0700216 s.SingletonContext.VisitAllModules(visit)
217}
218
Colin Cross4c83e5c2019-02-25 14:54:28 -0800219func (s *singletonContextAdaptor) VisitAllModules(visit func(Module)) {
Colin Cross0875c522017-11-28 17:34:01 -0800220 s.SingletonContext.VisitAllModules(visitAdaptor(visit))
221}
222
Colin Cross4c83e5c2019-02-25 14:54:28 -0800223func (s *singletonContextAdaptor) VisitAllModulesIf(pred func(Module) bool, visit func(Module)) {
Colin Cross0875c522017-11-28 17:34:01 -0800224 s.SingletonContext.VisitAllModulesIf(predAdaptor(pred), visitAdaptor(visit))
225}
226
Mitch Phillips3a7a31b2019-10-16 15:00:12 -0700227func (s *singletonContextAdaptor) VisitDirectDeps(module Module, visit func(Module)) {
228 s.SingletonContext.VisitDirectDeps(module, visitAdaptor(visit))
229}
230
231func (s *singletonContextAdaptor) VisitDirectDepsIf(module Module, pred func(Module) bool, visit func(Module)) {
232 s.SingletonContext.VisitDirectDepsIf(module, predAdaptor(pred), visitAdaptor(visit))
233}
234
Colin Cross4c83e5c2019-02-25 14:54:28 -0800235func (s *singletonContextAdaptor) VisitDepsDepthFirst(module Module, visit func(Module)) {
Colin Cross0875c522017-11-28 17:34:01 -0800236 s.SingletonContext.VisitDepsDepthFirst(module, visitAdaptor(visit))
237}
238
Colin Cross4c83e5c2019-02-25 14:54:28 -0800239func (s *singletonContextAdaptor) VisitDepsDepthFirstIf(module Module, pred func(Module) bool, visit func(Module)) {
Colin Cross0875c522017-11-28 17:34:01 -0800240 s.SingletonContext.VisitDepsDepthFirstIf(module, predAdaptor(pred), visitAdaptor(visit))
241}
242
Colin Cross4c83e5c2019-02-25 14:54:28 -0800243func (s *singletonContextAdaptor) VisitAllModuleVariants(module Module, visit func(Module)) {
Colin Cross0875c522017-11-28 17:34:01 -0800244 s.SingletonContext.VisitAllModuleVariants(module, visitAdaptor(visit))
245}
246
Colin Cross4c83e5c2019-02-25 14:54:28 -0800247func (s *singletonContextAdaptor) PrimaryModule(module Module) Module {
Colin Cross0875c522017-11-28 17:34:01 -0800248 return s.SingletonContext.PrimaryModule(module).(Module)
249}
250
Colin Cross4c83e5c2019-02-25 14:54:28 -0800251func (s *singletonContextAdaptor) FinalModule(module Module) Module {
Colin Cross0875c522017-11-28 17:34:01 -0800252 return s.SingletonContext.FinalModule(module).(Module)
253}