xref: /aosp_15_r20/build/soong/android/register.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
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	topDownMutator    blueprint.TopDownMutator
93	transitionMutator blueprint.TransitionMutator
94
95	usesRename              bool
96	usesReverseDependencies bool
97	usesReplaceDependencies bool
98	usesCreateModule        bool
99	mutatesDependencies     bool
100	mutatesGlobalState      bool
101	neverFar                bool
102}
103
104var _ sortableComponent = &mutator{}
105
106type ModuleFactory func() Module
107
108// ModuleFactoryAdaptor wraps a ModuleFactory into a blueprint.ModuleFactory by converting a Module
109// into a blueprint.Module and a list of property structs
110func ModuleFactoryAdaptor(factory ModuleFactory) blueprint.ModuleFactory {
111	return func() (blueprint.Module, []interface{}) {
112		module := factory()
113		return module, module.GetProperties()
114	}
115}
116
117type SingletonFactory func() Singleton
118
119// SingletonFactoryAdaptor wraps a SingletonFactory into a blueprint.SingletonFactory by converting
120// a Singleton into a blueprint.Singleton
121func SingletonFactoryAdaptor(ctx *Context, factory SingletonFactory) blueprint.SingletonFactory {
122	return func() blueprint.Singleton {
123		singleton := factory()
124		if makevars, ok := singleton.(SingletonMakeVarsProvider); ok {
125			ctx.registerSingletonMakeVarsProvider(makevars)
126		}
127		return &singletonAdaptor{Singleton: singleton}
128	}
129}
130
131func RegisterModuleType(name string, factory ModuleFactory) {
132	moduleTypes = append(moduleTypes, moduleType{name, factory})
133	RegisterModuleTypeForDocs(name, reflect.ValueOf(factory))
134}
135
136// RegisterModuleTypeForDocs associates a module type name with a reflect.Value of the factory
137// function that has documentation for the module type.  It is normally called automatically
138// by RegisterModuleType, but can be called manually after RegisterModuleType in order to
139// override the factory method used for documentation, for example if the method passed to
140// RegisterModuleType was a lambda.
141func RegisterModuleTypeForDocs(name string, factory reflect.Value) {
142	moduleTypesForDocs[name] = factory
143	moduleTypeByFactory[factory] = name
144}
145
146func registerSingletonType(name string, factory SingletonFactory, parallel bool) {
147	singletons = append(singletons, newSingleton(name, factory, parallel))
148}
149
150func RegisterSingletonType(name string, factory SingletonFactory) {
151	registerSingletonType(name, factory, false)
152}
153
154func RegisterParallelSingletonType(name string, factory SingletonFactory) {
155	registerSingletonType(name, factory, true)
156}
157
158type Context struct {
159	*blueprint.Context
160	config Config
161}
162
163func NewContext(config Config) *Context {
164	ctx := &Context{blueprint.NewContext(), config}
165	ctx.SetSrcDir(absSrcDir)
166	ctx.AddSourceRootDirs(config.SourceRootDirs()...)
167	return ctx
168}
169
170// Register the pipeline of singletons, module types, and mutators for
171// generating build.ninja and other files for Kati, from Android.bp files.
172func (ctx *Context) Register() {
173	for _, t := range moduleTypes {
174		t.register(ctx)
175	}
176
177	mutators := collateGloballyRegisteredMutators()
178	mutators.registerAll(ctx)
179
180	singletons := collateGloballyRegisteredSingletons()
181	singletons.registerAll(ctx)
182}
183
184func (ctx *Context) Config() Config {
185	return ctx.config
186}
187
188func (ctx *Context) registerSingletonMakeVarsProvider(makevars SingletonMakeVarsProvider) {
189	registerSingletonMakeVarsProvider(ctx.config, makevars)
190}
191
192func collateGloballyRegisteredSingletons() sortableComponents {
193	allSingletons := append(sortableComponents(nil), singletons...)
194	allSingletons = append(allSingletons,
195		// Register phony just before makevars so it can write out its phony rules as Make rules
196		singleton{parallel: false, name: "phony", factory: phonySingletonFactory},
197
198		// Register makevars after other singletons so they can export values through makevars
199		singleton{parallel: false, name: "makevars", factory: makeVarsSingletonFunc},
200
201		// Register rawfiles and ninjadeps last so that they can track all used environment variables and
202		// Ninja file dependencies stored in the config.
203		singleton{parallel: false, name: "rawfiles", factory: rawFilesSingletonFactory},
204		singleton{parallel: false, name: "ninjadeps", factory: ninjaDepsSingletonFactory},
205	)
206
207	return allSingletons
208}
209
210func ModuleTypeFactories() map[string]ModuleFactory {
211	ret := make(map[string]ModuleFactory)
212	for _, t := range moduleTypes {
213		ret[t.name] = t.factory
214	}
215	return ret
216}
217
218func ModuleTypeFactoriesForDocs() map[string]reflect.Value {
219	return moduleTypesForDocs
220}
221
222func ModuleTypeByFactory() map[reflect.Value]string {
223	return moduleTypeByFactory
224}
225
226// Interface for registering build components.
227//
228// Provided to allow registration of build components to be shared between the runtime
229// and test environments.
230type RegistrationContext interface {
231	RegisterModuleType(name string, factory ModuleFactory)
232	RegisterSingletonModuleType(name string, factory SingletonModuleFactory)
233	RegisterParallelSingletonModuleType(name string, factory SingletonModuleFactory)
234	RegisterParallelSingletonType(name string, factory SingletonFactory)
235	RegisterSingletonType(name string, factory SingletonFactory)
236	PreArchMutators(f RegisterMutatorFunc)
237
238	// Register pre arch mutators that are hard coded into mutator.go.
239	//
240	// Only registers mutators for testing, is a noop on the InitRegistrationContext.
241	HardCodedPreArchMutators(f RegisterMutatorFunc)
242
243	PreDepsMutators(f RegisterMutatorFunc)
244	PostDepsMutators(f RegisterMutatorFunc)
245	PostApexMutators(f RegisterMutatorFunc)
246	FinalDepsMutators(f RegisterMutatorFunc)
247}
248
249// Used to register build components from an init() method, e.g.
250//
251//	init() {
252//	  RegisterBuildComponents(android.InitRegistrationContext)
253//	}
254//
255//	func RegisterBuildComponents(ctx android.RegistrationContext) {
256//	  ctx.RegisterModuleType(...)
257//	  ...
258//	}
259//
260// Extracting the actual registration into a separate RegisterBuildComponents(ctx) function
261// allows it to be used to initialize test context, e.g.
262//
263//	ctx := android.NewTestContext(config)
264//	RegisterBuildComponents(ctx)
265var InitRegistrationContext RegistrationContext = &initRegistrationContext{
266	moduleTypes:    make(map[string]ModuleFactory),
267	singletonTypes: make(map[string]SingletonFactory),
268}
269
270// Make sure the TestContext implements RegistrationContext.
271var _ RegistrationContext = (*TestContext)(nil)
272
273type initRegistrationContext struct {
274	moduleTypes        map[string]ModuleFactory
275	singletonTypes     map[string]SingletonFactory
276	moduleTypesForDocs map[string]reflect.Value
277}
278
279func (ctx *initRegistrationContext) RegisterModuleType(name string, factory ModuleFactory) {
280	if _, present := ctx.moduleTypes[name]; present {
281		panic(fmt.Sprintf("module type %q is already registered", name))
282	}
283	ctx.moduleTypes[name] = factory
284	RegisterModuleType(name, factory)
285	RegisterModuleTypeForDocs(name, reflect.ValueOf(factory))
286}
287
288func (ctx *initRegistrationContext) RegisterSingletonModuleType(name string, factory SingletonModuleFactory) {
289	ctx.registerSingletonModuleType(name, factory, false)
290}
291func (ctx *initRegistrationContext) RegisterParallelSingletonModuleType(name string, factory SingletonModuleFactory) {
292	ctx.registerSingletonModuleType(name, factory, true)
293}
294
295func (ctx *initRegistrationContext) registerSingletonModuleType(name string, factory SingletonModuleFactory, parallel bool) {
296	s, m := SingletonModuleFactoryAdaptor(name, factory)
297	ctx.registerSingletonType(name, s, parallel)
298	ctx.RegisterModuleType(name, m)
299	// Overwrite moduleTypesForDocs with the original factory instead of the lambda returned by
300	// SingletonModuleFactoryAdaptor so that docs can find the module type documentation on the
301	// factory method.
302	RegisterModuleTypeForDocs(name, reflect.ValueOf(factory))
303}
304
305func (ctx *initRegistrationContext) registerSingletonType(name string, factory SingletonFactory, parallel bool) {
306	if _, present := ctx.singletonTypes[name]; present {
307		panic(fmt.Sprintf("singleton type %q is already registered", name))
308	}
309	ctx.singletonTypes[name] = factory
310	registerSingletonType(name, factory, parallel)
311}
312
313func (ctx *initRegistrationContext) RegisterSingletonType(name string, factory SingletonFactory) {
314	ctx.registerSingletonType(name, factory, false)
315}
316
317func (ctx *initRegistrationContext) RegisterParallelSingletonType(name string, factory SingletonFactory) {
318	ctx.registerSingletonType(name, factory, true)
319}
320
321func (ctx *initRegistrationContext) PreArchMutators(f RegisterMutatorFunc) {
322	PreArchMutators(f)
323}
324
325func (ctx *initRegistrationContext) HardCodedPreArchMutators(_ RegisterMutatorFunc) {
326	// Nothing to do as the mutators are hard code in preArch in mutator.go
327}
328
329func (ctx *initRegistrationContext) PreDepsMutators(f RegisterMutatorFunc) {
330	PreDepsMutators(f)
331}
332
333func (ctx *initRegistrationContext) PostDepsMutators(f RegisterMutatorFunc) {
334	PostDepsMutators(f)
335}
336
337func (ctx *initRegistrationContext) PostApexMutators(f RegisterMutatorFunc) {
338	PostApexMutators(f)
339}
340
341func (ctx *initRegistrationContext) FinalDepsMutators(f RegisterMutatorFunc) {
342	FinalDepsMutators(f)
343}
344