prebuilt.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513
  1. // Copyright 2016 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. "strings"
  19. "github.com/google/blueprint"
  20. "github.com/google/blueprint/proptools"
  21. )
  22. // This file implements common functionality for handling modules that may exist as prebuilts,
  23. // source, or both.
  24. func RegisterPrebuiltMutators(ctx RegistrationContext) {
  25. ctx.PreArchMutators(RegisterPrebuiltsPreArchMutators)
  26. ctx.PostDepsMutators(RegisterPrebuiltsPostDepsMutators)
  27. }
  28. // Marks a dependency tag as possibly preventing a reference to a source from being
  29. // replaced with the prebuilt.
  30. type ReplaceSourceWithPrebuilt interface {
  31. blueprint.DependencyTag
  32. // Return true if the dependency defined by this tag should be replaced with the
  33. // prebuilt.
  34. ReplaceSourceWithPrebuilt() bool
  35. }
  36. type prebuiltDependencyTag struct {
  37. blueprint.BaseDependencyTag
  38. }
  39. var PrebuiltDepTag prebuiltDependencyTag
  40. // Mark this tag so dependencies that use it are excluded from visibility enforcement.
  41. func (t prebuiltDependencyTag) ExcludeFromVisibilityEnforcement() {}
  42. // Mark this tag so dependencies that use it are excluded from APEX contents.
  43. func (t prebuiltDependencyTag) ExcludeFromApexContents() {}
  44. var _ ExcludeFromVisibilityEnforcementTag = PrebuiltDepTag
  45. var _ ExcludeFromApexContentsTag = PrebuiltDepTag
  46. // UserSuppliedPrebuiltProperties contains the prebuilt properties that can be specified in an
  47. // Android.bp file.
  48. type UserSuppliedPrebuiltProperties struct {
  49. // When prefer is set to true the prebuilt will be used instead of any source module with
  50. // a matching name.
  51. Prefer *bool `android:"arch_variant"`
  52. // When specified this names a Soong config variable that controls the prefer property.
  53. //
  54. // If the value of the named Soong config variable is true then prefer is set to false and vice
  55. // versa. If the Soong config variable is not set then it defaults to false, so prefer defaults
  56. // to true.
  57. //
  58. // If specified then the prefer property is ignored in favor of the value of the Soong config
  59. // variable.
  60. Use_source_config_var *ConfigVarProperties
  61. }
  62. // CopyUserSuppliedPropertiesFromPrebuilt copies the user supplied prebuilt properties from the
  63. // prebuilt properties.
  64. func (u *UserSuppliedPrebuiltProperties) CopyUserSuppliedPropertiesFromPrebuilt(p *Prebuilt) {
  65. *u = p.properties.UserSuppliedPrebuiltProperties
  66. }
  67. type PrebuiltProperties struct {
  68. UserSuppliedPrebuiltProperties
  69. SourceExists bool `blueprint:"mutated"`
  70. UsePrebuilt bool `blueprint:"mutated"`
  71. // Set if the module has been renamed to remove the "prebuilt_" prefix.
  72. PrebuiltRenamedToSource bool `blueprint:"mutated"`
  73. }
  74. // Properties that can be used to select a Soong config variable.
  75. type ConfigVarProperties struct {
  76. // Allow instances of this struct to be used as a property value in a BpPropertySet.
  77. BpPrintableBase
  78. // The name of the configuration namespace.
  79. //
  80. // As passed to add_soong_config_namespace in Make.
  81. Config_namespace *string
  82. // The name of the configuration variable.
  83. //
  84. // As passed to add_soong_config_var_value in Make.
  85. Var_name *string
  86. }
  87. type Prebuilt struct {
  88. properties PrebuiltProperties
  89. // nil if the prebuilt has no srcs property at all. See InitPrebuiltModuleWithoutSrcs.
  90. srcsSupplier PrebuiltSrcsSupplier
  91. // "-" if the prebuilt has no srcs property at all. See InitPrebuiltModuleWithoutSrcs.
  92. srcsPropertyName string
  93. }
  94. // RemoveOptionalPrebuiltPrefix returns the result of removing the "prebuilt_" prefix from the
  95. // supplied name if it has one, or returns the name unmodified if it does not.
  96. func RemoveOptionalPrebuiltPrefix(name string) string {
  97. return strings.TrimPrefix(name, "prebuilt_")
  98. }
  99. // RemoveOptionalPrebuiltPrefixFromBazelLabel removes the "prebuilt_" prefix from the *target name* of a Bazel label.
  100. // This differs from RemoveOptionalPrebuiltPrefix in that it does not remove it from the start of the string, but
  101. // instead removes it from the target name itself.
  102. func RemoveOptionalPrebuiltPrefixFromBazelLabel(label string) string {
  103. splitLabel := strings.Split(label, ":")
  104. bazelModuleNameNoPrebuilt := RemoveOptionalPrebuiltPrefix(splitLabel[1])
  105. return strings.Join([]string{
  106. splitLabel[0],
  107. bazelModuleNameNoPrebuilt,
  108. }, ":")
  109. }
  110. func (p *Prebuilt) Name(name string) string {
  111. return PrebuiltNameFromSource(name)
  112. }
  113. // PrebuiltNameFromSource returns the result of prepending the "prebuilt_" prefix to the supplied
  114. // name.
  115. func PrebuiltNameFromSource(name string) string {
  116. return "prebuilt_" + name
  117. }
  118. func (p *Prebuilt) ForcePrefer() {
  119. p.properties.Prefer = proptools.BoolPtr(true)
  120. }
  121. func (p *Prebuilt) Prefer() bool {
  122. return proptools.Bool(p.properties.Prefer)
  123. }
  124. // SingleSourcePathFromSupplier invokes the supplied supplier for the current module in the
  125. // supplied context to retrieve a list of file paths, ensures that the returned list of file paths
  126. // contains a single value and then assumes that is a module relative file path and converts it to
  127. // a Path accordingly.
  128. //
  129. // Any issues, such as nil supplier or not exactly one file path will be reported as errors on the
  130. // supplied context and this will return nil.
  131. func SingleSourcePathFromSupplier(ctx ModuleContext, srcsSupplier PrebuiltSrcsSupplier, srcsPropertyName string) Path {
  132. if srcsSupplier != nil {
  133. srcs := srcsSupplier(ctx, ctx.Module())
  134. if len(srcs) == 0 {
  135. ctx.PropertyErrorf(srcsPropertyName, "missing prebuilt source file")
  136. return nil
  137. }
  138. if len(srcs) > 1 {
  139. ctx.PropertyErrorf(srcsPropertyName, "multiple prebuilt source files")
  140. return nil
  141. }
  142. // Return the singleton source after expanding any filegroup in the
  143. // sources.
  144. src := srcs[0]
  145. return PathForModuleSrc(ctx, src)
  146. } else {
  147. ctx.ModuleErrorf("prebuilt source was not set")
  148. return nil
  149. }
  150. }
  151. // The below source-related functions and the srcs, src fields are based on an assumption that
  152. // prebuilt modules have a static source property at the moment. Currently there is only one
  153. // exception, android_app_import, which chooses a source file depending on the product's DPI
  154. // preference configs. We'll want to add native support for dynamic source cases if we end up having
  155. // more modules like this.
  156. func (p *Prebuilt) SingleSourcePath(ctx ModuleContext) Path {
  157. return SingleSourcePathFromSupplier(ctx, p.srcsSupplier, p.srcsPropertyName)
  158. }
  159. func (p *Prebuilt) UsePrebuilt() bool {
  160. return p.properties.UsePrebuilt
  161. }
  162. // Called to provide the srcs value for the prebuilt module.
  163. //
  164. // This can be called with a context for any module not just the prebuilt one itself. It can also be
  165. // called concurrently.
  166. //
  167. // Return the src value or nil if it is not available.
  168. type PrebuiltSrcsSupplier func(ctx BaseModuleContext, prebuilt Module) []string
  169. func initPrebuiltModuleCommon(module PrebuiltInterface) *Prebuilt {
  170. p := module.Prebuilt()
  171. module.AddProperties(&p.properties)
  172. return p
  173. }
  174. // Initialize the module as a prebuilt module that has no dedicated property that lists its
  175. // sources. SingleSourcePathFromSupplier should not be called for this module.
  176. //
  177. // This is the case e.g. for header modules, which provides the headers in source form
  178. // regardless whether they are prebuilt or not.
  179. func InitPrebuiltModuleWithoutSrcs(module PrebuiltInterface) {
  180. p := initPrebuiltModuleCommon(module)
  181. p.srcsPropertyName = "-"
  182. }
  183. // Initialize the module as a prebuilt module that uses the provided supplier to access the
  184. // prebuilt sources of the module.
  185. //
  186. // The supplier will be called multiple times and must return the same values each time it
  187. // is called. If it returns an empty array (or nil) then the prebuilt module will not be used
  188. // as a replacement for a source module with the same name even if prefer = true.
  189. //
  190. // If the Prebuilt.SingleSourcePath() is called on the module then this must return an array
  191. // containing exactly one source file.
  192. //
  193. // The provided property name is used to provide helpful error messages in the event that
  194. // a problem arises, e.g. calling SingleSourcePath() when more than one source is provided.
  195. func InitPrebuiltModuleWithSrcSupplier(module PrebuiltInterface, srcsSupplier PrebuiltSrcsSupplier, srcsPropertyName string) {
  196. if srcsSupplier == nil {
  197. panic(fmt.Errorf("srcsSupplier must not be nil"))
  198. }
  199. if srcsPropertyName == "" {
  200. panic(fmt.Errorf("srcsPropertyName must not be empty"))
  201. }
  202. p := initPrebuiltModuleCommon(module)
  203. p.srcsSupplier = srcsSupplier
  204. p.srcsPropertyName = srcsPropertyName
  205. }
  206. func InitPrebuiltModule(module PrebuiltInterface, srcs *[]string) {
  207. if srcs == nil {
  208. panic(fmt.Errorf("srcs must not be nil"))
  209. }
  210. srcsSupplier := func(ctx BaseModuleContext, _ Module) []string {
  211. return *srcs
  212. }
  213. InitPrebuiltModuleWithSrcSupplier(module, srcsSupplier, "srcs")
  214. }
  215. func InitSingleSourcePrebuiltModule(module PrebuiltInterface, srcProps interface{}, srcField string) {
  216. srcPropsValue := reflect.ValueOf(srcProps).Elem()
  217. srcStructField, _ := srcPropsValue.Type().FieldByName(srcField)
  218. if !srcPropsValue.IsValid() || srcStructField.Name == "" {
  219. panic(fmt.Errorf("invalid single source prebuilt %+v", module))
  220. }
  221. if srcPropsValue.Kind() != reflect.Struct && srcPropsValue.Kind() != reflect.Interface {
  222. panic(fmt.Errorf("invalid single source prebuilt %+v", srcProps))
  223. }
  224. srcFieldIndex := srcStructField.Index
  225. srcPropertyName := proptools.PropertyNameForField(srcField)
  226. srcsSupplier := func(ctx BaseModuleContext, _ Module) []string {
  227. if !module.Enabled() {
  228. return nil
  229. }
  230. value := srcPropsValue.FieldByIndex(srcFieldIndex)
  231. if value.Kind() == reflect.Ptr {
  232. value = value.Elem()
  233. }
  234. if value.Kind() != reflect.String {
  235. panic(fmt.Errorf("prebuilt src field %q in %T in module %s should be a string or a pointer to one but was %v", srcField, srcProps, module, value))
  236. }
  237. src := value.String()
  238. if src == "" {
  239. return nil
  240. }
  241. return []string{src}
  242. }
  243. InitPrebuiltModuleWithSrcSupplier(module, srcsSupplier, srcPropertyName)
  244. }
  245. type PrebuiltInterface interface {
  246. Module
  247. Prebuilt() *Prebuilt
  248. }
  249. // IsModulePreferred returns true if the given module is preferred.
  250. //
  251. // A source module is preferred if there is no corresponding prebuilt module or the prebuilt module
  252. // does not have "prefer: true".
  253. //
  254. // A prebuilt module is preferred if there is no corresponding source module or the prebuilt module
  255. // has "prefer: true".
  256. func IsModulePreferred(module Module) bool {
  257. if module.IsReplacedByPrebuilt() {
  258. // A source module that has been replaced by a prebuilt counterpart.
  259. return false
  260. }
  261. if p := GetEmbeddedPrebuilt(module); p != nil {
  262. return p.UsePrebuilt()
  263. }
  264. return true
  265. }
  266. // IsModulePrebuilt returns true if the module implements PrebuiltInterface and
  267. // has been initialized as a prebuilt and so returns a non-nil value from the
  268. // PrebuiltInterface.Prebuilt() method.
  269. func IsModulePrebuilt(module Module) bool {
  270. return GetEmbeddedPrebuilt(module) != nil
  271. }
  272. // GetEmbeddedPrebuilt returns a pointer to the embedded Prebuilt structure or
  273. // nil if the module does not implement PrebuiltInterface or has not been
  274. // initialized as a prebuilt module.
  275. func GetEmbeddedPrebuilt(module Module) *Prebuilt {
  276. if p, ok := module.(PrebuiltInterface); ok {
  277. return p.Prebuilt()
  278. }
  279. return nil
  280. }
  281. // PrebuiltGetPreferred returns the module that is preferred for the given
  282. // module. That is either the module itself or the prebuilt counterpart that has
  283. // taken its place. The given module must be a direct dependency of the current
  284. // context module, and it must be the source module if both source and prebuilt
  285. // exist.
  286. //
  287. // This function is for use on dependencies after PrebuiltPostDepsMutator has
  288. // run - any dependency that is registered before that will already reference
  289. // the right module. This function is only safe to call after all mutators that
  290. // may call CreateVariations, e.g. in GenerateAndroidBuildActions.
  291. func PrebuiltGetPreferred(ctx BaseModuleContext, module Module) Module {
  292. if !module.IsReplacedByPrebuilt() {
  293. return module
  294. }
  295. if IsModulePrebuilt(module) {
  296. // If we're given a prebuilt then assume there's no source module around.
  297. return module
  298. }
  299. sourceModDepFound := false
  300. var prebuiltMod Module
  301. ctx.WalkDeps(func(child, parent Module) bool {
  302. if prebuiltMod != nil {
  303. return false
  304. }
  305. if parent == ctx.Module() {
  306. // First level: Only recurse if the module is found as a direct dependency.
  307. sourceModDepFound = child == module
  308. return sourceModDepFound
  309. }
  310. // Second level: Follow PrebuiltDepTag to the prebuilt.
  311. if t := ctx.OtherModuleDependencyTag(child); t == PrebuiltDepTag {
  312. prebuiltMod = child
  313. }
  314. return false
  315. })
  316. if prebuiltMod == nil {
  317. if !sourceModDepFound {
  318. panic(fmt.Errorf("Failed to find source module as a direct dependency: %s", module))
  319. } else {
  320. panic(fmt.Errorf("Failed to find prebuilt for source module: %s", module))
  321. }
  322. }
  323. return prebuiltMod
  324. }
  325. func RegisterPrebuiltsPreArchMutators(ctx RegisterMutatorsContext) {
  326. ctx.BottomUp("prebuilt_rename", PrebuiltRenameMutator).Parallel()
  327. }
  328. func RegisterPrebuiltsPostDepsMutators(ctx RegisterMutatorsContext) {
  329. ctx.BottomUp("prebuilt_source", PrebuiltSourceDepsMutator).Parallel()
  330. ctx.TopDown("prebuilt_select", PrebuiltSelectModuleMutator).Parallel()
  331. ctx.BottomUp("prebuilt_postdeps", PrebuiltPostDepsMutator).Parallel()
  332. }
  333. // PrebuiltRenameMutator ensures that there always is a module with an
  334. // undecorated name.
  335. func PrebuiltRenameMutator(ctx BottomUpMutatorContext) {
  336. m := ctx.Module()
  337. if p := GetEmbeddedPrebuilt(m); p != nil {
  338. name := m.base().BaseModuleName()
  339. if !ctx.OtherModuleExists(name) {
  340. ctx.Rename(name)
  341. p.properties.PrebuiltRenamedToSource = true
  342. }
  343. }
  344. }
  345. // PrebuiltSourceDepsMutator adds dependencies to the prebuilt module from the
  346. // corresponding source module, if one exists for the same variant.
  347. func PrebuiltSourceDepsMutator(ctx BottomUpMutatorContext) {
  348. m := ctx.Module()
  349. // If this module is a prebuilt, is enabled and has not been renamed to source then add a
  350. // dependency onto the source if it is present.
  351. if p := GetEmbeddedPrebuilt(m); p != nil && m.Enabled() && !p.properties.PrebuiltRenamedToSource {
  352. name := m.base().BaseModuleName()
  353. if ctx.OtherModuleReverseDependencyVariantExists(name) {
  354. ctx.AddReverseDependency(ctx.Module(), PrebuiltDepTag, name)
  355. p.properties.SourceExists = true
  356. }
  357. }
  358. }
  359. // checkInvariantsForSourceAndPrebuilt checks if invariants are kept when replacing
  360. // source with prebuilt. Note that the current module for the context is the source module.
  361. func checkInvariantsForSourceAndPrebuilt(ctx BaseModuleContext, s, p Module) {
  362. if _, ok := s.(OverrideModule); ok {
  363. // skip the check when the source module is `override_X` because it's only a placeholder
  364. // for the actual source module. The check will be invoked for the actual module.
  365. return
  366. }
  367. if sourcePartition, prebuiltPartition := s.PartitionTag(ctx.DeviceConfig()), p.PartitionTag(ctx.DeviceConfig()); sourcePartition != prebuiltPartition {
  368. ctx.OtherModuleErrorf(p, "partition is different: %s(%s) != %s(%s)",
  369. sourcePartition, ctx.ModuleName(), prebuiltPartition, ctx.OtherModuleName(p))
  370. }
  371. }
  372. // PrebuiltSelectModuleMutator marks prebuilts that are used, either overriding source modules or
  373. // because the source module doesn't exist. It also disables installing overridden source modules.
  374. func PrebuiltSelectModuleMutator(ctx TopDownMutatorContext) {
  375. m := ctx.Module()
  376. if p := GetEmbeddedPrebuilt(m); p != nil {
  377. if p.srcsSupplier == nil && p.srcsPropertyName == "" {
  378. panic(fmt.Errorf("prebuilt module did not have InitPrebuiltModule called on it"))
  379. }
  380. if !p.properties.SourceExists {
  381. p.properties.UsePrebuilt = p.usePrebuilt(ctx, nil, m)
  382. }
  383. } else if s, ok := ctx.Module().(Module); ok {
  384. ctx.VisitDirectDepsWithTag(PrebuiltDepTag, func(prebuiltModule Module) {
  385. p := GetEmbeddedPrebuilt(prebuiltModule)
  386. if p.usePrebuilt(ctx, s, prebuiltModule) {
  387. checkInvariantsForSourceAndPrebuilt(ctx, s, prebuiltModule)
  388. p.properties.UsePrebuilt = true
  389. s.ReplacedByPrebuilt()
  390. }
  391. })
  392. }
  393. }
  394. // PrebuiltPostDepsMutator replaces dependencies on the source module with dependencies on the
  395. // prebuilt when both modules exist and the prebuilt should be used. When the prebuilt should not
  396. // be used, disable installing it.
  397. func PrebuiltPostDepsMutator(ctx BottomUpMutatorContext) {
  398. m := ctx.Module()
  399. if p := GetEmbeddedPrebuilt(m); p != nil {
  400. name := m.base().BaseModuleName()
  401. if p.properties.UsePrebuilt {
  402. if p.properties.SourceExists {
  403. ctx.ReplaceDependenciesIf(name, func(from blueprint.Module, tag blueprint.DependencyTag, to blueprint.Module) bool {
  404. if t, ok := tag.(ReplaceSourceWithPrebuilt); ok {
  405. return t.ReplaceSourceWithPrebuilt()
  406. }
  407. return true
  408. })
  409. }
  410. } else {
  411. m.HideFromMake()
  412. }
  413. }
  414. }
  415. // usePrebuilt returns true if a prebuilt should be used instead of the source module. The prebuilt
  416. // will be used if it is marked "prefer" or if the source module is disabled.
  417. func (p *Prebuilt) usePrebuilt(ctx TopDownMutatorContext, source Module, prebuilt Module) bool {
  418. if p.srcsSupplier != nil && len(p.srcsSupplier(ctx, prebuilt)) == 0 {
  419. return false
  420. }
  421. // Skip prebuilt modules under unexported namespaces so that we won't
  422. // end up shadowing non-prebuilt module when prebuilt module under same
  423. // name happens to have a `Prefer` property set to true.
  424. if ctx.Config().KatiEnabled() && !prebuilt.ExportedToMake() {
  425. return false
  426. }
  427. // If source is not available or is disabled then always use the prebuilt.
  428. if source == nil || !source.Enabled() {
  429. return true
  430. }
  431. // If the use_source_config_var property is set then it overrides the prefer property setting.
  432. if configVar := p.properties.Use_source_config_var; configVar != nil {
  433. return !ctx.Config().VendorConfig(proptools.String(configVar.Config_namespace)).Bool(proptools.String(configVar.Var_name))
  434. }
  435. // TODO: use p.Properties.Name and ctx.ModuleDir to override preference
  436. return Bool(p.properties.Prefer)
  437. }
  438. func (p *Prebuilt) SourceExists() bool {
  439. return p.properties.SourceExists
  440. }