blob: 64381828abe8d008930ad632823b41a3d9ef709e [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 Cross3c0a83d2023-12-12 14:13:26 -080023 blueprintSingletonContext() blueprint.SingletonContext
24
Colin Crossaabf6792017-11-29 00:27:14 -080025 Config() Config
Colin Cross65494b92019-02-07 14:25:51 -080026 DeviceConfig() DeviceConfig
Colin Cross0875c522017-11-28 17:34:01 -080027
28 ModuleName(module blueprint.Module) string
29 ModuleDir(module blueprint.Module) string
30 ModuleSubDir(module blueprint.Module) string
31 ModuleType(module blueprint.Module) string
32 BlueprintFile(module blueprint.Module) string
33
Bob Badoureef4c1c2022-05-16 12:20:04 -070034 // ModuleVariantsFromName returns the list of module variants named `name` in the same namespace as `referer` enforcing visibility rules.
35 // Allows generating build actions for `referer` based on the metadata for `name` deferred until the singleton context.
36 ModuleVariantsFromName(referer Module, name string) []Module
37
Yu Liu663e4502024-08-12 18:23:59 +000038 otherModuleProvider(module blueprint.Module, provider blueprint.AnyProviderKey) (any, bool)
Colin Crossd27e7b82020-07-02 11:38:17 -070039
Colin Cross0875c522017-11-28 17:34:01 -080040 ModuleErrorf(module blueprint.Module, format string, args ...interface{})
41 Errorf(format string, args ...interface{})
42 Failed() bool
43
44 Variable(pctx PackageContext, name, value string)
Colin Cross59014392017-12-12 11:05:06 -080045 Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule
Colin Cross0875c522017-11-28 17:34:01 -080046 Build(pctx PackageContext, params BuildParams)
Colin Crossc3d87d32020-06-04 13:25:17 -070047
48 // Phony creates a Make-style phony rule, a rule with no commands that can depend on other
49 // phony rules or real files. Phony can be called on the same name multiple times to add
50 // additional dependencies.
51 Phony(name string, deps ...Path)
52
Colin Cross0875c522017-11-28 17:34:01 -080053 RequireNinjaVersion(major, minor, micro int)
54
Lukacs T. Berki9f6c24a2021-08-26 15:07:24 +020055 // SetOutDir sets the value of the top-level "builddir" Ninja variable
Colin Cross0875c522017-11-28 17:34:01 -080056 // that controls where Ninja stores its build log files. This value can be
57 // set at most one time for a single build, later calls are ignored.
Lukacs T. Berki9f6c24a2021-08-26 15:07:24 +020058 SetOutDir(pctx PackageContext, value string)
Colin Cross0875c522017-11-28 17:34:01 -080059
60 // Eval takes a string with embedded ninja variables, and returns a string
61 // with all of the variables recursively expanded. Any variables references
62 // are expanded in the scope of the PackageContext.
63 Eval(pctx PackageContext, ninjaStr string) (string, error)
64
Colin Cross2465c3d2018-09-28 10:19:18 -070065 VisitAllModulesBlueprint(visit func(blueprint.Module))
Colin Cross0875c522017-11-28 17:34:01 -080066 VisitAllModules(visit func(Module))
Yu Liuec7043d2024-11-05 18:22:20 +000067 VisitAllModuleProxies(visit func(proxy ModuleProxy))
Colin Cross0875c522017-11-28 17:34:01 -080068 VisitAllModulesIf(pred func(Module) bool, visit func(Module))
Mitch Phillips3a7a31b2019-10-16 15:00:12 -070069
70 VisitDirectDeps(module Module, visit func(Module))
71 VisitDirectDepsIf(module Module, pred func(Module) bool, visit func(Module))
72
Colin Cross6b753602018-06-21 13:03:07 -070073 // Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
Colin Cross0875c522017-11-28 17:34:01 -080074 VisitDepsDepthFirst(module Module, visit func(Module))
Colin Cross6b753602018-06-21 13:03:07 -070075 // Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
Colin Cross0875c522017-11-28 17:34:01 -080076 VisitDepsDepthFirstIf(module Module, pred func(Module) bool,
77 visit func(Module))
78
79 VisitAllModuleVariants(module Module, visit func(Module))
80
Yu Liuec7043d2024-11-05 18:22:20 +000081 VisitAllModuleVariantProxies(module Module, visit func(proxy ModuleProxy))
82
Colin Cross0875c522017-11-28 17:34:01 -080083 PrimaryModule(module Module) Module
84 FinalModule(module Module) Module
85
86 AddNinjaFileDeps(deps ...string)
87
88 // GlobWithDeps returns a list of files that match the specified pattern but do not match any
89 // of the patterns in excludes. It also adds efficient dependencies to rerun the primary
90 // builder whenever a file matching the pattern as added or removed, without rerunning if a
91 // file that does not match the pattern is added to a searched directory.
92 GlobWithDeps(pattern string, excludes []string) ([]string, error)
Cole Faust02987bd2024-03-21 17:58:43 -070093
94 // OtherModulePropertyErrorf reports an error on the line number of the given property of the given module
95 OtherModulePropertyErrorf(module Module, property string, format string, args ...interface{})
Cole Faust4e2bf9f2024-09-11 13:26:20 -070096
97 // HasMutatorFinished returns true if the given mutator has finished running.
98 // It will panic if given an invalid mutator name.
99 HasMutatorFinished(mutatorName string) bool
Colin Cross0875c522017-11-28 17:34:01 -0800100}
101
102type singletonAdaptor struct {
103 Singleton
Colin Cross4c83e5c2019-02-25 14:54:28 -0800104
105 buildParams []BuildParams
106 ruleParams map[blueprint.Rule]blueprint.RuleParams
Colin Cross0875c522017-11-28 17:34:01 -0800107}
108
Colin Cross4c83e5c2019-02-25 14:54:28 -0800109var _ testBuildProvider = (*singletonAdaptor)(nil)
110
111func (s *singletonAdaptor) GenerateBuildActions(ctx blueprint.SingletonContext) {
112 sctx := &singletonContextAdaptor{SingletonContext: ctx}
113 if sctx.Config().captureBuild {
114 sctx.ruleParams = make(map[blueprint.Rule]blueprint.RuleParams)
115 }
116
117 s.Singleton.GenerateBuildActions(sctx)
118
119 s.buildParams = sctx.buildParams
120 s.ruleParams = sctx.ruleParams
121}
122
123func (s *singletonAdaptor) BuildParamsForTests() []BuildParams {
124 return s.buildParams
125}
126
127func (s *singletonAdaptor) RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams {
128 return s.ruleParams
Colin Cross0875c522017-11-28 17:34:01 -0800129}
130
131type Singleton interface {
132 GenerateBuildActions(SingletonContext)
133}
134
135type singletonContextAdaptor struct {
136 blueprint.SingletonContext
Colin Cross4c83e5c2019-02-25 14:54:28 -0800137
138 buildParams []BuildParams
139 ruleParams map[blueprint.Rule]blueprint.RuleParams
Colin Cross0875c522017-11-28 17:34:01 -0800140}
141
Colin Cross3c0a83d2023-12-12 14:13:26 -0800142func (s *singletonContextAdaptor) blueprintSingletonContext() blueprint.SingletonContext {
143 return s.SingletonContext
144}
145
Colin Cross4c83e5c2019-02-25 14:54:28 -0800146func (s *singletonContextAdaptor) Config() Config {
Colin Crossaabf6792017-11-29 00:27:14 -0800147 return s.SingletonContext.Config().(Config)
148}
149
Colin Cross4c83e5c2019-02-25 14:54:28 -0800150func (s *singletonContextAdaptor) DeviceConfig() DeviceConfig {
Colin Cross65494b92019-02-07 14:25:51 -0800151 return DeviceConfig{s.Config().deviceConfig}
152}
153
Colin Cross4c83e5c2019-02-25 14:54:28 -0800154func (s *singletonContextAdaptor) Variable(pctx PackageContext, name, value string) {
Colin Cross0875c522017-11-28 17:34:01 -0800155 s.SingletonContext.Variable(pctx.PackageContext, name, value)
156}
157
Colin Cross4c83e5c2019-02-25 14:54:28 -0800158func (s *singletonContextAdaptor) Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule {
Ramy Medhat944839a2020-03-31 22:14:52 -0400159 if s.Config().UseRemoteBuild() {
160 if params.Pool == nil {
161 // When USE_GOMA=true or USE_RBE=true are set and the rule is not supported by goma/RBE, restrict
162 // jobs to the local parallelism value
163 params.Pool = localPool
164 } else if params.Pool == remotePool {
165 // remotePool is a fake pool used to identify rule that are supported for remoting. If the rule's
166 // pool is the remotePool, replace with nil so that ninja runs it at NINJA_REMOTE_NUM_JOBS
167 // parallelism.
168 params.Pool = nil
169 }
Colin Cross2e2dbc22019-09-25 13:31:46 -0700170 }
Colin Cross4c83e5c2019-02-25 14:54:28 -0800171 rule := s.SingletonContext.Rule(pctx.PackageContext, name, params, argNames...)
172 if s.Config().captureBuild {
173 s.ruleParams[rule] = params
174 }
175 return rule
Colin Cross0875c522017-11-28 17:34:01 -0800176}
177
Colin Cross4c83e5c2019-02-25 14:54:28 -0800178func (s *singletonContextAdaptor) Build(pctx PackageContext, params BuildParams) {
179 if s.Config().captureBuild {
180 s.buildParams = append(s.buildParams, params)
181 }
Colin Cross0875c522017-11-28 17:34:01 -0800182 bparams := convertBuildParams(params)
183 s.SingletonContext.Build(pctx.PackageContext, bparams)
Colin Cross0875c522017-11-28 17:34:01 -0800184}
185
Colin Crossc3d87d32020-06-04 13:25:17 -0700186func (s *singletonContextAdaptor) Phony(name string, deps ...Path) {
Yu Liu54513622024-08-19 20:00:32 +0000187 addSingletonPhony(s.Config(), name, deps...)
Colin Crossc3d87d32020-06-04 13:25:17 -0700188}
189
Lukacs T. Berki9f6c24a2021-08-26 15:07:24 +0200190func (s *singletonContextAdaptor) SetOutDir(pctx PackageContext, value string) {
191 s.SingletonContext.SetOutDir(pctx.PackageContext, value)
Colin Cross0875c522017-11-28 17:34:01 -0800192}
193
Colin Cross4c83e5c2019-02-25 14:54:28 -0800194func (s *singletonContextAdaptor) Eval(pctx PackageContext, ninjaStr string) (string, error) {
Colin Cross0875c522017-11-28 17:34:01 -0800195 return s.SingletonContext.Eval(pctx.PackageContext, ninjaStr)
196}
197
198// visitAdaptor wraps a visit function that takes an android.Module parameter into
Yu Liuec7043d2024-11-05 18:22:20 +0000199// a function that takes a blueprint.Module parameter and only calls the visit function if the
Colin Cross0875c522017-11-28 17:34:01 -0800200// blueprint.Module is an android.Module.
201func visitAdaptor(visit func(Module)) func(blueprint.Module) {
202 return func(module blueprint.Module) {
203 if aModule, ok := module.(Module); ok {
204 visit(aModule)
205 }
206 }
207}
208
Yu Liuec7043d2024-11-05 18:22:20 +0000209// visitProxyAdaptor wraps a visit function that takes an android.ModuleProxy parameter into
210// a function that takes a blueprint.ModuleProxy parameter.
211func visitProxyAdaptor(visit func(proxy ModuleProxy)) func(proxy blueprint.ModuleProxy) {
212 return func(module blueprint.ModuleProxy) {
213 visit(ModuleProxy{
214 module: module,
215 })
216 }
217}
218
Colin Cross0875c522017-11-28 17:34:01 -0800219// predAdaptor wraps a pred function that takes an android.Module parameter
220// into a function that takes an blueprint.Module parameter and only calls the visit function if the
221// blueprint.Module is an android.Module, otherwise returns false.
222func predAdaptor(pred func(Module) bool) func(blueprint.Module) bool {
223 return func(module blueprint.Module) bool {
224 if aModule, ok := module.(Module); ok {
225 return pred(aModule)
226 } else {
227 return false
228 }
229 }
230}
231
Colin Cross4c83e5c2019-02-25 14:54:28 -0800232func (s *singletonContextAdaptor) VisitAllModulesBlueprint(visit func(blueprint.Module)) {
Colin Cross2465c3d2018-09-28 10:19:18 -0700233 s.SingletonContext.VisitAllModules(visit)
234}
235
Colin Cross4c83e5c2019-02-25 14:54:28 -0800236func (s *singletonContextAdaptor) VisitAllModules(visit func(Module)) {
Colin Cross0875c522017-11-28 17:34:01 -0800237 s.SingletonContext.VisitAllModules(visitAdaptor(visit))
238}
239
Yu Liuec7043d2024-11-05 18:22:20 +0000240func (s *singletonContextAdaptor) VisitAllModuleProxies(visit func(proxy ModuleProxy)) {
241 s.SingletonContext.VisitAllModuleProxies(visitProxyAdaptor(visit))
242}
243
Colin Cross4c83e5c2019-02-25 14:54:28 -0800244func (s *singletonContextAdaptor) VisitAllModulesIf(pred func(Module) bool, visit func(Module)) {
Colin Cross0875c522017-11-28 17:34:01 -0800245 s.SingletonContext.VisitAllModulesIf(predAdaptor(pred), visitAdaptor(visit))
246}
247
Mitch Phillips3a7a31b2019-10-16 15:00:12 -0700248func (s *singletonContextAdaptor) VisitDirectDeps(module Module, visit func(Module)) {
249 s.SingletonContext.VisitDirectDeps(module, visitAdaptor(visit))
250}
251
252func (s *singletonContextAdaptor) VisitDirectDepsIf(module Module, pred func(Module) bool, visit func(Module)) {
253 s.SingletonContext.VisitDirectDepsIf(module, predAdaptor(pred), visitAdaptor(visit))
254}
255
Colin Cross4c83e5c2019-02-25 14:54:28 -0800256func (s *singletonContextAdaptor) VisitDepsDepthFirst(module Module, visit func(Module)) {
Colin Cross0875c522017-11-28 17:34:01 -0800257 s.SingletonContext.VisitDepsDepthFirst(module, visitAdaptor(visit))
258}
259
Colin Cross4c83e5c2019-02-25 14:54:28 -0800260func (s *singletonContextAdaptor) VisitDepsDepthFirstIf(module Module, pred func(Module) bool, visit func(Module)) {
Colin Cross0875c522017-11-28 17:34:01 -0800261 s.SingletonContext.VisitDepsDepthFirstIf(module, predAdaptor(pred), visitAdaptor(visit))
262}
263
Colin Cross4c83e5c2019-02-25 14:54:28 -0800264func (s *singletonContextAdaptor) VisitAllModuleVariants(module Module, visit func(Module)) {
Colin Cross0875c522017-11-28 17:34:01 -0800265 s.SingletonContext.VisitAllModuleVariants(module, visitAdaptor(visit))
266}
267
Yu Liuec7043d2024-11-05 18:22:20 +0000268func (s *singletonContextAdaptor) VisitAllModuleVariantProxies(module Module, visit func(proxy ModuleProxy)) {
269 s.SingletonContext.VisitAllModuleVariantProxies(module, visitProxyAdaptor(visit))
270}
271
Colin Cross4c83e5c2019-02-25 14:54:28 -0800272func (s *singletonContextAdaptor) PrimaryModule(module Module) Module {
Colin Cross0875c522017-11-28 17:34:01 -0800273 return s.SingletonContext.PrimaryModule(module).(Module)
274}
275
Colin Cross4c83e5c2019-02-25 14:54:28 -0800276func (s *singletonContextAdaptor) FinalModule(module Module) Module {
Colin Cross0875c522017-11-28 17:34:01 -0800277 return s.SingletonContext.FinalModule(module).(Module)
278}
Bob Badoureef4c1c2022-05-16 12:20:04 -0700279
280func (s *singletonContextAdaptor) ModuleVariantsFromName(referer Module, name string) []Module {
Cole Faust894bb3b2024-02-07 11:28:26 -0800281 // get module reference for visibility enforcement
Cole Faust9a24d902024-03-18 15:38:12 -0700282 qualified := createVisibilityModuleReference(s.ModuleName(referer), s.ModuleDir(referer), referer)
Bob Badoureef4c1c2022-05-16 12:20:04 -0700283
284 modules := s.SingletonContext.ModuleVariantsFromName(referer, name)
285 result := make([]Module, 0, len(modules))
286 for _, m := range modules {
287 if module, ok := m.(Module); ok {
288 // enforce visibility
289 depName := s.ModuleName(module)
290 depDir := s.ModuleDir(module)
291 depQualified := qualifiedModuleName{depDir, depName}
292 // Targets are always visible to other targets in their own package.
Cole Faust894bb3b2024-02-07 11:28:26 -0800293 if depQualified.pkg != qualified.name.pkg {
Bob Badoureef4c1c2022-05-16 12:20:04 -0700294 rule := effectiveVisibilityRules(s.Config(), depQualified)
295 if !rule.matches(qualified) {
Bob Badoura5ea2472022-05-20 16:37:26 -0700296 s.ModuleErrorf(referer, "module %q references %q which is not visible to this module\nYou may need to add %q to its visibility",
297 referer.Name(), depQualified, "//"+s.ModuleDir(referer))
Bob Badoureef4c1c2022-05-16 12:20:04 -0700298 continue
299 }
300 }
301 result = append(result, module)
302 }
303 }
304 return result
305}
Colin Cross3c0a83d2023-12-12 14:13:26 -0800306
Yu Liu663e4502024-08-12 18:23:59 +0000307func (s *singletonContextAdaptor) otherModuleProvider(module blueprint.Module, provider blueprint.AnyProviderKey) (any, bool) {
Colin Cross3c0a83d2023-12-12 14:13:26 -0800308 return s.SingletonContext.ModuleProvider(module, provider)
309}
Cole Faust02987bd2024-03-21 17:58:43 -0700310
311func (s *singletonContextAdaptor) OtherModulePropertyErrorf(module Module, property string, format string, args ...interface{}) {
Cole Fausta963b942024-04-11 17:43:00 -0700312 s.blueprintSingletonContext().OtherModulePropertyErrorf(module, property, format, args...)
Cole Faust02987bd2024-03-21 17:58:43 -0700313}
Cole Faust4e2bf9f2024-09-11 13:26:20 -0700314
315func (s *singletonContextAdaptor) HasMutatorFinished(mutatorName string) bool {
316 return s.blueprintSingletonContext().HasMutatorFinished(mutatorName)
317}