blob: 61889f6c2d63cc52f0530ea8ef4e7aaaac756553 [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
24type moduleType struct {
25 name string
Colin Cross7089c272019-01-25 22:43:35 -080026 factory ModuleFactory
Colin Cross463a90e2015-06-17 14:20:06 -070027}
28
29var moduleTypes []moduleType
Colin Cross9aed5bc2020-12-28 15:15:34 -080030var moduleTypesForDocs = map[string]reflect.Value{}
Colin Cross463a90e2015-06-17 14:20:06 -070031
32type singleton struct {
33 name string
Colin Cross06fa5882020-10-29 18:21:38 -070034 factory SingletonFactory
Colin Cross463a90e2015-06-17 14:20:06 -070035}
36
37var singletons []singleton
Colin Cross5a79c832017-11-07 13:35:38 -080038var preSingletons []singleton
Colin Cross463a90e2015-06-17 14:20:06 -070039
Colin Cross6362e272015-10-29 15:25:03 -070040type mutator struct {
41 name string
42 bottomUpMutator blueprint.BottomUpMutator
43 topDownMutator blueprint.TopDownMutator
Colin Crosse8a67a72016-08-07 21:17:54 -070044 parallel bool
Colin Cross463a90e2015-06-17 14:20:06 -070045}
46
Colin Cross36242852017-06-23 15:06:31 -070047type ModuleFactory func() Module
48
Colin Cross0875c522017-11-28 17:34:01 -080049// ModuleFactoryAdaptor wraps a ModuleFactory into a blueprint.ModuleFactory by converting a Module
Colin Cross36242852017-06-23 15:06:31 -070050// into a blueprint.Module and a list of property structs
51func ModuleFactoryAdaptor(factory ModuleFactory) blueprint.ModuleFactory {
52 return func() (blueprint.Module, []interface{}) {
53 module := factory()
54 return module, module.GetProperties()
55 }
56}
57
Colin Cross0875c522017-11-28 17:34:01 -080058type SingletonFactory func() Singleton
59
60// SingletonFactoryAdaptor wraps a SingletonFactory into a blueprint.SingletonFactory by converting
61// a Singleton into a blueprint.Singleton
Colin Cross06fa5882020-10-29 18:21:38 -070062func SingletonFactoryAdaptor(ctx *Context, factory SingletonFactory) blueprint.SingletonFactory {
Colin Cross0875c522017-11-28 17:34:01 -080063 return func() blueprint.Singleton {
64 singleton := factory()
Colin Crossed023ec2019-02-19 12:38:45 -080065 if makevars, ok := singleton.(SingletonMakeVarsProvider); ok {
Colin Cross06fa5882020-10-29 18:21:38 -070066 registerSingletonMakeVarsProvider(ctx.config, makevars)
Colin Crossed023ec2019-02-19 12:38:45 -080067 }
Colin Cross4c83e5c2019-02-25 14:54:28 -080068 return &singletonAdaptor{Singleton: singleton}
Colin Cross0875c522017-11-28 17:34:01 -080069 }
70}
71
Colin Cross36242852017-06-23 15:06:31 -070072func RegisterModuleType(name string, factory ModuleFactory) {
Colin Cross7089c272019-01-25 22:43:35 -080073 moduleTypes = append(moduleTypes, moduleType{name, factory})
Colin Cross9aed5bc2020-12-28 15:15:34 -080074 RegisterModuleTypeForDocs(name, reflect.ValueOf(factory))
75}
76
77// RegisterModuleTypeForDocs associates a module type name with a reflect.Value of the factory
78// function that has documentation for the module type. It is normally called automatically
79// by RegisterModuleType, but can be called manually after RegisterModuleType in order to
80// override the factory method used for documentation, for example if the method passed to
81// RegisterModuleType was a lambda.
82func RegisterModuleTypeForDocs(name string, factory reflect.Value) {
83 moduleTypesForDocs[name] = factory
Colin Cross463a90e2015-06-17 14:20:06 -070084}
85
Colin Cross0875c522017-11-28 17:34:01 -080086func RegisterSingletonType(name string, factory SingletonFactory) {
Colin Cross06fa5882020-10-29 18:21:38 -070087 singletons = append(singletons, singleton{name, factory})
Colin Cross463a90e2015-06-17 14:20:06 -070088}
89
Colin Cross0875c522017-11-28 17:34:01 -080090func RegisterPreSingletonType(name string, factory SingletonFactory) {
Colin Cross06fa5882020-10-29 18:21:38 -070091 preSingletons = append(preSingletons, singleton{name, factory})
Colin Cross5a79c832017-11-07 13:35:38 -080092}
93
Colin Crosscec81712017-07-13 14:43:27 -070094type Context struct {
95 *blueprint.Context
Colin Crossae8600b2020-10-29 17:09:13 -070096 config Config
Colin Crosscec81712017-07-13 14:43:27 -070097}
Colin Cross463a90e2015-06-17 14:20:06 -070098
Colin Crossae8600b2020-10-29 17:09:13 -070099func NewContext(config Config) *Context {
100 ctx := &Context{blueprint.NewContext(), config}
Colin Cross988414c2020-01-11 01:11:46 +0000101 ctx.SetSrcDir(absSrcDir)
102 return ctx
Colin Crosscec81712017-07-13 14:43:27 -0700103}
104
Jingwen Chen4133ce62020-12-02 04:34:15 -0500105// RegisterForBazelConversion registers an alternate shadow pipeline of
106// singletons, module types and mutators to register for converting Blueprint
107// files to semantically equivalent BUILD files.
108func (ctx *Context) RegisterForBazelConversion() {
109 for _, t := range moduleTypes {
110 ctx.RegisterModuleType(t.name, ModuleFactoryAdaptor(t.factory))
111 }
112
113 bazelConverterSingleton := singleton{"bp2build", BazelConverterSingleton}
114 ctx.RegisterSingletonType(bazelConverterSingleton.name,
115 SingletonFactoryAdaptor(ctx, bazelConverterSingleton.factory))
116
117 registerMutatorsForBazelConversion(ctx.Context)
118}
119
Colin Crosscec81712017-07-13 14:43:27 -0700120func (ctx *Context) Register() {
Colin Cross5a79c832017-11-07 13:35:38 -0800121 for _, t := range preSingletons {
Colin Cross06fa5882020-10-29 18:21:38 -0700122 ctx.RegisterPreSingletonType(t.name, SingletonFactoryAdaptor(ctx, t.factory))
Colin Cross5a79c832017-11-07 13:35:38 -0800123 }
124
Colin Cross463a90e2015-06-17 14:20:06 -0700125 for _, t := range moduleTypes {
Colin Cross7089c272019-01-25 22:43:35 -0800126 ctx.RegisterModuleType(t.name, ModuleFactoryAdaptor(t.factory))
Colin Cross463a90e2015-06-17 14:20:06 -0700127 }
128
129 for _, t := range singletons {
Colin Cross06fa5882020-10-29 18:21:38 -0700130 ctx.RegisterSingletonType(t.name, SingletonFactoryAdaptor(ctx, t.factory))
Colin Cross463a90e2015-06-17 14:20:06 -0700131 }
132
Martin Stjernholm710ec3a2020-01-16 15:12:04 +0000133 registerMutators(ctx.Context, preArch, preDeps, postDeps, finalDeps)
Colin Cross1e676be2016-10-12 14:38:15 -0700134
Colin Cross06fa5882020-10-29 18:21:38 -0700135 ctx.RegisterSingletonType("bazeldeps", SingletonFactoryAdaptor(ctx, BazelSingleton))
Chris Parsonsa798d962020-10-12 23:44:08 -0400136
Colin Crossc3d87d32020-06-04 13:25:17 -0700137 // Register phony just before makevars so it can write out its phony rules as Make rules
Colin Cross06fa5882020-10-29 18:21:38 -0700138 ctx.RegisterSingletonType("phony", SingletonFactoryAdaptor(ctx, phonySingletonFactory))
Colin Crossc3d87d32020-06-04 13:25:17 -0700139
Colin Cross580d2ce2019-02-09 22:59:32 -0800140 // Register makevars after other singletons so they can export values through makevars
Colin Cross06fa5882020-10-29 18:21:38 -0700141 ctx.RegisterSingletonType("makevars", SingletonFactoryAdaptor(ctx, makeVarsSingletonFunc))
Colin Cross580d2ce2019-02-09 22:59:32 -0800142
Colin Cross12129292020-10-29 18:23:58 -0700143 // Register env and ninjadeps last so that they can track all used environment variables and
144 // Ninja file dependencies stored in the config.
Colin Cross06fa5882020-10-29 18:21:38 -0700145 ctx.RegisterSingletonType("env", SingletonFactoryAdaptor(ctx, EnvSingleton))
Colin Cross12129292020-10-29 18:23:58 -0700146 ctx.RegisterSingletonType("ninjadeps", SingletonFactoryAdaptor(ctx, ninjaDepsSingletonFactory))
Colin Cross463a90e2015-06-17 14:20:06 -0700147}
Colin Cross7089c272019-01-25 22:43:35 -0800148
149func ModuleTypeFactories() map[string]ModuleFactory {
150 ret := make(map[string]ModuleFactory)
151 for _, t := range moduleTypes {
152 ret[t.name] = t.factory
153 }
154 return ret
155}
Paul Duffinf9b1da02019-12-18 19:51:55 +0000156
Colin Cross9aed5bc2020-12-28 15:15:34 -0800157func ModuleTypeFactoriesForDocs() map[string]reflect.Value {
158 return moduleTypesForDocs
159}
160
Paul Duffinf9b1da02019-12-18 19:51:55 +0000161// Interface for registering build components.
162//
163// Provided to allow registration of build components to be shared between the runtime
164// and test environments.
165type RegistrationContext interface {
166 RegisterModuleType(name string, factory ModuleFactory)
Colin Cross9aed5bc2020-12-28 15:15:34 -0800167 RegisterSingletonModuleType(name string, factory SingletonModuleFactory)
Paul Duffinf9b1da02019-12-18 19:51:55 +0000168 RegisterSingletonType(name string, factory SingletonFactory)
Paul Duffina48f7582019-12-19 11:25:19 +0000169 PreArchMutators(f RegisterMutatorFunc)
Paul Duffina80ef842020-01-14 12:09:36 +0000170
171 // Register pre arch mutators that are hard coded into mutator.go.
172 //
173 // Only registers mutators for testing, is a noop on the InitRegistrationContext.
174 HardCodedPreArchMutators(f RegisterMutatorFunc)
175
Paul Duffin2ccaffd2019-12-19 15:12:58 +0000176 PreDepsMutators(f RegisterMutatorFunc)
177 PostDepsMutators(f RegisterMutatorFunc)
Martin Stjernholm710ec3a2020-01-16 15:12:04 +0000178 FinalDepsMutators(f RegisterMutatorFunc)
Paul Duffinf9b1da02019-12-18 19:51:55 +0000179}
180
181// Used to register build components from an init() method, e.g.
182//
183// init() {
184// RegisterBuildComponents(android.InitRegistrationContext)
185// }
186//
187// func RegisterBuildComponents(ctx android.RegistrationContext) {
188// ctx.RegisterModuleType(...)
189// ...
190// }
191//
192// Extracting the actual registration into a separate RegisterBuildComponents(ctx) function
193// allows it to be used to initialize test context, e.g.
194//
Colin Crossae8600b2020-10-29 17:09:13 -0700195// ctx := android.NewTestContext(config)
Paul Duffinf9b1da02019-12-18 19:51:55 +0000196// RegisterBuildComponents(ctx)
Paul Duffin0a286832019-12-19 12:23:01 +0000197var InitRegistrationContext RegistrationContext = &initRegistrationContext{
198 moduleTypes: make(map[string]ModuleFactory),
199 singletonTypes: make(map[string]SingletonFactory),
200}
Paul Duffinf9b1da02019-12-18 19:51:55 +0000201
202// Make sure the TestContext implements RegistrationContext.
203var _ RegistrationContext = (*TestContext)(nil)
204
Paul Duffin0a286832019-12-19 12:23:01 +0000205type initRegistrationContext struct {
Colin Cross9aed5bc2020-12-28 15:15:34 -0800206 moduleTypes map[string]ModuleFactory
207 singletonTypes map[string]SingletonFactory
208 moduleTypesForDocs map[string]reflect.Value
Paul Duffin0a286832019-12-19 12:23:01 +0000209}
Paul Duffinf9b1da02019-12-18 19:51:55 +0000210
Paul Duffin0a286832019-12-19 12:23:01 +0000211func (ctx *initRegistrationContext) RegisterModuleType(name string, factory ModuleFactory) {
212 if _, present := ctx.moduleTypes[name]; present {
213 panic(fmt.Sprintf("module type %q is already registered", name))
214 }
215 ctx.moduleTypes[name] = factory
Paul Duffinf9b1da02019-12-18 19:51:55 +0000216 RegisterModuleType(name, factory)
Colin Cross9aed5bc2020-12-28 15:15:34 -0800217 RegisterModuleTypeForDocs(name, reflect.ValueOf(factory))
218}
219
220func (ctx *initRegistrationContext) RegisterSingletonModuleType(name string, factory SingletonModuleFactory) {
221 s, m := SingletonModuleFactoryAdaptor(name, factory)
222 ctx.RegisterSingletonType(name, s)
223 ctx.RegisterModuleType(name, m)
224 // Overwrite moduleTypesForDocs with the original factory instead of the lambda returned by
225 // SingletonModuleFactoryAdaptor so that docs can find the module type documentation on the
226 // factory method.
227 RegisterModuleTypeForDocs(name, reflect.ValueOf(factory))
Paul Duffinf9b1da02019-12-18 19:51:55 +0000228}
229
Paul Duffin0a286832019-12-19 12:23:01 +0000230func (ctx *initRegistrationContext) RegisterSingletonType(name string, factory SingletonFactory) {
231 if _, present := ctx.singletonTypes[name]; present {
232 panic(fmt.Sprintf("singleton type %q is already registered", name))
233 }
234 ctx.singletonTypes[name] = factory
Paul Duffinf9b1da02019-12-18 19:51:55 +0000235 RegisterSingletonType(name, factory)
236}
Paul Duffina48f7582019-12-19 11:25:19 +0000237
Paul Duffin0a286832019-12-19 12:23:01 +0000238func (ctx *initRegistrationContext) PreArchMutators(f RegisterMutatorFunc) {
Paul Duffina48f7582019-12-19 11:25:19 +0000239 PreArchMutators(f)
240}
Paul Duffin2ccaffd2019-12-19 15:12:58 +0000241
Paul Duffina80ef842020-01-14 12:09:36 +0000242func (ctx *initRegistrationContext) HardCodedPreArchMutators(f RegisterMutatorFunc) {
243 // Nothing to do as the mutators are hard code in preArch in mutator.go
244}
245
Paul Duffin2ccaffd2019-12-19 15:12:58 +0000246func (ctx *initRegistrationContext) PreDepsMutators(f RegisterMutatorFunc) {
247 PreDepsMutators(f)
248}
249
250func (ctx *initRegistrationContext) PostDepsMutators(f RegisterMutatorFunc) {
251 PostDepsMutators(f)
252}
Martin Stjernholm710ec3a2020-01-16 15:12:04 +0000253
254func (ctx *initRegistrationContext) FinalDepsMutators(f RegisterMutatorFunc) {
255 FinalDepsMutators(f)
256}