blob: d00c15fd0bc923fe60042a7b446d54c731552efe [file] [log] [blame]
Colin Cross463a90e2015-06-17 14:20:06 -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 Cross798bfce2016-10-12 14:28:16 -070015package android
Colin Cross463a90e2015-06-17 14:20:06 -070016
Colin Cross4498afc2016-10-13 14:18:27 -070017import (
Paul Duffin0a286832019-12-19 12:23:01 +000018 "fmt"
Colin Cross4498afc2016-10-13 14:18:27 -070019 "github.com/google/blueprint"
Colin Crossb63d7b32023-12-07 16:54:51 -080020 "reflect"
Colin Cross4498afc2016-10-13 14:18:27 -070021)
Colin Cross463a90e2015-06-17 14:20:06 -070022
Paul Duffin1d2d42f2021-03-06 20:08:12 +000023// A sortable component is one whose registration order affects the order in which it is executed
24// and so affects the behavior of the build system. As a result it is important for the order in
25// which they are registered during tests to match the order used at runtime and so the test
26// infrastructure will sort them to match.
27//
28// The sortable components are mutators, singletons and pre-singletons. Module types are not
29// sortable because their order of registration does not affect the runtime behavior.
30type sortableComponent interface {
31 // componentName returns the name of the component.
32 //
Usta Shresthac725f472022-01-11 02:44:21 -050033 // Uniquely identifies the components within the set of components used at runtime and during
Paul Duffin1d2d42f2021-03-06 20:08:12 +000034 // tests.
35 componentName() string
36
Sasha Smundak1845f422022-12-13 14:18:58 -080037 // registers this component in the supplied context.
Paul Duffin1d2d42f2021-03-06 20:08:12 +000038 register(ctx *Context)
39}
40
41type sortableComponents []sortableComponent
42
43// registerAll registers all components in this slice with the supplied context.
44func (r sortableComponents) registerAll(ctx *Context) {
45 for _, c := range r {
46 c.register(ctx)
47 }
48}
49
Colin Cross463a90e2015-06-17 14:20:06 -070050type moduleType struct {
51 name string
Colin Cross7089c272019-01-25 22:43:35 -080052 factory ModuleFactory
Colin Cross463a90e2015-06-17 14:20:06 -070053}
54
Paul Duffin1d2d42f2021-03-06 20:08:12 +000055func (t moduleType) register(ctx *Context) {
56 ctx.RegisterModuleType(t.name, ModuleFactoryAdaptor(t.factory))
57}
58
Colin Cross463a90e2015-06-17 14:20:06 -070059var moduleTypes []moduleType
Colin Cross9aed5bc2020-12-28 15:15:34 -080060var moduleTypesForDocs = map[string]reflect.Value{}
Sam Delmerico286bf262022-03-09 20:46:37 +000061var moduleTypeByFactory = map[reflect.Value]string{}
Colin Cross463a90e2015-06-17 14:20:06 -070062
63type singleton struct {
LaMont Jonese59c0db2023-05-15 21:50:29 +000064 // True if this should be registered as a parallel singleton.
65 parallel bool
66
Colin Cross463a90e2015-06-17 14:20:06 -070067 name string
Colin Cross06fa5882020-10-29 18:21:38 -070068 factory SingletonFactory
Colin Cross463a90e2015-06-17 14:20:06 -070069}
70
LaMont Jonese59c0db2023-05-15 21:50:29 +000071func newSingleton(name string, factory SingletonFactory, parallel bool) singleton {
Cole Faustae6cda62023-11-01 15:32:40 -070072 return singleton{parallel: parallel, name: name, factory: factory}
Paul Duffin1d2d42f2021-03-06 20:08:12 +000073}
74
75func (s singleton) componentName() string {
76 return s.name
77}
78
79func (s singleton) register(ctx *Context) {
80 adaptor := SingletonFactoryAdaptor(ctx, s.factory)
Cole Faustae6cda62023-11-01 15:32:40 -070081 ctx.RegisterSingletonType(s.name, adaptor, s.parallel)
Paul Duffin1d2d42f2021-03-06 20:08:12 +000082}
83
84var _ sortableComponent = singleton{}
85
86var singletons sortableComponents
Colin Cross463a90e2015-06-17 14:20:06 -070087
Colin Cross6362e272015-10-29 15:25:03 -070088type mutator struct {
Lukacs T. Berki6c716762022-06-13 20:50:39 +020089 name string
90 bottomUpMutator blueprint.BottomUpMutator
91 topDownMutator blueprint.TopDownMutator
92 transitionMutator blueprint.TransitionMutator
93 parallel bool
Colin Cross463a90e2015-06-17 14:20:06 -070094}
95
Paul Duffin1d2d42f2021-03-06 20:08:12 +000096var _ sortableComponent = &mutator{}
97
Colin Cross36242852017-06-23 15:06:31 -070098type ModuleFactory func() Module
99
Colin Cross0875c522017-11-28 17:34:01 -0800100// ModuleFactoryAdaptor wraps a ModuleFactory into a blueprint.ModuleFactory by converting a Module
Colin Cross36242852017-06-23 15:06:31 -0700101// into a blueprint.Module and a list of property structs
102func ModuleFactoryAdaptor(factory ModuleFactory) blueprint.ModuleFactory {
103 return func() (blueprint.Module, []interface{}) {
104 module := factory()
105 return module, module.GetProperties()
106 }
107}
108
Colin Cross0875c522017-11-28 17:34:01 -0800109type SingletonFactory func() Singleton
110
111// SingletonFactoryAdaptor wraps a SingletonFactory into a blueprint.SingletonFactory by converting
112// a Singleton into a blueprint.Singleton
Colin Cross06fa5882020-10-29 18:21:38 -0700113func SingletonFactoryAdaptor(ctx *Context, factory SingletonFactory) blueprint.SingletonFactory {
Colin Cross0875c522017-11-28 17:34:01 -0800114 return func() blueprint.Singleton {
115 singleton := factory()
Colin Crossed023ec2019-02-19 12:38:45 -0800116 if makevars, ok := singleton.(SingletonMakeVarsProvider); ok {
Sasha Smundak1845f422022-12-13 14:18:58 -0800117 ctx.registerSingletonMakeVarsProvider(makevars)
Colin Crossed023ec2019-02-19 12:38:45 -0800118 }
Colin Cross4c83e5c2019-02-25 14:54:28 -0800119 return &singletonAdaptor{Singleton: singleton}
Colin Cross0875c522017-11-28 17:34:01 -0800120 }
121}
122
Colin Cross36242852017-06-23 15:06:31 -0700123func RegisterModuleType(name string, factory ModuleFactory) {
Colin Cross7089c272019-01-25 22:43:35 -0800124 moduleTypes = append(moduleTypes, moduleType{name, factory})
Colin Cross9aed5bc2020-12-28 15:15:34 -0800125 RegisterModuleTypeForDocs(name, reflect.ValueOf(factory))
126}
127
128// RegisterModuleTypeForDocs associates a module type name with a reflect.Value of the factory
129// function that has documentation for the module type. It is normally called automatically
130// by RegisterModuleType, but can be called manually after RegisterModuleType in order to
131// override the factory method used for documentation, for example if the method passed to
132// RegisterModuleType was a lambda.
133func RegisterModuleTypeForDocs(name string, factory reflect.Value) {
134 moduleTypesForDocs[name] = factory
Sam Delmerico286bf262022-03-09 20:46:37 +0000135 moduleTypeByFactory[factory] = name
Colin Cross463a90e2015-06-17 14:20:06 -0700136}
137
LaMont Jonese59c0db2023-05-15 21:50:29 +0000138func registerSingletonType(name string, factory SingletonFactory, parallel bool) {
139 singletons = append(singletons, newSingleton(name, factory, parallel))
140}
141
Colin Cross0875c522017-11-28 17:34:01 -0800142func RegisterSingletonType(name string, factory SingletonFactory) {
LaMont Jonese59c0db2023-05-15 21:50:29 +0000143 registerSingletonType(name, factory, false)
144}
145
146func RegisterParallelSingletonType(name string, factory SingletonFactory) {
147 registerSingletonType(name, factory, true)
Colin Cross463a90e2015-06-17 14:20:06 -0700148}
149
Colin Crosscec81712017-07-13 14:43:27 -0700150type Context struct {
151 *blueprint.Context
Colin Crossae8600b2020-10-29 17:09:13 -0700152 config Config
Colin Crosscec81712017-07-13 14:43:27 -0700153}
Colin Cross463a90e2015-06-17 14:20:06 -0700154
Colin Crossae8600b2020-10-29 17:09:13 -0700155func NewContext(config Config) *Context {
156 ctx := &Context{blueprint.NewContext(), config}
Colin Cross988414c2020-01-11 01:11:46 +0000157 ctx.SetSrcDir(absSrcDir)
Spandan Dasc5763832022-11-08 18:42:16 +0000158 ctx.AddIncludeTags(config.IncludeTags()...)
Sam Delmerico98a73292023-02-21 11:50:29 -0500159 ctx.AddSourceRootDirs(config.SourceRootDirs()...)
Colin Cross988414c2020-01-11 01:11:46 +0000160 return ctx
Colin Crosscec81712017-07-13 14:43:27 -0700161}
162
Jingwen Chendaa54bc2020-12-14 02:58:54 -0500163// Register the pipeline of singletons, module types, and mutators for
164// generating build.ninja and other files for Kati, from Android.bp files.
Colin Crosscec81712017-07-13 14:43:27 -0700165func (ctx *Context) Register() {
Colin Cross463a90e2015-06-17 14:20:06 -0700166 for _, t := range moduleTypes {
Paul Duffin1d2d42f2021-03-06 20:08:12 +0000167 t.register(ctx)
Colin Cross463a90e2015-06-17 14:20:06 -0700168 }
169
Paul Duffinc05b0342021-03-06 13:28:13 +0000170 mutators := collateGloballyRegisteredMutators()
171 mutators.registerAll(ctx)
Colin Cross1e676be2016-10-12 14:38:15 -0700172
Paul Duffin42d0b932021-03-06 20:24:50 +0000173 singletons := collateGloballyRegisteredSingletons()
174 singletons.registerAll(ctx)
175}
Chris Parsonsa798d962020-10-12 23:44:08 -0400176
Sasha Smundak1845f422022-12-13 14:18:58 -0800177func (ctx *Context) Config() Config {
178 return ctx.config
179}
180
181func (ctx *Context) registerSingletonMakeVarsProvider(makevars SingletonMakeVarsProvider) {
182 registerSingletonMakeVarsProvider(ctx.config, makevars)
183}
184
Paul Duffin42d0b932021-03-06 20:24:50 +0000185func collateGloballyRegisteredSingletons() sortableComponents {
186 allSingletons := append(sortableComponents(nil), singletons...)
187 allSingletons = append(allSingletons,
Paul Duffin42d0b932021-03-06 20:24:50 +0000188 // Register phony just before makevars so it can write out its phony rules as Make rules
Cole Faustae6cda62023-11-01 15:32:40 -0700189 singleton{parallel: false, name: "phony", factory: phonySingletonFactory},
Colin Cross580d2ce2019-02-09 22:59:32 -0800190
Paul Duffin42d0b932021-03-06 20:24:50 +0000191 // Register makevars after other singletons so they can export values through makevars
Cole Faustae6cda62023-11-01 15:32:40 -0700192 singleton{parallel: false, name: "makevars", factory: makeVarsSingletonFunc},
Paul Duffin42d0b932021-03-06 20:24:50 +0000193
Colin Cross31a67452023-11-02 16:57:08 -0700194 // Register rawfiles and ninjadeps last so that they can track all used environment variables and
Paul Duffin42d0b932021-03-06 20:24:50 +0000195 // Ninja file dependencies stored in the config.
Colin Cross31a67452023-11-02 16:57:08 -0700196 singleton{parallel: false, name: "rawfiles", factory: rawFilesSingletonFactory},
Cole Faustae6cda62023-11-01 15:32:40 -0700197 singleton{parallel: false, name: "ninjadeps", factory: ninjaDepsSingletonFactory},
Paul Duffin42d0b932021-03-06 20:24:50 +0000198 )
199
200 return allSingletons
Colin Cross463a90e2015-06-17 14:20:06 -0700201}
Colin Cross7089c272019-01-25 22:43:35 -0800202
203func ModuleTypeFactories() map[string]ModuleFactory {
204 ret := make(map[string]ModuleFactory)
205 for _, t := range moduleTypes {
206 ret[t.name] = t.factory
207 }
208 return ret
209}
Paul Duffinf9b1da02019-12-18 19:51:55 +0000210
Colin Cross9aed5bc2020-12-28 15:15:34 -0800211func ModuleTypeFactoriesForDocs() map[string]reflect.Value {
212 return moduleTypesForDocs
213}
214
Sam Delmerico286bf262022-03-09 20:46:37 +0000215func ModuleTypeByFactory() map[reflect.Value]string {
216 return moduleTypeByFactory
217}
218
Paul Duffinf9b1da02019-12-18 19:51:55 +0000219// Interface for registering build components.
220//
221// Provided to allow registration of build components to be shared between the runtime
222// and test environments.
223type RegistrationContext interface {
224 RegisterModuleType(name string, factory ModuleFactory)
Colin Cross9aed5bc2020-12-28 15:15:34 -0800225 RegisterSingletonModuleType(name string, factory SingletonModuleFactory)
LaMont Jonese59c0db2023-05-15 21:50:29 +0000226 RegisterParallelSingletonModuleType(name string, factory SingletonModuleFactory)
LaMont Jonese59c0db2023-05-15 21:50:29 +0000227 RegisterParallelSingletonType(name string, factory SingletonFactory)
Paul Duffinf9b1da02019-12-18 19:51:55 +0000228 RegisterSingletonType(name string, factory SingletonFactory)
Paul Duffina48f7582019-12-19 11:25:19 +0000229 PreArchMutators(f RegisterMutatorFunc)
Paul Duffina80ef842020-01-14 12:09:36 +0000230
231 // Register pre arch mutators that are hard coded into mutator.go.
232 //
233 // Only registers mutators for testing, is a noop on the InitRegistrationContext.
234 HardCodedPreArchMutators(f RegisterMutatorFunc)
235
Paul Duffin2ccaffd2019-12-19 15:12:58 +0000236 PreDepsMutators(f RegisterMutatorFunc)
237 PostDepsMutators(f RegisterMutatorFunc)
Martin Stjernholm710ec3a2020-01-16 15:12:04 +0000238 FinalDepsMutators(f RegisterMutatorFunc)
Paul Duffinf9b1da02019-12-18 19:51:55 +0000239}
240
241// Used to register build components from an init() method, e.g.
242//
Colin Crossd079e0b2022-08-16 10:27:33 -0700243// init() {
244// RegisterBuildComponents(android.InitRegistrationContext)
245// }
Paul Duffinf9b1da02019-12-18 19:51:55 +0000246//
Colin Crossd079e0b2022-08-16 10:27:33 -0700247// func RegisterBuildComponents(ctx android.RegistrationContext) {
248// ctx.RegisterModuleType(...)
249// ...
250// }
Paul Duffinf9b1da02019-12-18 19:51:55 +0000251//
252// Extracting the actual registration into a separate RegisterBuildComponents(ctx) function
253// allows it to be used to initialize test context, e.g.
254//
Colin Crossd079e0b2022-08-16 10:27:33 -0700255// ctx := android.NewTestContext(config)
256// RegisterBuildComponents(ctx)
Paul Duffin0a286832019-12-19 12:23:01 +0000257var InitRegistrationContext RegistrationContext = &initRegistrationContext{
Cole Faustae6cda62023-11-01 15:32:40 -0700258 moduleTypes: make(map[string]ModuleFactory),
259 singletonTypes: make(map[string]SingletonFactory),
Paul Duffin0a286832019-12-19 12:23:01 +0000260}
Paul Duffinf9b1da02019-12-18 19:51:55 +0000261
262// Make sure the TestContext implements RegistrationContext.
263var _ RegistrationContext = (*TestContext)(nil)
264
Paul Duffin0a286832019-12-19 12:23:01 +0000265type initRegistrationContext struct {
Colin Cross9aed5bc2020-12-28 15:15:34 -0800266 moduleTypes map[string]ModuleFactory
267 singletonTypes map[string]SingletonFactory
268 moduleTypesForDocs map[string]reflect.Value
Paul Duffin0a286832019-12-19 12:23:01 +0000269}
Paul Duffinf9b1da02019-12-18 19:51:55 +0000270
Paul Duffin0a286832019-12-19 12:23:01 +0000271func (ctx *initRegistrationContext) RegisterModuleType(name string, factory ModuleFactory) {
272 if _, present := ctx.moduleTypes[name]; present {
273 panic(fmt.Sprintf("module type %q is already registered", name))
274 }
275 ctx.moduleTypes[name] = factory
Paul Duffinf9b1da02019-12-18 19:51:55 +0000276 RegisterModuleType(name, factory)
Colin Cross9aed5bc2020-12-28 15:15:34 -0800277 RegisterModuleTypeForDocs(name, reflect.ValueOf(factory))
278}
279
280func (ctx *initRegistrationContext) RegisterSingletonModuleType(name string, factory SingletonModuleFactory) {
LaMont Jonese59c0db2023-05-15 21:50:29 +0000281 ctx.registerSingletonModuleType(name, factory, false)
282}
283func (ctx *initRegistrationContext) RegisterParallelSingletonModuleType(name string, factory SingletonModuleFactory) {
284 ctx.registerSingletonModuleType(name, factory, true)
285}
286
287func (ctx *initRegistrationContext) registerSingletonModuleType(name string, factory SingletonModuleFactory, parallel bool) {
Colin Cross9aed5bc2020-12-28 15:15:34 -0800288 s, m := SingletonModuleFactoryAdaptor(name, factory)
LaMont Jonese59c0db2023-05-15 21:50:29 +0000289 ctx.registerSingletonType(name, s, parallel)
Colin Cross9aed5bc2020-12-28 15:15:34 -0800290 ctx.RegisterModuleType(name, m)
291 // Overwrite moduleTypesForDocs with the original factory instead of the lambda returned by
292 // SingletonModuleFactoryAdaptor so that docs can find the module type documentation on the
293 // factory method.
294 RegisterModuleTypeForDocs(name, reflect.ValueOf(factory))
Paul Duffinf9b1da02019-12-18 19:51:55 +0000295}
296
LaMont Jonese59c0db2023-05-15 21:50:29 +0000297func (ctx *initRegistrationContext) registerSingletonType(name string, factory SingletonFactory, parallel bool) {
Paul Duffin0a286832019-12-19 12:23:01 +0000298 if _, present := ctx.singletonTypes[name]; present {
299 panic(fmt.Sprintf("singleton type %q is already registered", name))
300 }
301 ctx.singletonTypes[name] = factory
LaMont Jonese59c0db2023-05-15 21:50:29 +0000302 registerSingletonType(name, factory, parallel)
303}
304
305func (ctx *initRegistrationContext) RegisterSingletonType(name string, factory SingletonFactory) {
306 ctx.registerSingletonType(name, factory, false)
307}
308
309func (ctx *initRegistrationContext) RegisterParallelSingletonType(name string, factory SingletonFactory) {
310 ctx.registerSingletonType(name, factory, true)
Paul Duffinf9b1da02019-12-18 19:51:55 +0000311}
Paul Duffina48f7582019-12-19 11:25:19 +0000312
Paul Duffin0a286832019-12-19 12:23:01 +0000313func (ctx *initRegistrationContext) PreArchMutators(f RegisterMutatorFunc) {
Paul Duffina48f7582019-12-19 11:25:19 +0000314 PreArchMutators(f)
315}
Paul Duffin2ccaffd2019-12-19 15:12:58 +0000316
Sasha Smundak1845f422022-12-13 14:18:58 -0800317func (ctx *initRegistrationContext) HardCodedPreArchMutators(_ RegisterMutatorFunc) {
Paul Duffina80ef842020-01-14 12:09:36 +0000318 // Nothing to do as the mutators are hard code in preArch in mutator.go
319}
320
Paul Duffin2ccaffd2019-12-19 15:12:58 +0000321func (ctx *initRegistrationContext) PreDepsMutators(f RegisterMutatorFunc) {
322 PreDepsMutators(f)
323}
324
325func (ctx *initRegistrationContext) PostDepsMutators(f RegisterMutatorFunc) {
326 PostDepsMutators(f)
327}
Martin Stjernholm710ec3a2020-01-16 15:12:04 +0000328
329func (ctx *initRegistrationContext) FinalDepsMutators(f RegisterMutatorFunc) {
330 FinalDepsMutators(f)
331}