blob: cd0d152db680118bbee40c9748cdc00a5141fd35 [file] [log] [blame]
Colin Cross6362e272015-10-29 15:25:03 -07001// Copyright 2015 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
Colin Cross635c3b02016-05-18 15:37:25 -070015package android
Colin Cross6362e272015-10-29 15:25:03 -070016
Colin Cross795c3772017-03-16 16:50:10 -070017import (
Colin Cross795c3772017-03-16 16:50:10 -070018 "github.com/google/blueprint"
Colin Cross519917d2017-11-02 16:35:56 -070019 "github.com/google/blueprint/proptools"
Colin Cross795c3772017-03-16 16:50:10 -070020)
Colin Cross6362e272015-10-29 15:25:03 -070021
Jeff Gastonaf3cc2d2017-09-27 17:01:44 -070022// Phases:
23// run Pre-arch mutators
24// run archMutator
25// run Pre-deps mutators
26// run depsMutator
27// run PostDeps mutators
28// continue on to GenerateAndroidBuildActions
Colin Cross1e676be2016-10-12 14:38:15 -070029
Colin Cross795c3772017-03-16 16:50:10 -070030func registerMutatorsToContext(ctx *blueprint.Context, mutators []*mutator) {
31 for _, t := range mutators {
32 var handle blueprint.MutatorHandle
33 if t.bottomUpMutator != nil {
34 handle = ctx.RegisterBottomUpMutator(t.name, t.bottomUpMutator)
35 } else if t.topDownMutator != nil {
36 handle = ctx.RegisterTopDownMutator(t.name, t.topDownMutator)
37 }
38 if t.parallel {
39 handle.Parallel()
Colin Cross1e676be2016-10-12 14:38:15 -070040 }
41 }
Colin Cross1e676be2016-10-12 14:38:15 -070042}
43
Colin Crosscec81712017-07-13 14:43:27 -070044func registerMutators(ctx *blueprint.Context, preArch, preDeps, postDeps []RegisterMutatorFunc) {
45 mctx := &registerMutatorsContext{}
Nan Zhangdb0b9a32017-02-27 10:12:13 -080046
47 register := func(funcs []RegisterMutatorFunc) {
48 for _, f := range funcs {
Colin Crosscec81712017-07-13 14:43:27 -070049 f(mctx)
Nan Zhangdb0b9a32017-02-27 10:12:13 -080050 }
51 }
52
Colin Crosscec81712017-07-13 14:43:27 -070053 register(preArch)
Nan Zhangdb0b9a32017-02-27 10:12:13 -080054
Colin Crosscec81712017-07-13 14:43:27 -070055 register(preDeps)
56
57 mctx.BottomUp("deps", depsMutator).Parallel()
58
59 register(postDeps)
60
61 registerMutatorsToContext(ctx, mctx.mutators)
Colin Cross795c3772017-03-16 16:50:10 -070062}
63
64type registerMutatorsContext struct {
65 mutators []*mutator
66}
Colin Cross1e676be2016-10-12 14:38:15 -070067
68type RegisterMutatorsContext interface {
Colin Cross25de6c32019-06-06 14:29:25 -070069 TopDown(name string, m TopDownMutator) MutatorHandle
70 BottomUp(name string, m BottomUpMutator) MutatorHandle
Colin Cross1e676be2016-10-12 14:38:15 -070071}
72
73type RegisterMutatorFunc func(RegisterMutatorsContext)
74
Colin Crosscec81712017-07-13 14:43:27 -070075var preArch = []RegisterMutatorFunc{
Colin Crossf8b860a2019-04-16 14:43:28 -070076 registerLoadHookMutator,
Dan Willemsen6e72ef72018-01-26 18:27:02 -080077 RegisterNamespaceMutator,
Colin Cross5ea9bcc2017-07-27 15:41:32 -070078 RegisterPrebuiltsPreArchMutators,
Martin Stjernholm226b20d2019-05-17 22:42:02 +010079 registerVisibilityRuleChecker,
Colin Cross89536d42017-07-07 14:35:50 -070080 RegisterDefaultsPreArchMutators,
Paul Duffin2e61fa62019-03-28 14:10:57 +000081 registerVisibilityRuleGatherer,
Colin Crosscec81712017-07-13 14:43:27 -070082}
83
Colin Crossae4c6182017-09-15 17:33:55 -070084func registerArchMutator(ctx RegisterMutatorsContext) {
85 ctx.BottomUp("arch", archMutator).Parallel()
86 ctx.TopDown("arch_hooks", archHookMutator).Parallel()
87}
88
Colin Crosscec81712017-07-13 14:43:27 -070089var preDeps = []RegisterMutatorFunc{
Colin Crossae4c6182017-09-15 17:33:55 -070090 registerArchMutator,
Colin Crosscec81712017-07-13 14:43:27 -070091}
92
93var postDeps = []RegisterMutatorFunc{
Colin Cross1b488422019-03-04 22:33:56 -080094 registerPathDepsMutator,
Colin Cross5ea9bcc2017-07-27 15:41:32 -070095 RegisterPrebuiltsPostDepsMutators,
Paul Duffin2e61fa62019-03-28 14:10:57 +000096 registerVisibilityRuleEnforcer,
Steven Moreland65b3fd92017-12-06 14:18:35 -080097 registerNeverallowMutator,
Jaewoong Jungb639a6a2019-05-10 15:16:29 -070098 RegisterOverridePostDepsMutators,
Colin Crosscec81712017-07-13 14:43:27 -070099}
Colin Cross1e676be2016-10-12 14:38:15 -0700100
101func PreArchMutators(f RegisterMutatorFunc) {
102 preArch = append(preArch, f)
103}
104
105func PreDepsMutators(f RegisterMutatorFunc) {
106 preDeps = append(preDeps, f)
107}
108
109func PostDepsMutators(f RegisterMutatorFunc) {
110 postDeps = append(postDeps, f)
111}
112
Colin Cross25de6c32019-06-06 14:29:25 -0700113type TopDownMutator func(TopDownMutatorContext)
Colin Cross6362e272015-10-29 15:25:03 -0700114
Colin Cross635c3b02016-05-18 15:37:25 -0700115type TopDownMutatorContext interface {
Colin Crossaabf6792017-11-29 00:27:14 -0800116 BaseModuleContext
Colin Cross3f68a132017-10-23 17:10:29 -0700117
Colin Cross380c69a2019-06-10 17:49:58 +0000118 OtherModuleExists(name string) bool
Colin Cross3f68a132017-10-23 17:10:29 -0700119 Rename(name string)
Colin Cross380c69a2019-06-10 17:49:58 +0000120 Module() Module
121
122 OtherModuleName(m blueprint.Module) string
123 OtherModuleDir(m blueprint.Module) string
124 OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{})
125 OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag
Colin Cross3f68a132017-10-23 17:10:29 -0700126
127 CreateModule(blueprint.ModuleFactory, ...interface{})
Colin Cross380c69a2019-06-10 17:49:58 +0000128
129 GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module
130 GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
131
132 VisitDirectDeps(visit func(Module))
133 VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module))
134 VisitDirectDepsIf(pred func(Module) bool, visit func(Module))
135 VisitDepsDepthFirst(visit func(Module))
136 VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
137 WalkDeps(visit func(Module, Module) bool)
138 // GetWalkPath is supposed to be called in visit function passed in WalkDeps()
139 // and returns a top-down dependency path from a start module to current child module.
140 GetWalkPath() []Module
Colin Cross6362e272015-10-29 15:25:03 -0700141}
142
Colin Cross25de6c32019-06-06 14:29:25 -0700143type topDownMutatorContext struct {
Colin Cross380c69a2019-06-10 17:49:58 +0000144 blueprint.TopDownMutatorContext
Colin Cross0ea8ba82019-06-06 14:33:29 -0700145 baseModuleContext
Colin Cross380c69a2019-06-10 17:49:58 +0000146 walkPath []Module
Colin Cross6362e272015-10-29 15:25:03 -0700147}
148
Colin Cross25de6c32019-06-06 14:29:25 -0700149type BottomUpMutator func(BottomUpMutatorContext)
Colin Cross6362e272015-10-29 15:25:03 -0700150
Colin Cross635c3b02016-05-18 15:37:25 -0700151type BottomUpMutatorContext interface {
Colin Crossaabf6792017-11-29 00:27:14 -0800152 BaseModuleContext
Colin Crossaabf6792017-11-29 00:27:14 -0800153
Colin Cross380c69a2019-06-10 17:49:58 +0000154 OtherModuleExists(name string) bool
Colin Crossaabf6792017-11-29 00:27:14 -0800155 Rename(name string)
Colin Cross380c69a2019-06-10 17:49:58 +0000156 Module() blueprint.Module
Colin Crossaabf6792017-11-29 00:27:14 -0800157
158 AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string)
159 AddReverseDependency(module blueprint.Module, tag blueprint.DependencyTag, name string)
160 CreateVariations(...string) []blueprint.Module
161 CreateLocalVariations(...string) []blueprint.Module
162 SetDependencyVariation(string)
163 AddVariationDependencies([]blueprint.Variation, blueprint.DependencyTag, ...string)
164 AddFarVariationDependencies([]blueprint.Variation, blueprint.DependencyTag, ...string)
165 AddInterVariantDependency(tag blueprint.DependencyTag, from, to blueprint.Module)
166 ReplaceDependencies(string)
Colin Cross6362e272015-10-29 15:25:03 -0700167}
168
Colin Cross25de6c32019-06-06 14:29:25 -0700169type bottomUpMutatorContext struct {
Colin Cross380c69a2019-06-10 17:49:58 +0000170 blueprint.BottomUpMutatorContext
Colin Cross0ea8ba82019-06-06 14:33:29 -0700171 baseModuleContext
Colin Cross6362e272015-10-29 15:25:03 -0700172}
173
Colin Cross25de6c32019-06-06 14:29:25 -0700174func (x *registerMutatorsContext) BottomUp(name string, m BottomUpMutator) MutatorHandle {
Colin Cross798bfce2016-10-12 14:28:16 -0700175 f := func(ctx blueprint.BottomUpMutatorContext) {
Colin Cross635c3b02016-05-18 15:37:25 -0700176 if a, ok := ctx.Module().(Module); ok {
Colin Cross25de6c32019-06-06 14:29:25 -0700177 actx := &bottomUpMutatorContext{
Colin Cross380c69a2019-06-10 17:49:58 +0000178 BottomUpMutatorContext: ctx,
179 baseModuleContext: a.base().baseModuleContextFactory(ctx),
Colin Cross6362e272015-10-29 15:25:03 -0700180 }
Colin Cross798bfce2016-10-12 14:28:16 -0700181 m(actx)
Colin Cross6362e272015-10-29 15:25:03 -0700182 }
Colin Cross798bfce2016-10-12 14:28:16 -0700183 }
184 mutator := &mutator{name: name, bottomUpMutator: f}
Colin Cross795c3772017-03-16 16:50:10 -0700185 x.mutators = append(x.mutators, mutator)
Colin Cross798bfce2016-10-12 14:28:16 -0700186 return mutator
Colin Cross6362e272015-10-29 15:25:03 -0700187}
188
Colin Cross25de6c32019-06-06 14:29:25 -0700189func (x *registerMutatorsContext) TopDown(name string, m TopDownMutator) MutatorHandle {
Colin Cross798bfce2016-10-12 14:28:16 -0700190 f := func(ctx blueprint.TopDownMutatorContext) {
Colin Cross635c3b02016-05-18 15:37:25 -0700191 if a, ok := ctx.Module().(Module); ok {
Colin Cross25de6c32019-06-06 14:29:25 -0700192 actx := &topDownMutatorContext{
Colin Cross380c69a2019-06-10 17:49:58 +0000193 TopDownMutatorContext: ctx,
194 baseModuleContext: a.base().baseModuleContextFactory(ctx),
Colin Cross6362e272015-10-29 15:25:03 -0700195 }
Colin Cross798bfce2016-10-12 14:28:16 -0700196 m(actx)
Colin Cross6362e272015-10-29 15:25:03 -0700197 }
Colin Cross798bfce2016-10-12 14:28:16 -0700198 }
199 mutator := &mutator{name: name, topDownMutator: f}
Colin Cross795c3772017-03-16 16:50:10 -0700200 x.mutators = append(x.mutators, mutator)
Colin Cross798bfce2016-10-12 14:28:16 -0700201 return mutator
202}
203
204type MutatorHandle interface {
205 Parallel() MutatorHandle
206}
207
208func (mutator *mutator) Parallel() MutatorHandle {
209 mutator.parallel = true
210 return mutator
Colin Cross6362e272015-10-29 15:25:03 -0700211}
Colin Cross1e676be2016-10-12 14:38:15 -0700212
213func depsMutator(ctx BottomUpMutatorContext) {
Colin Cross6db4a6a2018-08-30 12:52:41 -0700214 if m, ok := ctx.Module().(Module); ok && m.Enabled() {
Colin Cross1e676be2016-10-12 14:38:15 -0700215 m.DepsMutator(ctx)
216 }
217}
Colin Crossd11fcda2017-10-23 17:59:01 -0700218
Colin Cross380c69a2019-06-10 17:49:58 +0000219func (t *topDownMutatorContext) Config() Config {
220 return t.config
221}
222
223func (b *bottomUpMutatorContext) Config() Config {
224 return b.config
225}
226
227func (t *topDownMutatorContext) Module() Module {
228 module, _ := t.TopDownMutatorContext.Module().(Module)
229 return module
230}
231
232func (t *topDownMutatorContext) VisitDirectDeps(visit func(Module)) {
233 t.TopDownMutatorContext.VisitDirectDeps(func(module blueprint.Module) {
234 if aModule, _ := module.(Module); aModule != nil {
235 visit(aModule)
236 }
237 })
238}
239
240func (t *topDownMutatorContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) {
241 t.TopDownMutatorContext.VisitDirectDeps(func(module blueprint.Module) {
242 if aModule, _ := module.(Module); aModule != nil {
243 if t.TopDownMutatorContext.OtherModuleDependencyTag(aModule) == tag {
244 visit(aModule)
245 }
246 }
247 })
248}
249
250func (t *topDownMutatorContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) {
251 t.TopDownMutatorContext.VisitDirectDepsIf(
252 // pred
253 func(module blueprint.Module) bool {
254 if aModule, _ := module.(Module); aModule != nil {
255 return pred(aModule)
256 } else {
257 return false
258 }
259 },
260 // visit
261 func(module blueprint.Module) {
262 visit(module.(Module))
263 })
264}
265
266func (t *topDownMutatorContext) VisitDepsDepthFirst(visit func(Module)) {
267 t.TopDownMutatorContext.VisitDepsDepthFirst(func(module blueprint.Module) {
268 if aModule, _ := module.(Module); aModule != nil {
269 visit(aModule)
270 }
271 })
272}
273
274func (t *topDownMutatorContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) {
275 t.TopDownMutatorContext.VisitDepsDepthFirstIf(
276 // pred
277 func(module blueprint.Module) bool {
278 if aModule, _ := module.(Module); aModule != nil {
279 return pred(aModule)
280 } else {
281 return false
282 }
283 },
284 // visit
285 func(module blueprint.Module) {
286 visit(module.(Module))
287 })
288}
289
290func (t *topDownMutatorContext) WalkDeps(visit func(Module, Module) bool) {
291 t.walkPath = []Module{t.Module()}
292 t.TopDownMutatorContext.WalkDeps(func(child, parent blueprint.Module) bool {
293 childAndroidModule, _ := child.(Module)
294 parentAndroidModule, _ := parent.(Module)
295 if childAndroidModule != nil && parentAndroidModule != nil {
296 // record walkPath before visit
297 for t.walkPath[len(t.walkPath)-1] != parentAndroidModule {
298 t.walkPath = t.walkPath[0 : len(t.walkPath)-1]
299 }
300 t.walkPath = append(t.walkPath, childAndroidModule)
301 return visit(childAndroidModule, parentAndroidModule)
302 } else {
303 return false
304 }
305 })
306}
307
308func (t *topDownMutatorContext) GetWalkPath() []Module {
309 return t.walkPath
310}
311
Colin Cross25de6c32019-06-06 14:29:25 -0700312func (t *topDownMutatorContext) AppendProperties(props ...interface{}) {
Colin Cross519917d2017-11-02 16:35:56 -0700313 for _, p := range props {
Colin Cross25de6c32019-06-06 14:29:25 -0700314 err := proptools.AppendMatchingProperties(t.Module().base().customizableProperties,
Colin Cross519917d2017-11-02 16:35:56 -0700315 p, nil)
316 if err != nil {
317 if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok {
Colin Cross25de6c32019-06-06 14:29:25 -0700318 t.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error())
Colin Cross519917d2017-11-02 16:35:56 -0700319 } else {
320 panic(err)
321 }
322 }
323 }
324}
325
Colin Cross25de6c32019-06-06 14:29:25 -0700326func (t *topDownMutatorContext) PrependProperties(props ...interface{}) {
Colin Cross519917d2017-11-02 16:35:56 -0700327 for _, p := range props {
Colin Cross25de6c32019-06-06 14:29:25 -0700328 err := proptools.PrependMatchingProperties(t.Module().base().customizableProperties,
Colin Cross519917d2017-11-02 16:35:56 -0700329 p, nil)
330 if err != nil {
331 if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok {
Colin Cross25de6c32019-06-06 14:29:25 -0700332 t.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error())
Colin Cross519917d2017-11-02 16:35:56 -0700333 } else {
334 panic(err)
335 }
336 }
337 }
338}