register.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  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. package android
  15. import (
  16. "fmt"
  17. "reflect"
  18. "github.com/google/blueprint"
  19. )
  20. // A sortable component is one whose registration order affects the order in which it is executed
  21. // and so affects the behavior of the build system. As a result it is important for the order in
  22. // which they are registered during tests to match the order used at runtime and so the test
  23. // infrastructure will sort them to match.
  24. //
  25. // The sortable components are mutators, singletons and pre-singletons. Module types are not
  26. // sortable because their order of registration does not affect the runtime behavior.
  27. type sortableComponent interface {
  28. // componentName returns the name of the component.
  29. //
  30. // Uniquely identifies the components within the set of components used at runtime and during
  31. // tests.
  32. componentName() string
  33. // register registers this component in the supplied context.
  34. register(ctx *Context)
  35. }
  36. type sortableComponents []sortableComponent
  37. // registerAll registers all components in this slice with the supplied context.
  38. func (r sortableComponents) registerAll(ctx *Context) {
  39. for _, c := range r {
  40. c.register(ctx)
  41. }
  42. }
  43. type moduleType struct {
  44. name string
  45. factory ModuleFactory
  46. }
  47. func (t moduleType) register(ctx *Context) {
  48. ctx.RegisterModuleType(t.name, ModuleFactoryAdaptor(t.factory))
  49. }
  50. var moduleTypes []moduleType
  51. var moduleTypesForDocs = map[string]reflect.Value{}
  52. var moduleTypeByFactory = map[reflect.Value]string{}
  53. type singleton struct {
  54. // True if this should be registered as a pre-singleton, false otherwise.
  55. pre bool
  56. name string
  57. factory SingletonFactory
  58. }
  59. func newSingleton(name string, factory SingletonFactory) singleton {
  60. return singleton{false, name, factory}
  61. }
  62. func newPreSingleton(name string, factory SingletonFactory) singleton {
  63. return singleton{true, name, factory}
  64. }
  65. func (s singleton) componentName() string {
  66. return s.name
  67. }
  68. func (s singleton) register(ctx *Context) {
  69. adaptor := SingletonFactoryAdaptor(ctx, s.factory)
  70. if s.pre {
  71. ctx.RegisterPreSingletonType(s.name, adaptor)
  72. } else {
  73. ctx.RegisterSingletonType(s.name, adaptor)
  74. }
  75. }
  76. var _ sortableComponent = singleton{}
  77. var singletons sortableComponents
  78. var preSingletons sortableComponents
  79. type mutator struct {
  80. name string
  81. bottomUpMutator blueprint.BottomUpMutator
  82. topDownMutator blueprint.TopDownMutator
  83. transitionMutator blueprint.TransitionMutator
  84. parallel bool
  85. }
  86. var _ sortableComponent = &mutator{}
  87. type ModuleFactory func() Module
  88. // ModuleFactoryAdaptor wraps a ModuleFactory into a blueprint.ModuleFactory by converting a Module
  89. // into a blueprint.Module and a list of property structs
  90. func ModuleFactoryAdaptor(factory ModuleFactory) blueprint.ModuleFactory {
  91. return func() (blueprint.Module, []interface{}) {
  92. module := factory()
  93. return module, module.GetProperties()
  94. }
  95. }
  96. type SingletonFactory func() Singleton
  97. // SingletonFactoryAdaptor wraps a SingletonFactory into a blueprint.SingletonFactory by converting
  98. // a Singleton into a blueprint.Singleton
  99. func SingletonFactoryAdaptor(ctx *Context, factory SingletonFactory) blueprint.SingletonFactory {
  100. return func() blueprint.Singleton {
  101. singleton := factory()
  102. if makevars, ok := singleton.(SingletonMakeVarsProvider); ok {
  103. registerSingletonMakeVarsProvider(ctx.config, makevars)
  104. }
  105. return &singletonAdaptor{Singleton: singleton}
  106. }
  107. }
  108. func RegisterModuleType(name string, factory ModuleFactory) {
  109. moduleTypes = append(moduleTypes, moduleType{name, factory})
  110. RegisterModuleTypeForDocs(name, reflect.ValueOf(factory))
  111. }
  112. // RegisterModuleTypeForDocs associates a module type name with a reflect.Value of the factory
  113. // function that has documentation for the module type. It is normally called automatically
  114. // by RegisterModuleType, but can be called manually after RegisterModuleType in order to
  115. // override the factory method used for documentation, for example if the method passed to
  116. // RegisterModuleType was a lambda.
  117. func RegisterModuleTypeForDocs(name string, factory reflect.Value) {
  118. moduleTypesForDocs[name] = factory
  119. moduleTypeByFactory[factory] = name
  120. }
  121. func RegisterSingletonType(name string, factory SingletonFactory) {
  122. singletons = append(singletons, newSingleton(name, factory))
  123. }
  124. func RegisterPreSingletonType(name string, factory SingletonFactory) {
  125. preSingletons = append(preSingletons, newPreSingleton(name, factory))
  126. }
  127. type Context struct {
  128. *blueprint.Context
  129. config Config
  130. }
  131. func NewContext(config Config) *Context {
  132. ctx := &Context{blueprint.NewContext(), config}
  133. ctx.SetSrcDir(absSrcDir)
  134. return ctx
  135. }
  136. func (ctx *Context) SetRunningAsBp2build() {
  137. ctx.config.runningAsBp2Build = true
  138. }
  139. // RegisterForBazelConversion registers an alternate shadow pipeline of
  140. // singletons, module types and mutators to register for converting Blueprint
  141. // files to semantically equivalent BUILD files.
  142. func (ctx *Context) RegisterForBazelConversion() {
  143. for _, t := range moduleTypes {
  144. t.register(ctx)
  145. }
  146. // Required for SingletonModule types, even though we are not using them.
  147. for _, t := range singletons {
  148. t.register(ctx)
  149. }
  150. RegisterMutatorsForBazelConversion(ctx, bp2buildPreArchMutators)
  151. }
  152. // Register the pipeline of singletons, module types, and mutators for
  153. // generating build.ninja and other files for Kati, from Android.bp files.
  154. func (ctx *Context) Register() {
  155. preSingletons.registerAll(ctx)
  156. for _, t := range moduleTypes {
  157. t.register(ctx)
  158. }
  159. mutators := collateGloballyRegisteredMutators()
  160. mutators.registerAll(ctx)
  161. singletons := collateGloballyRegisteredSingletons()
  162. singletons.registerAll(ctx)
  163. }
  164. func collateGloballyRegisteredSingletons() sortableComponents {
  165. allSingletons := append(sortableComponents(nil), singletons...)
  166. allSingletons = append(allSingletons,
  167. singleton{false, "bazeldeps", BazelSingleton},
  168. // Register phony just before makevars so it can write out its phony rules as Make rules
  169. singleton{false, "phony", phonySingletonFactory},
  170. // Register makevars after other singletons so they can export values through makevars
  171. singleton{false, "makevars", makeVarsSingletonFunc},
  172. // Register env and ninjadeps last so that they can track all used environment variables and
  173. // Ninja file dependencies stored in the config.
  174. singleton{false, "ninjadeps", ninjaDepsSingletonFactory},
  175. )
  176. return allSingletons
  177. }
  178. func ModuleTypeFactories() map[string]ModuleFactory {
  179. ret := make(map[string]ModuleFactory)
  180. for _, t := range moduleTypes {
  181. ret[t.name] = t.factory
  182. }
  183. return ret
  184. }
  185. func ModuleTypeFactoriesForDocs() map[string]reflect.Value {
  186. return moduleTypesForDocs
  187. }
  188. func ModuleTypeByFactory() map[reflect.Value]string {
  189. return moduleTypeByFactory
  190. }
  191. // Interface for registering build components.
  192. //
  193. // Provided to allow registration of build components to be shared between the runtime
  194. // and test environments.
  195. type RegistrationContext interface {
  196. RegisterModuleType(name string, factory ModuleFactory)
  197. RegisterSingletonModuleType(name string, factory SingletonModuleFactory)
  198. RegisterPreSingletonType(name string, factory SingletonFactory)
  199. RegisterSingletonType(name string, factory SingletonFactory)
  200. PreArchMutators(f RegisterMutatorFunc)
  201. // Register pre arch mutators that are hard coded into mutator.go.
  202. //
  203. // Only registers mutators for testing, is a noop on the InitRegistrationContext.
  204. HardCodedPreArchMutators(f RegisterMutatorFunc)
  205. PreDepsMutators(f RegisterMutatorFunc)
  206. PostDepsMutators(f RegisterMutatorFunc)
  207. FinalDepsMutators(f RegisterMutatorFunc)
  208. }
  209. // Used to register build components from an init() method, e.g.
  210. //
  211. // init() {
  212. // RegisterBuildComponents(android.InitRegistrationContext)
  213. // }
  214. //
  215. // func RegisterBuildComponents(ctx android.RegistrationContext) {
  216. // ctx.RegisterModuleType(...)
  217. // ...
  218. // }
  219. //
  220. // Extracting the actual registration into a separate RegisterBuildComponents(ctx) function
  221. // allows it to be used to initialize test context, e.g.
  222. //
  223. // ctx := android.NewTestContext(config)
  224. // RegisterBuildComponents(ctx)
  225. var InitRegistrationContext RegistrationContext = &initRegistrationContext{
  226. moduleTypes: make(map[string]ModuleFactory),
  227. singletonTypes: make(map[string]SingletonFactory),
  228. preSingletonTypes: make(map[string]SingletonFactory),
  229. }
  230. // Make sure the TestContext implements RegistrationContext.
  231. var _ RegistrationContext = (*TestContext)(nil)
  232. type initRegistrationContext struct {
  233. moduleTypes map[string]ModuleFactory
  234. singletonTypes map[string]SingletonFactory
  235. preSingletonTypes map[string]SingletonFactory
  236. moduleTypesForDocs map[string]reflect.Value
  237. }
  238. func (ctx *initRegistrationContext) RegisterModuleType(name string, factory ModuleFactory) {
  239. if _, present := ctx.moduleTypes[name]; present {
  240. panic(fmt.Sprintf("module type %q is already registered", name))
  241. }
  242. ctx.moduleTypes[name] = factory
  243. RegisterModuleType(name, factory)
  244. RegisterModuleTypeForDocs(name, reflect.ValueOf(factory))
  245. }
  246. func (ctx *initRegistrationContext) RegisterSingletonModuleType(name string, factory SingletonModuleFactory) {
  247. s, m := SingletonModuleFactoryAdaptor(name, factory)
  248. ctx.RegisterSingletonType(name, s)
  249. ctx.RegisterModuleType(name, m)
  250. // Overwrite moduleTypesForDocs with the original factory instead of the lambda returned by
  251. // SingletonModuleFactoryAdaptor so that docs can find the module type documentation on the
  252. // factory method.
  253. RegisterModuleTypeForDocs(name, reflect.ValueOf(factory))
  254. }
  255. func (ctx *initRegistrationContext) RegisterSingletonType(name string, factory SingletonFactory) {
  256. if _, present := ctx.singletonTypes[name]; present {
  257. panic(fmt.Sprintf("singleton type %q is already registered", name))
  258. }
  259. ctx.singletonTypes[name] = factory
  260. RegisterSingletonType(name, factory)
  261. }
  262. func (ctx *initRegistrationContext) RegisterPreSingletonType(name string, factory SingletonFactory) {
  263. if _, present := ctx.preSingletonTypes[name]; present {
  264. panic(fmt.Sprintf("pre singleton type %q is already registered", name))
  265. }
  266. ctx.preSingletonTypes[name] = factory
  267. RegisterPreSingletonType(name, factory)
  268. }
  269. func (ctx *initRegistrationContext) PreArchMutators(f RegisterMutatorFunc) {
  270. PreArchMutators(f)
  271. }
  272. func (ctx *initRegistrationContext) HardCodedPreArchMutators(f RegisterMutatorFunc) {
  273. // Nothing to do as the mutators are hard code in preArch in mutator.go
  274. }
  275. func (ctx *initRegistrationContext) PreDepsMutators(f RegisterMutatorFunc) {
  276. PreDepsMutators(f)
  277. }
  278. func (ctx *initRegistrationContext) PostDepsMutators(f RegisterMutatorFunc) {
  279. PostDepsMutators(f)
  280. }
  281. func (ctx *initRegistrationContext) FinalDepsMutators(f RegisterMutatorFunc) {
  282. FinalDepsMutators(f)
  283. }