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