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