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