• 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	"fmt"
19	"reflect"
20
21	"github.com/google/blueprint"
22)
23
24// A sortable component is one whose registration order affects the order in which it is executed
25// and so affects the behavior of the build system. As a result it is important for the order in
26// which they are registered during tests to match the order used at runtime and so the test
27// infrastructure will sort them to match.
28//
29// The sortable components are mutators, singletons and pre-singletons. Module types are not
30// sortable because their order of registration does not affect the runtime behavior.
31type sortableComponent interface {
32	// componentName returns the name of the component.
33	//
34	// Uniquely identifies the components within the set of components used at runtime and during
35	// tests.
36	componentName() string
37
38	// registers this component in the supplied context.
39	register(ctx *Context)
40}
41
42type sortableComponents []sortableComponent
43
44// registerAll registers all components in this slice with the supplied context.
45func (r sortableComponents) registerAll(ctx *Context) {
46	for _, c := range r {
47		c.register(ctx)
48	}
49}
50
51type moduleType struct {
52	name    string
53	factory ModuleFactory
54}
55
56func (t moduleType) register(ctx *Context) {
57	ctx.RegisterModuleType(t.name, ModuleFactoryAdaptor(t.factory))
58}
59
60var moduleTypes []moduleType
61var moduleTypesForDocs = map[string]reflect.Value{}
62var moduleTypeByFactory = map[reflect.Value]string{}
63
64type singleton struct {
65	// True if this should be registered as a parallel singleton.
66	parallel bool
67
68	name    string
69	factory SingletonFactory
70}
71
72func newSingleton(name string, factory SingletonFactory, parallel bool) singleton {
73	return singleton{parallel: parallel, name: name, factory: factory}
74}
75
76func (s singleton) componentName() string {
77	return s.name
78}
79
80func (s singleton) register(ctx *Context) {
81	adaptor := SingletonFactoryAdaptor(ctx, s.factory)
82	ctx.RegisterSingletonType(s.name, adaptor, s.parallel)
83}
84
85var _ sortableComponent = singleton{}
86
87var singletons sortableComponents
88
89type mutator struct {
90	name              string
91	bottomUpMutator   blueprint.BottomUpMutator
92	transitionMutator blueprint.TransitionMutator
93
94	usesRename              bool
95	usesReverseDependencies bool
96	usesReplaceDependencies bool
97	usesCreateModule        bool
98	mutatesDependencies     bool
99	mutatesGlobalState      bool
100	neverFar                bool
101}
102
103var _ sortableComponent = &mutator{}
104
105type ModuleFactory func() Module
106
107// ModuleFactoryAdaptor wraps a ModuleFactory into a blueprint.ModuleFactory by converting a Module
108// into a blueprint.Module and a list of property structs
109func ModuleFactoryAdaptor(factory ModuleFactory) blueprint.ModuleFactory {
110	return func() (blueprint.Module, []interface{}) {
111		module := factory()
112		return module, module.GetProperties()
113	}
114}
115
116type SingletonFactory func() Singleton
117
118// SingletonFactoryAdaptor wraps a SingletonFactory into a blueprint.SingletonFactory by converting
119// a Singleton into a blueprint.Singleton
120func SingletonFactoryAdaptor(ctx *Context, factory SingletonFactory) blueprint.SingletonFactory {
121	return func() blueprint.Singleton {
122		singleton := factory()
123		if makevars, ok := singleton.(SingletonMakeVarsProvider); ok {
124			ctx.registerSingletonMakeVarsProvider(makevars)
125		}
126		return &singletonAdaptor{Singleton: singleton}
127	}
128}
129
130func RegisterModuleType(name string, factory ModuleFactory) {
131	moduleTypes = append(moduleTypes, moduleType{name, factory})
132	RegisterModuleTypeForDocs(name, reflect.ValueOf(factory))
133}
134
135// RegisterModuleTypeForDocs associates a module type name with a reflect.Value of the factory
136// function that has documentation for the module type.  It is normally called automatically
137// by RegisterModuleType, but can be called manually after RegisterModuleType in order to
138// override the factory method used for documentation, for example if the method passed to
139// RegisterModuleType was a lambda.
140func RegisterModuleTypeForDocs(name string, factory reflect.Value) {
141	moduleTypesForDocs[name] = factory
142	moduleTypeByFactory[factory] = name
143}
144
145func registerSingletonType(name string, factory SingletonFactory, parallel bool) {
146	singletons = append(singletons, newSingleton(name, factory, parallel))
147}
148
149func RegisterSingletonType(name string, factory SingletonFactory) {
150	registerSingletonType(name, factory, false)
151}
152
153func RegisterParallelSingletonType(name string, factory SingletonFactory) {
154	registerSingletonType(name, factory, true)
155}
156
157type Context struct {
158	*blueprint.Context
159	config Config
160}
161
162func NewContext(config Config) *Context {
163	ctx := &Context{blueprint.NewContext(), config}
164	ctx.SetSrcDir(absSrcDir)
165	ctx.AddSourceRootDirs(config.SourceRootDirs()...)
166	return ctx
167}
168
169// Register the pipeline of singletons, module types, and mutators for
170// generating build.ninja and other files for Kati, from Android.bp files.
171func (ctx *Context) Register() {
172	for _, t := range moduleTypes {
173		t.register(ctx)
174	}
175
176	mutators := collateGloballyRegisteredMutators()
177	mutators.registerAll(ctx)
178
179	singletons := collateGloballyRegisteredSingletons()
180	singletons.registerAll(ctx)
181}
182
183func (ctx *Context) Config() Config {
184	return ctx.config
185}
186
187func (ctx *Context) registerSingletonMakeVarsProvider(makevars SingletonMakeVarsProvider) {
188	registerSingletonMakeVarsProvider(ctx.config, makevars)
189}
190
191func collateGloballyRegisteredSingletons() sortableComponents {
192	allSingletons := append(sortableComponents(nil), singletons...)
193	allSingletons = append(allSingletons,
194		// Soong only androidmk is registered later than other singletons in order to collect
195		// dist contributions from other singletons. This singleton is registered just before
196		// phony so that its phony rules can be collected by the phony singleton.
197		singleton{parallel: false, name: "soongonlyandroidmk", factory: soongOnlyAndroidMkSingletonFactory},
198
199		// Register phony just before makevars so it can write out its phony rules as Make rules
200		singleton{parallel: false, name: "phony", factory: phonySingletonFactory},
201
202		// Register makevars after other singletons so they can export values through makevars
203		singleton{parallel: false, name: "makevars", factory: makeVarsSingletonFunc},
204
205		// Register rawfiles and ninjadeps last so that they can track all used environment variables and
206		// Ninja file dependencies stored in the config.
207		singleton{parallel: false, name: "rawfiles", factory: rawFilesSingletonFactory},
208		singleton{parallel: false, name: "ninjadeps", factory: ninjaDepsSingletonFactory},
209	)
210
211	return allSingletons
212}
213
214func ModuleTypeFactories() map[string]ModuleFactory {
215	ret := make(map[string]ModuleFactory)
216	for _, t := range moduleTypes {
217		ret[t.name] = t.factory
218	}
219	return ret
220}
221
222func ModuleTypeFactoriesForDocs() map[string]reflect.Value {
223	return moduleTypesForDocs
224}
225
226func ModuleTypeByFactory() map[reflect.Value]string {
227	return moduleTypeByFactory
228}
229
230// Interface for registering build components.
231//
232// Provided to allow registration of build components to be shared between the runtime
233// and test environments.
234type RegistrationContext interface {
235	RegisterModuleType(name string, factory ModuleFactory)
236	RegisterSingletonModuleType(name string, factory SingletonModuleFactory)
237	RegisterParallelSingletonModuleType(name string, factory SingletonModuleFactory)
238	RegisterParallelSingletonType(name string, factory SingletonFactory)
239	RegisterSingletonType(name string, factory SingletonFactory)
240	PreArchMutators(f RegisterMutatorFunc)
241
242	// Register pre arch mutators that are hard coded into mutator.go.
243	//
244	// Only registers mutators for testing, is a noop on the InitRegistrationContext.
245	HardCodedPreArchMutators(f RegisterMutatorFunc)
246
247	PreDepsMutators(f RegisterMutatorFunc)
248	PostDepsMutators(f RegisterMutatorFunc)
249	PostApexMutators(f RegisterMutatorFunc)
250	FinalDepsMutators(f RegisterMutatorFunc)
251}
252
253// Used to register build components from an init() method, e.g.
254//
255//	init() {
256//	  RegisterBuildComponents(android.InitRegistrationContext)
257//	}
258//
259//	func RegisterBuildComponents(ctx android.RegistrationContext) {
260//	  ctx.RegisterModuleType(...)
261//	  ...
262//	}
263//
264// Extracting the actual registration into a separate RegisterBuildComponents(ctx) function
265// allows it to be used to initialize test context, e.g.
266//
267//	ctx := android.NewTestContext(config)
268//	RegisterBuildComponents(ctx)
269var InitRegistrationContext RegistrationContext = &initRegistrationContext{
270	moduleTypes:    make(map[string]ModuleFactory),
271	singletonTypes: make(map[string]SingletonFactory),
272}
273
274// Make sure the TestContext implements RegistrationContext.
275var _ RegistrationContext = (*TestContext)(nil)
276
277type initRegistrationContext struct {
278	moduleTypes        map[string]ModuleFactory
279	singletonTypes     map[string]SingletonFactory
280	moduleTypesForDocs map[string]reflect.Value
281}
282
283func (ctx *initRegistrationContext) RegisterModuleType(name string, factory ModuleFactory) {
284	if _, present := ctx.moduleTypes[name]; present {
285		panic(fmt.Sprintf("module type %q is already registered", name))
286	}
287	ctx.moduleTypes[name] = factory
288	RegisterModuleType(name, factory)
289	RegisterModuleTypeForDocs(name, reflect.ValueOf(factory))
290}
291
292func (ctx *initRegistrationContext) RegisterSingletonModuleType(name string, factory SingletonModuleFactory) {
293	ctx.registerSingletonModuleType(name, factory, false)
294}
295func (ctx *initRegistrationContext) RegisterParallelSingletonModuleType(name string, factory SingletonModuleFactory) {
296	ctx.registerSingletonModuleType(name, factory, true)
297}
298
299func (ctx *initRegistrationContext) registerSingletonModuleType(name string, factory SingletonModuleFactory, parallel bool) {
300	s, m := SingletonModuleFactoryAdaptor(name, factory)
301	ctx.registerSingletonType(name, s, parallel)
302	ctx.RegisterModuleType(name, m)
303	// Overwrite moduleTypesForDocs with the original factory instead of the lambda returned by
304	// SingletonModuleFactoryAdaptor so that docs can find the module type documentation on the
305	// factory method.
306	RegisterModuleTypeForDocs(name, reflect.ValueOf(factory))
307}
308
309func (ctx *initRegistrationContext) registerSingletonType(name string, factory SingletonFactory, parallel bool) {
310	if _, present := ctx.singletonTypes[name]; present {
311		panic(fmt.Sprintf("singleton type %q is already registered", name))
312	}
313	ctx.singletonTypes[name] = factory
314	registerSingletonType(name, factory, parallel)
315}
316
317func (ctx *initRegistrationContext) RegisterSingletonType(name string, factory SingletonFactory) {
318	ctx.registerSingletonType(name, factory, false)
319}
320
321func (ctx *initRegistrationContext) RegisterParallelSingletonType(name string, factory SingletonFactory) {
322	ctx.registerSingletonType(name, factory, true)
323}
324
325func (ctx *initRegistrationContext) PreArchMutators(f RegisterMutatorFunc) {
326	PreArchMutators(f)
327}
328
329func (ctx *initRegistrationContext) HardCodedPreArchMutators(_ RegisterMutatorFunc) {
330	// Nothing to do as the mutators are hard code in preArch in mutator.go
331}
332
333func (ctx *initRegistrationContext) PreDepsMutators(f RegisterMutatorFunc) {
334	PreDepsMutators(f)
335}
336
337func (ctx *initRegistrationContext) PostDepsMutators(f RegisterMutatorFunc) {
338	PostDepsMutators(f)
339}
340
341func (ctx *initRegistrationContext) PostApexMutators(f RegisterMutatorFunc) {
342	PostApexMutators(f)
343}
344
345func (ctx *initRegistrationContext) FinalDepsMutators(f RegisterMutatorFunc) {
346	FinalDepsMutators(f)
347}
348