• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// 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
15package android
16
17import (
18	"reflect"
19
20	"github.com/google/blueprint"
21	"github.com/google/blueprint/proptools"
22)
23
24// Phases:
25//   run Pre-arch mutators
26//   run archMutator
27//   run Pre-deps mutators
28//   run depsMutator
29//   run PostDeps mutators
30//   run FinalDeps mutators (CreateVariations disallowed in this phase)
31//   continue on to GenerateAndroidBuildActions
32
33func registerMutatorsToContext(ctx *blueprint.Context, mutators []*mutator) {
34	for _, t := range mutators {
35		var handle blueprint.MutatorHandle
36		if t.bottomUpMutator != nil {
37			handle = ctx.RegisterBottomUpMutator(t.name, t.bottomUpMutator)
38		} else if t.topDownMutator != nil {
39			handle = ctx.RegisterTopDownMutator(t.name, t.topDownMutator)
40		}
41		if t.parallel {
42			handle.Parallel()
43		}
44	}
45}
46
47func registerMutators(ctx *blueprint.Context, preArch, preDeps, postDeps, finalDeps []RegisterMutatorFunc) {
48	mctx := &registerMutatorsContext{}
49
50	register := func(funcs []RegisterMutatorFunc) {
51		for _, f := range funcs {
52			f(mctx)
53		}
54	}
55
56	register(preArch)
57
58	register(preDeps)
59
60	mctx.BottomUp("deps", depsMutator).Parallel()
61
62	register(postDeps)
63
64	mctx.finalPhase = true
65	register(finalDeps)
66
67	registerMutatorsToContext(ctx, mctx.mutators)
68}
69
70type registerMutatorsContext struct {
71	mutators   []*mutator
72	finalPhase bool
73}
74
75type RegisterMutatorsContext interface {
76	TopDown(name string, m TopDownMutator) MutatorHandle
77	BottomUp(name string, m BottomUpMutator) MutatorHandle
78}
79
80type RegisterMutatorFunc func(RegisterMutatorsContext)
81
82var preArch = []RegisterMutatorFunc{
83	RegisterNamespaceMutator,
84
85	// Check the visibility rules are valid.
86	//
87	// This must run after the package renamer mutators so that any issues found during
88	// validation of the package's default_visibility property are reported using the
89	// correct package name and not the synthetic name.
90	//
91	// This must also be run before defaults mutators as the rules for validation are
92	// different before checking the rules than they are afterwards. e.g.
93	//    visibility: ["//visibility:private", "//visibility:public"]
94	// would be invalid if specified in a module definition but is valid if it results
95	// from something like this:
96	//
97	//    defaults {
98	//        name: "defaults",
99	//        // Be inaccessible outside a package by default.
100	//        visibility: ["//visibility:private"]
101	//    }
102	//
103	//    defaultable_module {
104	//        name: "defaultable_module",
105	//        defaults: ["defaults"],
106	//        // Override the default.
107	//        visibility: ["//visibility:public"]
108	//    }
109	//
110	RegisterVisibilityRuleChecker,
111
112	// Apply properties from defaults modules to the referencing modules.
113	//
114	// Any mutators that are added before this will not see any modules created by
115	// a DefaultableHook.
116	RegisterDefaultsPreArchMutators,
117
118	// Create an association between prebuilt modules and their corresponding source
119	// modules (if any).
120	//
121	// Must be run after defaults mutators to ensure that any modules created by
122	// a DefaultableHook can be either a prebuilt or a source module with a matching
123	// prebuilt.
124	RegisterPrebuiltsPreArchMutators,
125
126	// Gather the visibility rules for all modules for us during visibility enforcement.
127	//
128	// This must come after the defaults mutators to ensure that any visibility supplied
129	// in a defaults module has been successfully applied before the rules are gathered.
130	RegisterVisibilityRuleGatherer,
131}
132
133func registerArchMutator(ctx RegisterMutatorsContext) {
134	ctx.BottomUp("os", osMutator).Parallel()
135	ctx.BottomUp("image", imageMutator).Parallel()
136	ctx.BottomUp("arch", archMutator).Parallel()
137}
138
139var preDeps = []RegisterMutatorFunc{
140	registerArchMutator,
141}
142
143var postDeps = []RegisterMutatorFunc{
144	registerPathDepsMutator,
145	RegisterPrebuiltsPostDepsMutators,
146	RegisterVisibilityRuleEnforcer,
147	RegisterNeverallowMutator,
148	RegisterOverridePostDepsMutators,
149}
150
151var finalDeps = []RegisterMutatorFunc{}
152
153func PreArchMutators(f RegisterMutatorFunc) {
154	preArch = append(preArch, f)
155}
156
157func PreDepsMutators(f RegisterMutatorFunc) {
158	preDeps = append(preDeps, f)
159}
160
161func PostDepsMutators(f RegisterMutatorFunc) {
162	postDeps = append(postDeps, f)
163}
164
165func FinalDepsMutators(f RegisterMutatorFunc) {
166	finalDeps = append(finalDeps, f)
167}
168
169type TopDownMutator func(TopDownMutatorContext)
170
171type TopDownMutatorContext interface {
172	BaseModuleContext
173
174	MutatorName() string
175
176	Rename(name string)
177
178	CreateModule(ModuleFactory, ...interface{}) Module
179}
180
181type topDownMutatorContext struct {
182	bp blueprint.TopDownMutatorContext
183	baseModuleContext
184}
185
186type BottomUpMutator func(BottomUpMutatorContext)
187
188type BottomUpMutatorContext interface {
189	BaseModuleContext
190
191	MutatorName() string
192
193	Rename(name string)
194
195	AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string)
196	AddReverseDependency(module blueprint.Module, tag blueprint.DependencyTag, name string)
197	CreateVariations(...string) []Module
198	CreateLocalVariations(...string) []Module
199	SetDependencyVariation(string)
200	SetDefaultDependencyVariation(*string)
201	AddVariationDependencies([]blueprint.Variation, blueprint.DependencyTag, ...string)
202	AddFarVariationDependencies([]blueprint.Variation, blueprint.DependencyTag, ...string)
203	AddInterVariantDependency(tag blueprint.DependencyTag, from, to blueprint.Module)
204	ReplaceDependencies(string)
205	AliasVariation(variationName string)
206}
207
208type bottomUpMutatorContext struct {
209	bp blueprint.BottomUpMutatorContext
210	baseModuleContext
211	finalPhase bool
212}
213
214func (x *registerMutatorsContext) BottomUp(name string, m BottomUpMutator) MutatorHandle {
215	finalPhase := x.finalPhase
216	f := func(ctx blueprint.BottomUpMutatorContext) {
217		if a, ok := ctx.Module().(Module); ok {
218			actx := &bottomUpMutatorContext{
219				bp:                ctx,
220				baseModuleContext: a.base().baseModuleContextFactory(ctx),
221				finalPhase:        finalPhase,
222			}
223			m(actx)
224		}
225	}
226	mutator := &mutator{name: name, bottomUpMutator: f}
227	x.mutators = append(x.mutators, mutator)
228	return mutator
229}
230
231func (x *registerMutatorsContext) TopDown(name string, m TopDownMutator) MutatorHandle {
232	f := func(ctx blueprint.TopDownMutatorContext) {
233		if a, ok := ctx.Module().(Module); ok {
234			actx := &topDownMutatorContext{
235				bp:                ctx,
236				baseModuleContext: a.base().baseModuleContextFactory(ctx),
237			}
238			m(actx)
239		}
240	}
241	mutator := &mutator{name: name, topDownMutator: f}
242	x.mutators = append(x.mutators, mutator)
243	return mutator
244}
245
246type MutatorHandle interface {
247	Parallel() MutatorHandle
248}
249
250func (mutator *mutator) Parallel() MutatorHandle {
251	mutator.parallel = true
252	return mutator
253}
254
255func depsMutator(ctx BottomUpMutatorContext) {
256	if m, ok := ctx.Module().(Module); ok && m.Enabled() {
257		m.DepsMutator(ctx)
258	}
259}
260
261func (t *topDownMutatorContext) AppendProperties(props ...interface{}) {
262	for _, p := range props {
263		err := proptools.AppendMatchingProperties(t.Module().base().customizableProperties,
264			p, nil)
265		if err != nil {
266			if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok {
267				t.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error())
268			} else {
269				panic(err)
270			}
271		}
272	}
273}
274
275func (t *topDownMutatorContext) PrependProperties(props ...interface{}) {
276	for _, p := range props {
277		err := proptools.PrependMatchingProperties(t.Module().base().customizableProperties,
278			p, nil)
279		if err != nil {
280			if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok {
281				t.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error())
282			} else {
283				panic(err)
284			}
285		}
286	}
287}
288
289// android.topDownMutatorContext either has to embed blueprint.TopDownMutatorContext, in which case every method that
290// has an overridden version in android.BaseModuleContext has to be manually forwarded to BaseModuleContext to avoid
291// ambiguous method errors, or it has to store a blueprint.TopDownMutatorContext non-embedded, in which case every
292// non-overridden method has to be forwarded.  There are fewer non-overridden methods, so use the latter.  The following
293// methods forward to the identical blueprint versions for topDownMutatorContext and bottomUpMutatorContext.
294
295func (t *topDownMutatorContext) MutatorName() string {
296	return t.bp.MutatorName()
297}
298
299func (t *topDownMutatorContext) Rename(name string) {
300	t.bp.Rename(name)
301	t.Module().base().commonProperties.DebugName = name
302}
303
304func (t *topDownMutatorContext) CreateModule(factory ModuleFactory, props ...interface{}) Module {
305	inherited := []interface{}{&t.Module().base().commonProperties}
306	module := t.bp.CreateModule(ModuleFactoryAdaptor(factory), append(inherited, props...)...).(Module)
307
308	if t.Module().base().variableProperties != nil && module.base().variableProperties != nil {
309		src := t.Module().base().variableProperties
310		dst := []interface{}{
311			module.base().variableProperties,
312			// Put an empty copy of the src properties into dst so that properties in src that are not in dst
313			// don't cause a "failed to find property to extend" error.
314			proptools.CloneEmptyProperties(reflect.ValueOf(src)).Interface(),
315		}
316		err := proptools.AppendMatchingProperties(dst, src, nil)
317		if err != nil {
318			panic(err)
319		}
320	}
321
322	return module
323}
324
325func (b *bottomUpMutatorContext) MutatorName() string {
326	return b.bp.MutatorName()
327}
328
329func (b *bottomUpMutatorContext) Rename(name string) {
330	b.bp.Rename(name)
331	b.Module().base().commonProperties.DebugName = name
332}
333
334func (b *bottomUpMutatorContext) AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) {
335	b.bp.AddDependency(module, tag, name...)
336}
337
338func (b *bottomUpMutatorContext) AddReverseDependency(module blueprint.Module, tag blueprint.DependencyTag, name string) {
339	b.bp.AddReverseDependency(module, tag, name)
340}
341
342func (b *bottomUpMutatorContext) CreateVariations(variations ...string) []Module {
343	if b.finalPhase {
344		panic("CreateVariations not allowed in FinalDepsMutators")
345	}
346
347	modules := b.bp.CreateVariations(variations...)
348
349	aModules := make([]Module, len(modules))
350	for i := range variations {
351		aModules[i] = modules[i].(Module)
352		base := aModules[i].base()
353		base.commonProperties.DebugMutators = append(base.commonProperties.DebugMutators, b.MutatorName())
354		base.commonProperties.DebugVariations = append(base.commonProperties.DebugVariations, variations[i])
355	}
356
357	return aModules
358}
359
360func (b *bottomUpMutatorContext) CreateLocalVariations(variations ...string) []Module {
361	if b.finalPhase {
362		panic("CreateLocalVariations not allowed in FinalDepsMutators")
363	}
364
365	modules := b.bp.CreateLocalVariations(variations...)
366
367	aModules := make([]Module, len(modules))
368	for i := range variations {
369		aModules[i] = modules[i].(Module)
370		base := aModules[i].base()
371		base.commonProperties.DebugMutators = append(base.commonProperties.DebugMutators, b.MutatorName())
372		base.commonProperties.DebugVariations = append(base.commonProperties.DebugVariations, variations[i])
373	}
374
375	return aModules
376}
377
378func (b *bottomUpMutatorContext) SetDependencyVariation(variation string) {
379	b.bp.SetDependencyVariation(variation)
380}
381
382func (b *bottomUpMutatorContext) SetDefaultDependencyVariation(variation *string) {
383	b.bp.SetDefaultDependencyVariation(variation)
384}
385
386func (b *bottomUpMutatorContext) AddVariationDependencies(variations []blueprint.Variation, tag blueprint.DependencyTag,
387	names ...string) {
388
389	b.bp.AddVariationDependencies(variations, tag, names...)
390}
391
392func (b *bottomUpMutatorContext) AddFarVariationDependencies(variations []blueprint.Variation,
393	tag blueprint.DependencyTag, names ...string) {
394
395	b.bp.AddFarVariationDependencies(variations, tag, names...)
396}
397
398func (b *bottomUpMutatorContext) AddInterVariantDependency(tag blueprint.DependencyTag, from, to blueprint.Module) {
399	b.bp.AddInterVariantDependency(tag, from, to)
400}
401
402func (b *bottomUpMutatorContext) ReplaceDependencies(name string) {
403	b.bp.ReplaceDependencies(name)
404}
405
406func (b *bottomUpMutatorContext) AliasVariation(variationName string) {
407	b.bp.AliasVariation(variationName)
408}
409