blob: 036a8113fbad4394d98d55a03b8118efdfd0bfd4 [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"
19
Colin Cross4498afc2016-10-13 14:18:27 -070020 "github.com/google/blueprint"
21)
Colin Cross463a90e2015-06-17 14:20:06 -070022
23type moduleType struct {
24 name string
Colin Cross7089c272019-01-25 22:43:35 -080025 factory ModuleFactory
Colin Cross463a90e2015-06-17 14:20:06 -070026}
27
28var moduleTypes []moduleType
29
30type singleton struct {
31 name string
32 factory blueprint.SingletonFactory
33}
34
35var singletons []singleton
Colin Cross5a79c832017-11-07 13:35:38 -080036var preSingletons []singleton
Colin Cross463a90e2015-06-17 14:20:06 -070037
Colin Cross6362e272015-10-29 15:25:03 -070038type mutator struct {
39 name string
40 bottomUpMutator blueprint.BottomUpMutator
41 topDownMutator blueprint.TopDownMutator
Colin Crosse8a67a72016-08-07 21:17:54 -070042 parallel bool
Colin Cross463a90e2015-06-17 14:20:06 -070043}
44
Colin Cross36242852017-06-23 15:06:31 -070045type ModuleFactory func() Module
46
Colin Cross0875c522017-11-28 17:34:01 -080047// ModuleFactoryAdaptor wraps a ModuleFactory into a blueprint.ModuleFactory by converting a Module
Colin Cross36242852017-06-23 15:06:31 -070048// into a blueprint.Module and a list of property structs
49func ModuleFactoryAdaptor(factory ModuleFactory) blueprint.ModuleFactory {
50 return func() (blueprint.Module, []interface{}) {
51 module := factory()
52 return module, module.GetProperties()
53 }
54}
55
Colin Cross0875c522017-11-28 17:34:01 -080056type SingletonFactory func() Singleton
57
58// SingletonFactoryAdaptor wraps a SingletonFactory into a blueprint.SingletonFactory by converting
59// a Singleton into a blueprint.Singleton
60func SingletonFactoryAdaptor(factory SingletonFactory) blueprint.SingletonFactory {
61 return func() blueprint.Singleton {
62 singleton := factory()
Colin Crossed023ec2019-02-19 12:38:45 -080063 if makevars, ok := singleton.(SingletonMakeVarsProvider); ok {
64 registerSingletonMakeVarsProvider(makevars)
65 }
Colin Cross4c83e5c2019-02-25 14:54:28 -080066 return &singletonAdaptor{Singleton: singleton}
Colin Cross0875c522017-11-28 17:34:01 -080067 }
68}
69
Colin Cross36242852017-06-23 15:06:31 -070070func RegisterModuleType(name string, factory ModuleFactory) {
Colin Cross7089c272019-01-25 22:43:35 -080071 moduleTypes = append(moduleTypes, moduleType{name, factory})
Colin Cross463a90e2015-06-17 14:20:06 -070072}
73
Colin Cross0875c522017-11-28 17:34:01 -080074func RegisterSingletonType(name string, factory SingletonFactory) {
75 singletons = append(singletons, singleton{name, SingletonFactoryAdaptor(factory)})
Colin Cross463a90e2015-06-17 14:20:06 -070076}
77
Colin Cross0875c522017-11-28 17:34:01 -080078func RegisterPreSingletonType(name string, factory SingletonFactory) {
79 preSingletons = append(preSingletons, singleton{name, SingletonFactoryAdaptor(factory)})
Colin Cross5a79c832017-11-07 13:35:38 -080080}
81
Colin Crosscec81712017-07-13 14:43:27 -070082type Context struct {
83 *blueprint.Context
84}
Colin Cross463a90e2015-06-17 14:20:06 -070085
Colin Crosscec81712017-07-13 14:43:27 -070086func NewContext() *Context {
Colin Cross988414c2020-01-11 01:11:46 +000087 ctx := &Context{blueprint.NewContext()}
88 ctx.SetSrcDir(absSrcDir)
89 return ctx
Colin Crosscec81712017-07-13 14:43:27 -070090}
91
92func (ctx *Context) Register() {
Colin Cross5a79c832017-11-07 13:35:38 -080093 for _, t := range preSingletons {
94 ctx.RegisterPreSingletonType(t.name, t.factory)
95 }
96
Colin Cross463a90e2015-06-17 14:20:06 -070097 for _, t := range moduleTypes {
Colin Cross7089c272019-01-25 22:43:35 -080098 ctx.RegisterModuleType(t.name, ModuleFactoryAdaptor(t.factory))
Colin Cross463a90e2015-06-17 14:20:06 -070099 }
100
101 for _, t := range singletons {
102 ctx.RegisterSingletonType(t.name, t.factory)
103 }
104
Martin Stjernholm710ec3a2020-01-16 15:12:04 +0000105 registerMutators(ctx.Context, preArch, preDeps, postDeps, finalDeps)
Colin Cross1e676be2016-10-12 14:38:15 -0700106
Colin Crossc3d87d32020-06-04 13:25:17 -0700107 // Register phony just before makevars so it can write out its phony rules as Make rules
108 ctx.RegisterSingletonType("phony", SingletonFactoryAdaptor(phonySingletonFactory))
109
Colin Cross580d2ce2019-02-09 22:59:32 -0800110 // Register makevars after other singletons so they can export values through makevars
111 ctx.RegisterSingletonType("makevars", SingletonFactoryAdaptor(makeVarsSingletonFunc))
112
113 // Register env last so that it can track all used environment variables
Colin Cross54855dd2017-11-28 23:55:23 -0800114 ctx.RegisterSingletonType("env", SingletonFactoryAdaptor(EnvSingleton))
Colin Cross463a90e2015-06-17 14:20:06 -0700115}
Colin Cross7089c272019-01-25 22:43:35 -0800116
117func ModuleTypeFactories() map[string]ModuleFactory {
118 ret := make(map[string]ModuleFactory)
119 for _, t := range moduleTypes {
120 ret[t.name] = t.factory
121 }
122 return ret
123}
Paul Duffinf9b1da02019-12-18 19:51:55 +0000124
125// Interface for registering build components.
126//
127// Provided to allow registration of build components to be shared between the runtime
128// and test environments.
129type RegistrationContext interface {
130 RegisterModuleType(name string, factory ModuleFactory)
131 RegisterSingletonType(name string, factory SingletonFactory)
Paul Duffina48f7582019-12-19 11:25:19 +0000132 PreArchMutators(f RegisterMutatorFunc)
Paul Duffina80ef842020-01-14 12:09:36 +0000133
134 // Register pre arch mutators that are hard coded into mutator.go.
135 //
136 // Only registers mutators for testing, is a noop on the InitRegistrationContext.
137 HardCodedPreArchMutators(f RegisterMutatorFunc)
138
Paul Duffin2ccaffd2019-12-19 15:12:58 +0000139 PreDepsMutators(f RegisterMutatorFunc)
140 PostDepsMutators(f RegisterMutatorFunc)
Martin Stjernholm710ec3a2020-01-16 15:12:04 +0000141 FinalDepsMutators(f RegisterMutatorFunc)
Paul Duffinf9b1da02019-12-18 19:51:55 +0000142}
143
144// Used to register build components from an init() method, e.g.
145//
146// init() {
147// RegisterBuildComponents(android.InitRegistrationContext)
148// }
149//
150// func RegisterBuildComponents(ctx android.RegistrationContext) {
151// ctx.RegisterModuleType(...)
152// ...
153// }
154//
155// Extracting the actual registration into a separate RegisterBuildComponents(ctx) function
156// allows it to be used to initialize test context, e.g.
157//
158// ctx := android.NewTestContext()
159// RegisterBuildComponents(ctx)
Paul Duffin0a286832019-12-19 12:23:01 +0000160var InitRegistrationContext RegistrationContext = &initRegistrationContext{
161 moduleTypes: make(map[string]ModuleFactory),
162 singletonTypes: make(map[string]SingletonFactory),
163}
Paul Duffinf9b1da02019-12-18 19:51:55 +0000164
165// Make sure the TestContext implements RegistrationContext.
166var _ RegistrationContext = (*TestContext)(nil)
167
Paul Duffin0a286832019-12-19 12:23:01 +0000168type initRegistrationContext struct {
169 moduleTypes map[string]ModuleFactory
170 singletonTypes map[string]SingletonFactory
171}
Paul Duffinf9b1da02019-12-18 19:51:55 +0000172
Paul Duffin0a286832019-12-19 12:23:01 +0000173func (ctx *initRegistrationContext) RegisterModuleType(name string, factory ModuleFactory) {
174 if _, present := ctx.moduleTypes[name]; present {
175 panic(fmt.Sprintf("module type %q is already registered", name))
176 }
177 ctx.moduleTypes[name] = factory
Paul Duffinf9b1da02019-12-18 19:51:55 +0000178 RegisterModuleType(name, factory)
179}
180
Paul Duffin0a286832019-12-19 12:23:01 +0000181func (ctx *initRegistrationContext) RegisterSingletonType(name string, factory SingletonFactory) {
182 if _, present := ctx.singletonTypes[name]; present {
183 panic(fmt.Sprintf("singleton type %q is already registered", name))
184 }
185 ctx.singletonTypes[name] = factory
Paul Duffinf9b1da02019-12-18 19:51:55 +0000186 RegisterSingletonType(name, factory)
187}
Paul Duffina48f7582019-12-19 11:25:19 +0000188
Paul Duffin0a286832019-12-19 12:23:01 +0000189func (ctx *initRegistrationContext) PreArchMutators(f RegisterMutatorFunc) {
Paul Duffina48f7582019-12-19 11:25:19 +0000190 PreArchMutators(f)
191}
Paul Duffin2ccaffd2019-12-19 15:12:58 +0000192
Paul Duffina80ef842020-01-14 12:09:36 +0000193func (ctx *initRegistrationContext) HardCodedPreArchMutators(f RegisterMutatorFunc) {
194 // Nothing to do as the mutators are hard code in preArch in mutator.go
195}
196
Paul Duffin2ccaffd2019-12-19 15:12:58 +0000197func (ctx *initRegistrationContext) PreDepsMutators(f RegisterMutatorFunc) {
198 PreDepsMutators(f)
199}
200
201func (ctx *initRegistrationContext) PostDepsMutators(f RegisterMutatorFunc) {
202 PostDepsMutators(f)
203}
Martin Stjernholm710ec3a2020-01-16 15:12:04 +0000204
205func (ctx *initRegistrationContext) FinalDepsMutators(f RegisterMutatorFunc) {
206 FinalDepsMutators(f)
207}