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