blob: 59848627a699e2abb7b210e0caee7b975e23fa9e [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 Cross9aed5bc2020-12-28 15:15:34 -080019 "reflect"
Paul Duffin0a286832019-12-19 12:23:01 +000020
Colin Cross4498afc2016-10-13 14:18:27 -070021 "github.com/google/blueprint"
22)
Colin Cross463a90e2015-06-17 14:20:06 -070023
Paul Duffin1d2d42f2021-03-06 20:08:12 +000024// 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 runtimr and during
35 // tests.
36 componentName() string
37
38 // register 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
Colin Cross463a90e2015-06-17 14:20:06 -070051type moduleType struct {
52 name string
Colin Cross7089c272019-01-25 22:43:35 -080053 factory ModuleFactory
Colin Cross463a90e2015-06-17 14:20:06 -070054}
55
Paul Duffin1d2d42f2021-03-06 20:08:12 +000056func (t moduleType) register(ctx *Context) {
57 ctx.RegisterModuleType(t.name, ModuleFactoryAdaptor(t.factory))
58}
59
Colin Cross463a90e2015-06-17 14:20:06 -070060var moduleTypes []moduleType
Colin Cross9aed5bc2020-12-28 15:15:34 -080061var moduleTypesForDocs = map[string]reflect.Value{}
Colin Cross463a90e2015-06-17 14:20:06 -070062
63type singleton struct {
Paul Duffin1d2d42f2021-03-06 20:08:12 +000064 // True if this should be registered as a pre-singleton, false otherwise.
65 pre 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
Paul Duffin1d2d42f2021-03-06 20:08:12 +000071func newSingleton(name string, factory SingletonFactory) singleton {
72 return singleton{false, name, factory}
73}
74
75func newPreSingleton(name string, factory SingletonFactory) singleton {
76 return singleton{true, name, factory}
77}
78
79func (s singleton) componentName() string {
80 return s.name
81}
82
83func (s singleton) register(ctx *Context) {
84 adaptor := SingletonFactoryAdaptor(ctx, s.factory)
85 if s.pre {
86 ctx.RegisterPreSingletonType(s.name, adaptor)
87 } else {
88 ctx.RegisterSingletonType(s.name, adaptor)
89 }
90}
91
92var _ sortableComponent = singleton{}
93
94var singletons sortableComponents
95var preSingletons sortableComponents
Colin Cross463a90e2015-06-17 14:20:06 -070096
Colin Cross6362e272015-10-29 15:25:03 -070097type mutator struct {
98 name string
99 bottomUpMutator blueprint.BottomUpMutator
100 topDownMutator blueprint.TopDownMutator
Colin Crosse8a67a72016-08-07 21:17:54 -0700101 parallel bool
Colin Cross463a90e2015-06-17 14:20:06 -0700102}
103
Paul Duffin1d2d42f2021-03-06 20:08:12 +0000104var _ sortableComponent = &mutator{}
105
Colin Cross36242852017-06-23 15:06:31 -0700106type ModuleFactory func() Module
107
Colin Cross0875c522017-11-28 17:34:01 -0800108// ModuleFactoryAdaptor wraps a ModuleFactory into a blueprint.ModuleFactory by converting a Module
Colin Cross36242852017-06-23 15:06:31 -0700109// 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
Colin Cross0875c522017-11-28 17:34:01 -0800117type SingletonFactory func() Singleton
118
119// SingletonFactoryAdaptor wraps a SingletonFactory into a blueprint.SingletonFactory by converting
120// a Singleton into a blueprint.Singleton
Colin Cross06fa5882020-10-29 18:21:38 -0700121func SingletonFactoryAdaptor(ctx *Context, factory SingletonFactory) blueprint.SingletonFactory {
Colin Cross0875c522017-11-28 17:34:01 -0800122 return func() blueprint.Singleton {
123 singleton := factory()
Colin Crossed023ec2019-02-19 12:38:45 -0800124 if makevars, ok := singleton.(SingletonMakeVarsProvider); ok {
Colin Cross06fa5882020-10-29 18:21:38 -0700125 registerSingletonMakeVarsProvider(ctx.config, makevars)
Colin Crossed023ec2019-02-19 12:38:45 -0800126 }
Colin Cross4c83e5c2019-02-25 14:54:28 -0800127 return &singletonAdaptor{Singleton: singleton}
Colin Cross0875c522017-11-28 17:34:01 -0800128 }
129}
130
Colin Cross36242852017-06-23 15:06:31 -0700131func RegisterModuleType(name string, factory ModuleFactory) {
Colin Cross7089c272019-01-25 22:43:35 -0800132 moduleTypes = append(moduleTypes, moduleType{name, factory})
Colin Cross9aed5bc2020-12-28 15:15:34 -0800133 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
Colin Cross463a90e2015-06-17 14:20:06 -0700143}
144
Colin Cross0875c522017-11-28 17:34:01 -0800145func RegisterSingletonType(name string, factory SingletonFactory) {
Paul Duffin1d2d42f2021-03-06 20:08:12 +0000146 singletons = append(singletons, newSingleton(name, factory))
Colin Cross463a90e2015-06-17 14:20:06 -0700147}
148
Colin Cross0875c522017-11-28 17:34:01 -0800149func RegisterPreSingletonType(name string, factory SingletonFactory) {
Paul Duffin1d2d42f2021-03-06 20:08:12 +0000150 preSingletons = append(preSingletons, newPreSingleton(name, factory))
Colin Cross5a79c832017-11-07 13:35:38 -0800151}
152
Colin Crosscec81712017-07-13 14:43:27 -0700153type Context struct {
154 *blueprint.Context
Colin Crossae8600b2020-10-29 17:09:13 -0700155 config Config
Colin Crosscec81712017-07-13 14:43:27 -0700156}
Colin Cross463a90e2015-06-17 14:20:06 -0700157
Colin Crossae8600b2020-10-29 17:09:13 -0700158func NewContext(config Config) *Context {
159 ctx := &Context{blueprint.NewContext(), config}
Colin Cross988414c2020-01-11 01:11:46 +0000160 ctx.SetSrcDir(absSrcDir)
161 return ctx
Colin Crosscec81712017-07-13 14:43:27 -0700162}
163
Jingwen Chen4133ce62020-12-02 04:34:15 -0500164// RegisterForBazelConversion registers an alternate shadow pipeline of
165// singletons, module types and mutators to register for converting Blueprint
166// files to semantically equivalent BUILD files.
167func (ctx *Context) RegisterForBazelConversion() {
168 for _, t := range moduleTypes {
Paul Duffin1d2d42f2021-03-06 20:08:12 +0000169 t.register(ctx)
Jingwen Chen4133ce62020-12-02 04:34:15 -0500170 }
171
Jingwen Chendaa54bc2020-12-14 02:58:54 -0500172 // Required for SingletonModule types, even though we are not using them.
173 for _, t := range singletons {
Paul Duffin1d2d42f2021-03-06 20:08:12 +0000174 t.register(ctx)
Liz Kammer2dd9ca42020-11-25 16:06:39 -0800175 }
Jingwen Chen4133ce62020-12-02 04:34:15 -0500176
Jingwen Chen12b4c272021-03-10 02:05:59 -0500177 bp2buildMutatorList := []RegisterMutatorFunc{}
178 for t, f := range bp2buildMutators {
179 ctx.config.bp2buildModuleTypeConfig[t] = true
180 bp2buildMutatorList = append(bp2buildMutatorList, f)
181 }
182
Chris Parsons5a34ffb2021-07-21 14:34:58 -0400183 RegisterMutatorsForBazelConversion(ctx, bp2buildPreArchMutators, bp2buildMutatorList)
Jingwen Chen4133ce62020-12-02 04:34:15 -0500184}
185
Jingwen Chendaa54bc2020-12-14 02:58:54 -0500186// Register the pipeline of singletons, module types, and mutators for
187// generating build.ninja and other files for Kati, from Android.bp files.
Colin Crosscec81712017-07-13 14:43:27 -0700188func (ctx *Context) Register() {
Paul Duffin1d2d42f2021-03-06 20:08:12 +0000189 preSingletons.registerAll(ctx)
Colin Cross5a79c832017-11-07 13:35:38 -0800190
Colin Cross463a90e2015-06-17 14:20:06 -0700191 for _, t := range moduleTypes {
Paul Duffin1d2d42f2021-03-06 20:08:12 +0000192 t.register(ctx)
Colin Cross463a90e2015-06-17 14:20:06 -0700193 }
194
Chris Parsonsb164b382021-03-29 20:06:57 -0400195 if ctx.config.BazelContext.BazelEnabled() {
196 // Hydrate the configuration of bp2build-enabled module types. This is
197 // required as a signal to identify which modules should be deferred to
198 // Bazel in mixed builds, if it is enabled.
199 for t, _ := range bp2buildMutators {
200 ctx.config.bp2buildModuleTypeConfig[t] = true
201 }
202 }
203
Paul Duffinc05b0342021-03-06 13:28:13 +0000204 mutators := collateGloballyRegisteredMutators()
205 mutators.registerAll(ctx)
Colin Cross1e676be2016-10-12 14:38:15 -0700206
Paul Duffin42d0b932021-03-06 20:24:50 +0000207 singletons := collateGloballyRegisteredSingletons()
208 singletons.registerAll(ctx)
209}
Chris Parsonsa798d962020-10-12 23:44:08 -0400210
Paul Duffin42d0b932021-03-06 20:24:50 +0000211func collateGloballyRegisteredSingletons() sortableComponents {
212 allSingletons := append(sortableComponents(nil), singletons...)
213 allSingletons = append(allSingletons,
214 singleton{false, "bazeldeps", BazelSingleton},
Colin Crossc3d87d32020-06-04 13:25:17 -0700215
Paul Duffin42d0b932021-03-06 20:24:50 +0000216 // Register phony just before makevars so it can write out its phony rules as Make rules
217 singleton{false, "phony", phonySingletonFactory},
Colin Cross580d2ce2019-02-09 22:59:32 -0800218
Paul Duffin42d0b932021-03-06 20:24:50 +0000219 // Register makevars after other singletons so they can export values through makevars
220 singleton{false, "makevars", makeVarsSingletonFunc},
221
222 // Register env and ninjadeps last so that they can track all used environment variables and
223 // Ninja file dependencies stored in the config.
Paul Duffin42d0b932021-03-06 20:24:50 +0000224 singleton{false, "ninjadeps", ninjaDepsSingletonFactory},
225 )
226
227 return allSingletons
Colin Cross463a90e2015-06-17 14:20:06 -0700228}
Colin Cross7089c272019-01-25 22:43:35 -0800229
230func ModuleTypeFactories() map[string]ModuleFactory {
231 ret := make(map[string]ModuleFactory)
232 for _, t := range moduleTypes {
233 ret[t.name] = t.factory
234 }
235 return ret
236}
Paul Duffinf9b1da02019-12-18 19:51:55 +0000237
Colin Cross9aed5bc2020-12-28 15:15:34 -0800238func ModuleTypeFactoriesForDocs() map[string]reflect.Value {
239 return moduleTypesForDocs
240}
241
Paul Duffinf9b1da02019-12-18 19:51:55 +0000242// Interface for registering build components.
243//
244// Provided to allow registration of build components to be shared between the runtime
245// and test environments.
246type RegistrationContext interface {
247 RegisterModuleType(name string, factory ModuleFactory)
Colin Cross9aed5bc2020-12-28 15:15:34 -0800248 RegisterSingletonModuleType(name string, factory SingletonModuleFactory)
Paul Duffineafc16b2021-02-24 01:43:18 +0000249 RegisterPreSingletonType(name string, factory SingletonFactory)
Paul Duffinf9b1da02019-12-18 19:51:55 +0000250 RegisterSingletonType(name string, factory SingletonFactory)
Paul Duffina48f7582019-12-19 11:25:19 +0000251 PreArchMutators(f RegisterMutatorFunc)
Paul Duffina80ef842020-01-14 12:09:36 +0000252
253 // Register pre arch mutators that are hard coded into mutator.go.
254 //
255 // Only registers mutators for testing, is a noop on the InitRegistrationContext.
256 HardCodedPreArchMutators(f RegisterMutatorFunc)
257
Paul Duffin2ccaffd2019-12-19 15:12:58 +0000258 PreDepsMutators(f RegisterMutatorFunc)
259 PostDepsMutators(f RegisterMutatorFunc)
Martin Stjernholm710ec3a2020-01-16 15:12:04 +0000260 FinalDepsMutators(f RegisterMutatorFunc)
Paul Duffinf9b1da02019-12-18 19:51:55 +0000261}
262
263// Used to register build components from an init() method, e.g.
264//
265// init() {
266// RegisterBuildComponents(android.InitRegistrationContext)
267// }
268//
269// func RegisterBuildComponents(ctx android.RegistrationContext) {
270// ctx.RegisterModuleType(...)
271// ...
272// }
273//
274// Extracting the actual registration into a separate RegisterBuildComponents(ctx) function
275// allows it to be used to initialize test context, e.g.
276//
Colin Crossae8600b2020-10-29 17:09:13 -0700277// ctx := android.NewTestContext(config)
Paul Duffinf9b1da02019-12-18 19:51:55 +0000278// RegisterBuildComponents(ctx)
Paul Duffin0a286832019-12-19 12:23:01 +0000279var InitRegistrationContext RegistrationContext = &initRegistrationContext{
Paul Duffin42da69d2021-03-22 13:41:36 +0000280 moduleTypes: make(map[string]ModuleFactory),
281 singletonTypes: make(map[string]SingletonFactory),
282 preSingletonTypes: make(map[string]SingletonFactory),
Paul Duffin0a286832019-12-19 12:23:01 +0000283}
Paul Duffinf9b1da02019-12-18 19:51:55 +0000284
285// Make sure the TestContext implements RegistrationContext.
286var _ RegistrationContext = (*TestContext)(nil)
287
Paul Duffin0a286832019-12-19 12:23:01 +0000288type initRegistrationContext struct {
Colin Cross9aed5bc2020-12-28 15:15:34 -0800289 moduleTypes map[string]ModuleFactory
290 singletonTypes map[string]SingletonFactory
Paul Duffineafc16b2021-02-24 01:43:18 +0000291 preSingletonTypes map[string]SingletonFactory
Colin Cross9aed5bc2020-12-28 15:15:34 -0800292 moduleTypesForDocs map[string]reflect.Value
Paul Duffin0a286832019-12-19 12:23:01 +0000293}
Paul Duffinf9b1da02019-12-18 19:51:55 +0000294
Paul Duffin0a286832019-12-19 12:23:01 +0000295func (ctx *initRegistrationContext) RegisterModuleType(name string, factory ModuleFactory) {
296 if _, present := ctx.moduleTypes[name]; present {
297 panic(fmt.Sprintf("module type %q is already registered", name))
298 }
299 ctx.moduleTypes[name] = factory
Paul Duffinf9b1da02019-12-18 19:51:55 +0000300 RegisterModuleType(name, factory)
Colin Cross9aed5bc2020-12-28 15:15:34 -0800301 RegisterModuleTypeForDocs(name, reflect.ValueOf(factory))
302}
303
304func (ctx *initRegistrationContext) RegisterSingletonModuleType(name string, factory SingletonModuleFactory) {
305 s, m := SingletonModuleFactoryAdaptor(name, factory)
306 ctx.RegisterSingletonType(name, s)
307 ctx.RegisterModuleType(name, m)
308 // Overwrite moduleTypesForDocs with the original factory instead of the lambda returned by
309 // SingletonModuleFactoryAdaptor so that docs can find the module type documentation on the
310 // factory method.
311 RegisterModuleTypeForDocs(name, reflect.ValueOf(factory))
Paul Duffinf9b1da02019-12-18 19:51:55 +0000312}
313
Paul Duffin0a286832019-12-19 12:23:01 +0000314func (ctx *initRegistrationContext) RegisterSingletonType(name string, factory SingletonFactory) {
315 if _, present := ctx.singletonTypes[name]; present {
316 panic(fmt.Sprintf("singleton type %q is already registered", name))
317 }
318 ctx.singletonTypes[name] = factory
Paul Duffinf9b1da02019-12-18 19:51:55 +0000319 RegisterSingletonType(name, factory)
320}
Paul Duffina48f7582019-12-19 11:25:19 +0000321
Paul Duffineafc16b2021-02-24 01:43:18 +0000322func (ctx *initRegistrationContext) RegisterPreSingletonType(name string, factory SingletonFactory) {
323 if _, present := ctx.preSingletonTypes[name]; present {
324 panic(fmt.Sprintf("pre singleton type %q is already registered", name))
325 }
326 ctx.preSingletonTypes[name] = factory
327 RegisterPreSingletonType(name, factory)
328}
329
Paul Duffin0a286832019-12-19 12:23:01 +0000330func (ctx *initRegistrationContext) PreArchMutators(f RegisterMutatorFunc) {
Paul Duffina48f7582019-12-19 11:25:19 +0000331 PreArchMutators(f)
332}
Paul Duffin2ccaffd2019-12-19 15:12:58 +0000333
Paul Duffina80ef842020-01-14 12:09:36 +0000334func (ctx *initRegistrationContext) HardCodedPreArchMutators(f RegisterMutatorFunc) {
335 // Nothing to do as the mutators are hard code in preArch in mutator.go
336}
337
Paul Duffin2ccaffd2019-12-19 15:12:58 +0000338func (ctx *initRegistrationContext) PreDepsMutators(f RegisterMutatorFunc) {
339 PreDepsMutators(f)
340}
341
342func (ctx *initRegistrationContext) PostDepsMutators(f RegisterMutatorFunc) {
343 PostDepsMutators(f)
344}
Martin Stjernholm710ec3a2020-01-16 15:12:04 +0000345
346func (ctx *initRegistrationContext) FinalDepsMutators(f RegisterMutatorFunc) {
347 FinalDepsMutators(f)
348}