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