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 20 "github.com/google/blueprint" 21) 22 23type moduleType struct { 24 name string 25 factory ModuleFactory 26} 27 28var moduleTypes []moduleType 29 30type singleton struct { 31 name string 32 factory blueprint.SingletonFactory 33} 34 35var singletons []singleton 36var preSingletons []singleton 37 38type mutator struct { 39 name string 40 bottomUpMutator blueprint.BottomUpMutator 41 topDownMutator blueprint.TopDownMutator 42 parallel bool 43} 44 45type ModuleFactory func() Module 46 47// ModuleFactoryAdaptor wraps a ModuleFactory into a blueprint.ModuleFactory by converting a Module 48// into a blueprint.Module and a list of property structs 49func ModuleFactoryAdaptor(factory ModuleFactory) blueprint.ModuleFactory { 50 return func() (blueprint.Module, []interface{}) { 51 module := factory() 52 return module, module.GetProperties() 53 } 54} 55 56type SingletonFactory func() Singleton 57 58// SingletonFactoryAdaptor wraps a SingletonFactory into a blueprint.SingletonFactory by converting 59// a Singleton into a blueprint.Singleton 60func SingletonFactoryAdaptor(factory SingletonFactory) blueprint.SingletonFactory { 61 return func() blueprint.Singleton { 62 singleton := factory() 63 if makevars, ok := singleton.(SingletonMakeVarsProvider); ok { 64 registerSingletonMakeVarsProvider(makevars) 65 } 66 return &singletonAdaptor{Singleton: singleton} 67 } 68} 69 70func RegisterModuleType(name string, factory ModuleFactory) { 71 moduleTypes = append(moduleTypes, moduleType{name, factory}) 72} 73 74func RegisterSingletonType(name string, factory SingletonFactory) { 75 singletons = append(singletons, singleton{name, SingletonFactoryAdaptor(factory)}) 76} 77 78func RegisterPreSingletonType(name string, factory SingletonFactory) { 79 preSingletons = append(preSingletons, singleton{name, SingletonFactoryAdaptor(factory)}) 80} 81 82type Context struct { 83 *blueprint.Context 84} 85 86func NewContext() *Context { 87 ctx := &Context{blueprint.NewContext()} 88 ctx.SetSrcDir(absSrcDir) 89 return ctx 90} 91 92func (ctx *Context) Register() { 93 for _, t := range preSingletons { 94 ctx.RegisterPreSingletonType(t.name, t.factory) 95 } 96 97 for _, t := range moduleTypes { 98 ctx.RegisterModuleType(t.name, ModuleFactoryAdaptor(t.factory)) 99 } 100 101 for _, t := range singletons { 102 ctx.RegisterSingletonType(t.name, t.factory) 103 } 104 105 registerMutators(ctx.Context, preArch, preDeps, postDeps, finalDeps) 106 107 // Register phony just before makevars so it can write out its phony rules as Make rules 108 ctx.RegisterSingletonType("phony", SingletonFactoryAdaptor(phonySingletonFactory)) 109 110 // Register makevars after other singletons so they can export values through makevars 111 ctx.RegisterSingletonType("makevars", SingletonFactoryAdaptor(makeVarsSingletonFunc)) 112 113 // Register env last so that it can track all used environment variables 114 ctx.RegisterSingletonType("env", SingletonFactoryAdaptor(EnvSingleton)) 115} 116 117func ModuleTypeFactories() map[string]ModuleFactory { 118 ret := make(map[string]ModuleFactory) 119 for _, t := range moduleTypes { 120 ret[t.name] = t.factory 121 } 122 return ret 123} 124 125// Interface for registering build components. 126// 127// Provided to allow registration of build components to be shared between the runtime 128// and test environments. 129type RegistrationContext interface { 130 RegisterModuleType(name string, factory ModuleFactory) 131 RegisterSingletonType(name string, factory SingletonFactory) 132 PreArchMutators(f RegisterMutatorFunc) 133 134 // Register pre arch mutators that are hard coded into mutator.go. 135 // 136 // Only registers mutators for testing, is a noop on the InitRegistrationContext. 137 HardCodedPreArchMutators(f RegisterMutatorFunc) 138 139 PreDepsMutators(f RegisterMutatorFunc) 140 PostDepsMutators(f RegisterMutatorFunc) 141 FinalDepsMutators(f RegisterMutatorFunc) 142} 143 144// Used to register build components from an init() method, e.g. 145// 146// init() { 147// RegisterBuildComponents(android.InitRegistrationContext) 148// } 149// 150// func RegisterBuildComponents(ctx android.RegistrationContext) { 151// ctx.RegisterModuleType(...) 152// ... 153// } 154// 155// Extracting the actual registration into a separate RegisterBuildComponents(ctx) function 156// allows it to be used to initialize test context, e.g. 157// 158// ctx := android.NewTestContext() 159// RegisterBuildComponents(ctx) 160var InitRegistrationContext RegistrationContext = &initRegistrationContext{ 161 moduleTypes: make(map[string]ModuleFactory), 162 singletonTypes: make(map[string]SingletonFactory), 163} 164 165// Make sure the TestContext implements RegistrationContext. 166var _ RegistrationContext = (*TestContext)(nil) 167 168type initRegistrationContext struct { 169 moduleTypes map[string]ModuleFactory 170 singletonTypes map[string]SingletonFactory 171} 172 173func (ctx *initRegistrationContext) RegisterModuleType(name string, factory ModuleFactory) { 174 if _, present := ctx.moduleTypes[name]; present { 175 panic(fmt.Sprintf("module type %q is already registered", name)) 176 } 177 ctx.moduleTypes[name] = factory 178 RegisterModuleType(name, factory) 179} 180 181func (ctx *initRegistrationContext) RegisterSingletonType(name string, factory SingletonFactory) { 182 if _, present := ctx.singletonTypes[name]; present { 183 panic(fmt.Sprintf("singleton type %q is already registered", name)) 184 } 185 ctx.singletonTypes[name] = factory 186 RegisterSingletonType(name, factory) 187} 188 189func (ctx *initRegistrationContext) PreArchMutators(f RegisterMutatorFunc) { 190 PreArchMutators(f) 191} 192 193func (ctx *initRegistrationContext) HardCodedPreArchMutators(f RegisterMutatorFunc) { 194 // Nothing to do as the mutators are hard code in preArch in mutator.go 195} 196 197func (ctx *initRegistrationContext) PreDepsMutators(f RegisterMutatorFunc) { 198 PreDepsMutators(f) 199} 200 201func (ctx *initRegistrationContext) PostDepsMutators(f RegisterMutatorFunc) { 202 PostDepsMutators(f) 203} 204 205func (ctx *initRegistrationContext) FinalDepsMutators(f RegisterMutatorFunc) { 206 FinalDepsMutators(f) 207} 208