| // Copyright 2015 Google Inc. All rights reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| package android |
| |
| import ( |
| "fmt" |
| |
| "github.com/google/blueprint" |
| ) |
| |
| type moduleType struct { |
| name string |
| factory ModuleFactory |
| } |
| |
| var moduleTypes []moduleType |
| |
| type singleton struct { |
| name string |
| factory blueprint.SingletonFactory |
| } |
| |
| var singletons []singleton |
| var preSingletons []singleton |
| |
| type mutator struct { |
| name string |
| bottomUpMutator blueprint.BottomUpMutator |
| topDownMutator blueprint.TopDownMutator |
| parallel bool |
| } |
| |
| type ModuleFactory func() Module |
| |
| // ModuleFactoryAdaptor wraps a ModuleFactory into a blueprint.ModuleFactory by converting a Module |
| // into a blueprint.Module and a list of property structs |
| func ModuleFactoryAdaptor(factory ModuleFactory) blueprint.ModuleFactory { |
| return func() (blueprint.Module, []interface{}) { |
| module := factory() |
| return module, module.GetProperties() |
| } |
| } |
| |
| type SingletonFactory func() Singleton |
| |
| // SingletonFactoryAdaptor wraps a SingletonFactory into a blueprint.SingletonFactory by converting |
| // a Singleton into a blueprint.Singleton |
| func SingletonFactoryAdaptor(factory SingletonFactory) blueprint.SingletonFactory { |
| return func() blueprint.Singleton { |
| singleton := factory() |
| if makevars, ok := singleton.(SingletonMakeVarsProvider); ok { |
| registerSingletonMakeVarsProvider(makevars) |
| } |
| return &singletonAdaptor{Singleton: singleton} |
| } |
| } |
| |
| func RegisterModuleType(name string, factory ModuleFactory) { |
| moduleTypes = append(moduleTypes, moduleType{name, factory}) |
| } |
| |
| func RegisterSingletonType(name string, factory SingletonFactory) { |
| singletons = append(singletons, singleton{name, SingletonFactoryAdaptor(factory)}) |
| } |
| |
| func RegisterPreSingletonType(name string, factory SingletonFactory) { |
| preSingletons = append(preSingletons, singleton{name, SingletonFactoryAdaptor(factory)}) |
| } |
| |
| type Context struct { |
| *blueprint.Context |
| config Config |
| } |
| |
| func NewContext(config Config) *Context { |
| ctx := &Context{blueprint.NewContext(), config} |
| ctx.SetSrcDir(absSrcDir) |
| return ctx |
| } |
| |
| func (ctx *Context) Register() { |
| for _, t := range preSingletons { |
| ctx.RegisterPreSingletonType(t.name, t.factory) |
| } |
| |
| for _, t := range moduleTypes { |
| ctx.RegisterModuleType(t.name, ModuleFactoryAdaptor(t.factory)) |
| } |
| |
| for _, t := range singletons { |
| ctx.RegisterSingletonType(t.name, t.factory) |
| } |
| |
| registerMutators(ctx.Context, preArch, preDeps, postDeps, finalDeps) |
| |
| ctx.RegisterSingletonType("bazeldeps", SingletonFactoryAdaptor(BazelSingleton)) |
| |
| // Register phony just before makevars so it can write out its phony rules as Make rules |
| ctx.RegisterSingletonType("phony", SingletonFactoryAdaptor(phonySingletonFactory)) |
| |
| // Register makevars after other singletons so they can export values through makevars |
| ctx.RegisterSingletonType("makevars", SingletonFactoryAdaptor(makeVarsSingletonFunc)) |
| |
| // Register env last so that it can track all used environment variables |
| ctx.RegisterSingletonType("env", SingletonFactoryAdaptor(EnvSingleton)) |
| } |
| |
| func ModuleTypeFactories() map[string]ModuleFactory { |
| ret := make(map[string]ModuleFactory) |
| for _, t := range moduleTypes { |
| ret[t.name] = t.factory |
| } |
| return ret |
| } |
| |
| // Interface for registering build components. |
| // |
| // Provided to allow registration of build components to be shared between the runtime |
| // and test environments. |
| type RegistrationContext interface { |
| RegisterModuleType(name string, factory ModuleFactory) |
| RegisterSingletonType(name string, factory SingletonFactory) |
| PreArchMutators(f RegisterMutatorFunc) |
| |
| // Register pre arch mutators that are hard coded into mutator.go. |
| // |
| // Only registers mutators for testing, is a noop on the InitRegistrationContext. |
| HardCodedPreArchMutators(f RegisterMutatorFunc) |
| |
| PreDepsMutators(f RegisterMutatorFunc) |
| PostDepsMutators(f RegisterMutatorFunc) |
| FinalDepsMutators(f RegisterMutatorFunc) |
| } |
| |
| // Used to register build components from an init() method, e.g. |
| // |
| // init() { |
| // RegisterBuildComponents(android.InitRegistrationContext) |
| // } |
| // |
| // func RegisterBuildComponents(ctx android.RegistrationContext) { |
| // ctx.RegisterModuleType(...) |
| // ... |
| // } |
| // |
| // Extracting the actual registration into a separate RegisterBuildComponents(ctx) function |
| // allows it to be used to initialize test context, e.g. |
| // |
| // ctx := android.NewTestContext(config) |
| // RegisterBuildComponents(ctx) |
| var InitRegistrationContext RegistrationContext = &initRegistrationContext{ |
| moduleTypes: make(map[string]ModuleFactory), |
| singletonTypes: make(map[string]SingletonFactory), |
| } |
| |
| // Make sure the TestContext implements RegistrationContext. |
| var _ RegistrationContext = (*TestContext)(nil) |
| |
| type initRegistrationContext struct { |
| moduleTypes map[string]ModuleFactory |
| singletonTypes map[string]SingletonFactory |
| } |
| |
| func (ctx *initRegistrationContext) RegisterModuleType(name string, factory ModuleFactory) { |
| if _, present := ctx.moduleTypes[name]; present { |
| panic(fmt.Sprintf("module type %q is already registered", name)) |
| } |
| ctx.moduleTypes[name] = factory |
| RegisterModuleType(name, factory) |
| } |
| |
| func (ctx *initRegistrationContext) RegisterSingletonType(name string, factory SingletonFactory) { |
| if _, present := ctx.singletonTypes[name]; present { |
| panic(fmt.Sprintf("singleton type %q is already registered", name)) |
| } |
| ctx.singletonTypes[name] = factory |
| RegisterSingletonType(name, factory) |
| } |
| |
| func (ctx *initRegistrationContext) PreArchMutators(f RegisterMutatorFunc) { |
| PreArchMutators(f) |
| } |
| |
| func (ctx *initRegistrationContext) HardCodedPreArchMutators(f RegisterMutatorFunc) { |
| // Nothing to do as the mutators are hard code in preArch in mutator.go |
| } |
| |
| func (ctx *initRegistrationContext) PreDepsMutators(f RegisterMutatorFunc) { |
| PreDepsMutators(f) |
| } |
| |
| func (ctx *initRegistrationContext) PostDepsMutators(f RegisterMutatorFunc) { |
| PostDepsMutators(f) |
| } |
| |
| func (ctx *initRegistrationContext) FinalDepsMutators(f RegisterMutatorFunc) { |
| FinalDepsMutators(f) |
| } |