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