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