prebuilt_etc.go 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839
  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 etc
  15. // This file implements module types that install prebuilt artifacts.
  16. //
  17. // There exist two classes of prebuilt modules in the Android tree. The first class are the ones
  18. // based on `android.Prebuilt`, such as `cc_prebuilt_library` and `java_import`. This kind of
  19. // modules may exist both as prebuilts and source at the same time, though only one would be
  20. // installed and the other would be marked disabled. The `prebuilt_postdeps` mutator would select
  21. // the actual modules to be installed. More details in android/prebuilt.go.
  22. //
  23. // The second class is described in this file. Unlike `android.Prebuilt` based module types,
  24. // `prebuilt_etc` exist only as prebuilts and cannot have a same-named source module counterpart.
  25. // This makes the logic of `prebuilt_etc` to be much simpler as they don't need to go through the
  26. // various `prebuilt_*` mutators.
  27. import (
  28. "encoding/json"
  29. "fmt"
  30. "path/filepath"
  31. "reflect"
  32. "strings"
  33. "github.com/google/blueprint/proptools"
  34. "android/soong/android"
  35. "android/soong/bazel"
  36. "android/soong/bazel/cquery"
  37. "android/soong/snapshot"
  38. )
  39. var pctx = android.NewPackageContext("android/soong/etc")
  40. // TODO(jungw): Now that it handles more than the ones in etc/, consider renaming this file.
  41. func init() {
  42. pctx.Import("android/soong/android")
  43. RegisterPrebuiltEtcBuildComponents(android.InitRegistrationContext)
  44. snapshot.RegisterSnapshotAction(generatePrebuiltSnapshot)
  45. }
  46. func RegisterPrebuiltEtcBuildComponents(ctx android.RegistrationContext) {
  47. ctx.RegisterModuleType("prebuilt_etc", PrebuiltEtcFactory)
  48. ctx.RegisterModuleType("prebuilt_etc_host", PrebuiltEtcHostFactory)
  49. ctx.RegisterModuleType("prebuilt_etc_cacerts", PrebuiltEtcCaCertsFactory)
  50. ctx.RegisterModuleType("prebuilt_root", PrebuiltRootFactory)
  51. ctx.RegisterModuleType("prebuilt_root_host", PrebuiltRootHostFactory)
  52. ctx.RegisterModuleType("prebuilt_usr_share", PrebuiltUserShareFactory)
  53. ctx.RegisterModuleType("prebuilt_usr_share_host", PrebuiltUserShareHostFactory)
  54. ctx.RegisterModuleType("prebuilt_font", PrebuiltFontFactory)
  55. ctx.RegisterModuleType("prebuilt_firmware", PrebuiltFirmwareFactory)
  56. ctx.RegisterModuleType("prebuilt_dsp", PrebuiltDSPFactory)
  57. ctx.RegisterModuleType("prebuilt_rfsa", PrebuiltRFSAFactory)
  58. ctx.RegisterModuleType("prebuilt_defaults", defaultsFactory)
  59. }
  60. var PrepareForTestWithPrebuiltEtc = android.FixtureRegisterWithContext(RegisterPrebuiltEtcBuildComponents)
  61. type prebuiltEtcProperties struct {
  62. // Source file of this prebuilt. Can reference a genrule type module with the ":module" syntax.
  63. Src *string `android:"path,arch_variant"`
  64. // Optional name for the installed file. If unspecified, name of the module is used as the file
  65. // name.
  66. Filename *string `android:"arch_variant"`
  67. // When set to true, and filename property is not set, the name for the installed file
  68. // is the same as the file name of the source file.
  69. Filename_from_src *bool `android:"arch_variant"`
  70. // Make this module available when building for ramdisk.
  71. // On device without a dedicated recovery partition, the module is only
  72. // available after switching root into
  73. // /first_stage_ramdisk. To expose the module before switching root, install
  74. // the recovery variant instead.
  75. Ramdisk_available *bool
  76. // Make this module available when building for vendor ramdisk.
  77. // On device without a dedicated recovery partition, the module is only
  78. // available after switching root into
  79. // /first_stage_ramdisk. To expose the module before switching root, install
  80. // the recovery variant instead.
  81. Vendor_ramdisk_available *bool
  82. // Make this module available when building for debug ramdisk.
  83. Debug_ramdisk_available *bool
  84. // Make this module available when building for recovery.
  85. Recovery_available *bool
  86. // Whether this module is directly installable to one of the partitions. Default: true.
  87. Installable *bool
  88. // Install symlinks to the installed file.
  89. Symlinks []string `android:"arch_variant"`
  90. }
  91. type prebuiltSubdirProperties struct {
  92. // Optional subdirectory under which this file is installed into, cannot be specified with
  93. // relative_install_path, prefer relative_install_path.
  94. Sub_dir *string `android:"arch_variant"`
  95. // Optional subdirectory under which this file is installed into, cannot be specified with
  96. // sub_dir.
  97. Relative_install_path *string `android:"arch_variant"`
  98. }
  99. type PrebuiltEtcModule interface {
  100. android.Module
  101. // Returns the base install directory, such as "etc", "usr/share".
  102. BaseDir() string
  103. // Returns the sub install directory relative to BaseDir().
  104. SubDir() string
  105. // Returns an android.OutputPath to the intermeidate file, which is the renamed prebuilt source
  106. // file.
  107. OutputFile() android.OutputPath
  108. }
  109. type PrebuiltEtc struct {
  110. android.ModuleBase
  111. android.DefaultableModuleBase
  112. android.BazelModuleBase
  113. snapshot.VendorSnapshotModuleInterface
  114. snapshot.RecoverySnapshotModuleInterface
  115. properties prebuiltEtcProperties
  116. subdirProperties prebuiltSubdirProperties
  117. sourceFilePath android.Path
  118. outputFilePath android.OutputPath
  119. // The base install location, e.g. "etc" for prebuilt_etc, "usr/share" for prebuilt_usr_share.
  120. installDirBase string
  121. // The base install location when soc_specific property is set to true, e.g. "firmware" for
  122. // prebuilt_firmware.
  123. socInstallDirBase string
  124. installDirPath android.InstallPath
  125. additionalDependencies *android.Paths
  126. }
  127. type Defaults struct {
  128. android.ModuleBase
  129. android.DefaultsModuleBase
  130. }
  131. func (p *PrebuiltEtc) inRamdisk() bool {
  132. return p.ModuleBase.InRamdisk() || p.ModuleBase.InstallInRamdisk()
  133. }
  134. func (p *PrebuiltEtc) onlyInRamdisk() bool {
  135. return p.ModuleBase.InstallInRamdisk()
  136. }
  137. func (p *PrebuiltEtc) InstallInRamdisk() bool {
  138. return p.inRamdisk()
  139. }
  140. func (p *PrebuiltEtc) inVendorRamdisk() bool {
  141. return p.ModuleBase.InVendorRamdisk() || p.ModuleBase.InstallInVendorRamdisk()
  142. }
  143. func (p *PrebuiltEtc) onlyInVendorRamdisk() bool {
  144. return p.ModuleBase.InstallInVendorRamdisk()
  145. }
  146. func (p *PrebuiltEtc) InstallInVendorRamdisk() bool {
  147. return p.inVendorRamdisk()
  148. }
  149. func (p *PrebuiltEtc) inDebugRamdisk() bool {
  150. return p.ModuleBase.InDebugRamdisk() || p.ModuleBase.InstallInDebugRamdisk()
  151. }
  152. func (p *PrebuiltEtc) onlyInDebugRamdisk() bool {
  153. return p.ModuleBase.InstallInDebugRamdisk()
  154. }
  155. func (p *PrebuiltEtc) InstallInDebugRamdisk() bool {
  156. return p.inDebugRamdisk()
  157. }
  158. func (p *PrebuiltEtc) InRecovery() bool {
  159. return p.ModuleBase.InRecovery() || p.ModuleBase.InstallInRecovery()
  160. }
  161. func (p *PrebuiltEtc) onlyInRecovery() bool {
  162. return p.ModuleBase.InstallInRecovery()
  163. }
  164. func (p *PrebuiltEtc) InstallInRecovery() bool {
  165. return p.InRecovery()
  166. }
  167. var _ android.ImageInterface = (*PrebuiltEtc)(nil)
  168. func (p *PrebuiltEtc) ImageMutatorBegin(ctx android.BaseModuleContext) {}
  169. func (p *PrebuiltEtc) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
  170. return !p.ModuleBase.InstallInRecovery() && !p.ModuleBase.InstallInRamdisk() &&
  171. !p.ModuleBase.InstallInVendorRamdisk() && !p.ModuleBase.InstallInDebugRamdisk()
  172. }
  173. func (p *PrebuiltEtc) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
  174. return proptools.Bool(p.properties.Ramdisk_available) || p.ModuleBase.InstallInRamdisk()
  175. }
  176. func (p *PrebuiltEtc) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
  177. return proptools.Bool(p.properties.Vendor_ramdisk_available) || p.ModuleBase.InstallInVendorRamdisk()
  178. }
  179. func (p *PrebuiltEtc) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
  180. return proptools.Bool(p.properties.Debug_ramdisk_available) || p.ModuleBase.InstallInDebugRamdisk()
  181. }
  182. func (p *PrebuiltEtc) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
  183. return proptools.Bool(p.properties.Recovery_available) || p.ModuleBase.InstallInRecovery()
  184. }
  185. func (p *PrebuiltEtc) ExtraImageVariations(ctx android.BaseModuleContext) []string {
  186. return nil
  187. }
  188. func (p *PrebuiltEtc) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) {
  189. }
  190. func (p *PrebuiltEtc) SourceFilePath(ctx android.ModuleContext) android.Path {
  191. return android.PathForModuleSrc(ctx, proptools.String(p.properties.Src))
  192. }
  193. func (p *PrebuiltEtc) InstallDirPath() android.InstallPath {
  194. return p.installDirPath
  195. }
  196. // This allows other derivative modules (e.g. prebuilt_etc_xml) to perform
  197. // additional steps (like validating the src) before the file is installed.
  198. func (p *PrebuiltEtc) SetAdditionalDependencies(paths android.Paths) {
  199. p.additionalDependencies = &paths
  200. }
  201. func (p *PrebuiltEtc) OutputFile() android.OutputPath {
  202. return p.outputFilePath
  203. }
  204. var _ android.OutputFileProducer = (*PrebuiltEtc)(nil)
  205. func (p *PrebuiltEtc) OutputFiles(tag string) (android.Paths, error) {
  206. switch tag {
  207. case "":
  208. return android.Paths{p.outputFilePath}, nil
  209. default:
  210. return nil, fmt.Errorf("unsupported module reference tag %q", tag)
  211. }
  212. }
  213. func (p *PrebuiltEtc) SubDir() string {
  214. if subDir := proptools.String(p.subdirProperties.Sub_dir); subDir != "" {
  215. return subDir
  216. }
  217. return proptools.String(p.subdirProperties.Relative_install_path)
  218. }
  219. func (p *PrebuiltEtc) BaseDir() string {
  220. return p.installDirBase
  221. }
  222. func (p *PrebuiltEtc) Installable() bool {
  223. return p.properties.Installable == nil || proptools.Bool(p.properties.Installable)
  224. }
  225. func (p *PrebuiltEtc) InVendor() bool {
  226. return p.ModuleBase.InstallInVendor()
  227. }
  228. func (p *PrebuiltEtc) ExcludeFromVendorSnapshot() bool {
  229. return false
  230. }
  231. func (p *PrebuiltEtc) ExcludeFromRecoverySnapshot() bool {
  232. return false
  233. }
  234. func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
  235. filename := proptools.String(p.properties.Filename)
  236. filenameFromSrc := proptools.Bool(p.properties.Filename_from_src)
  237. if p.properties.Src != nil {
  238. p.sourceFilePath = android.PathForModuleSrc(ctx, proptools.String(p.properties.Src))
  239. // Determine the output file basename.
  240. // If Filename is set, use the name specified by the property.
  241. // If Filename_from_src is set, use the source file name.
  242. // Otherwise use the module name.
  243. if filename != "" {
  244. if filenameFromSrc {
  245. ctx.PropertyErrorf("filename_from_src", "filename is set. filename_from_src can't be true")
  246. return
  247. }
  248. } else if filenameFromSrc {
  249. filename = p.sourceFilePath.Base()
  250. } else {
  251. filename = ctx.ModuleName()
  252. }
  253. } else if ctx.Config().AllowMissingDependencies() {
  254. // If no srcs was set and AllowMissingDependencies is enabled then
  255. // mark the module as missing dependencies and set a fake source path
  256. // and file name.
  257. ctx.AddMissingDependencies([]string{"MISSING_PREBUILT_SRC_FILE"})
  258. p.sourceFilePath = android.PathForModuleSrc(ctx)
  259. if filename == "" {
  260. filename = ctx.ModuleName()
  261. }
  262. } else {
  263. ctx.PropertyErrorf("src", "missing prebuilt source file")
  264. return
  265. }
  266. if strings.Contains(filename, "/") {
  267. ctx.PropertyErrorf("filename", "filename cannot contain separator '/'")
  268. return
  269. }
  270. // Check that `sub_dir` and `relative_install_path` are not set at the same time.
  271. if p.subdirProperties.Sub_dir != nil && p.subdirProperties.Relative_install_path != nil {
  272. ctx.PropertyErrorf("sub_dir", "relative_install_path is set. Cannot set sub_dir")
  273. }
  274. // If soc install dir was specified and SOC specific is set, set the installDirPath to the
  275. // specified socInstallDirBase.
  276. installBaseDir := p.installDirBase
  277. if p.SocSpecific() && p.socInstallDirBase != "" {
  278. installBaseDir = p.socInstallDirBase
  279. }
  280. p.installDirPath = android.PathForModuleInstall(ctx, installBaseDir, p.SubDir())
  281. // Call InstallFile even when uninstallable to make the module included in the package
  282. ip := installProperties{
  283. installable: p.Installable(),
  284. filename: filename,
  285. sourceFilePath: p.sourceFilePath,
  286. symlinks: p.properties.Symlinks,
  287. }
  288. p.addInstallRules(ctx, ip)
  289. }
  290. type installProperties struct {
  291. installable bool
  292. filename string
  293. sourceFilePath android.Path
  294. symlinks []string
  295. }
  296. // utility function to add install rules to the build graph.
  297. // Reduces code duplication between Soong and Mixed build analysis
  298. func (p *PrebuiltEtc) addInstallRules(ctx android.ModuleContext, ip installProperties) {
  299. if !ip.installable {
  300. p.SkipInstall()
  301. }
  302. // Copy the file from src to a location in out/ with the correct `filename`
  303. // This ensures that outputFilePath has the correct name for others to
  304. // use, as the source file may have a different name.
  305. p.outputFilePath = android.PathForModuleOut(ctx, ip.filename).OutputPath
  306. ctx.Build(pctx, android.BuildParams{
  307. Rule: android.Cp,
  308. Output: p.outputFilePath,
  309. Input: ip.sourceFilePath,
  310. })
  311. installPath := ctx.InstallFile(p.installDirPath, ip.filename, p.outputFilePath)
  312. for _, sl := range ip.symlinks {
  313. ctx.InstallSymlink(p.installDirPath, sl, installPath)
  314. }
  315. }
  316. func (p *PrebuiltEtc) AndroidMkEntries() []android.AndroidMkEntries {
  317. nameSuffix := ""
  318. if p.inRamdisk() && !p.onlyInRamdisk() {
  319. nameSuffix = ".ramdisk"
  320. }
  321. if p.inVendorRamdisk() && !p.onlyInVendorRamdisk() {
  322. nameSuffix = ".vendor_ramdisk"
  323. }
  324. if p.inDebugRamdisk() && !p.onlyInDebugRamdisk() {
  325. nameSuffix = ".debug_ramdisk"
  326. }
  327. if p.InRecovery() && !p.onlyInRecovery() {
  328. nameSuffix = ".recovery"
  329. }
  330. return []android.AndroidMkEntries{android.AndroidMkEntries{
  331. Class: "ETC",
  332. SubName: nameSuffix,
  333. OutputFile: android.OptionalPathForPath(p.outputFilePath),
  334. ExtraEntries: []android.AndroidMkExtraEntriesFunc{
  335. func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
  336. entries.SetString("LOCAL_MODULE_TAGS", "optional")
  337. entries.SetString("LOCAL_MODULE_PATH", p.installDirPath.String())
  338. entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.outputFilePath.Base())
  339. if len(p.properties.Symlinks) > 0 {
  340. entries.AddStrings("LOCAL_MODULE_SYMLINKS", p.properties.Symlinks...)
  341. }
  342. entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", !p.Installable())
  343. if p.additionalDependencies != nil {
  344. entries.AddStrings("LOCAL_ADDITIONAL_DEPENDENCIES", p.additionalDependencies.Strings()...)
  345. }
  346. },
  347. },
  348. }}
  349. }
  350. func InitPrebuiltEtcModule(p *PrebuiltEtc, dirBase string) {
  351. p.installDirBase = dirBase
  352. p.AddProperties(&p.properties)
  353. p.AddProperties(&p.subdirProperties)
  354. }
  355. func InitPrebuiltRootModule(p *PrebuiltEtc) {
  356. p.installDirBase = "."
  357. p.AddProperties(&p.properties)
  358. }
  359. // prebuilt_etc is for a prebuilt artifact that is installed in
  360. // <partition>/etc/<sub_dir> directory.
  361. func PrebuiltEtcFactory() android.Module {
  362. module := &PrebuiltEtc{}
  363. InitPrebuiltEtcModule(module, "etc")
  364. // This module is device-only
  365. android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
  366. android.InitDefaultableModule(module)
  367. android.InitBazelModule(module)
  368. return module
  369. }
  370. func defaultsFactory() android.Module {
  371. return DefaultsFactory()
  372. }
  373. func DefaultsFactory(props ...interface{}) android.Module {
  374. module := &Defaults{}
  375. module.AddProperties(props...)
  376. module.AddProperties(
  377. &prebuiltEtcProperties{},
  378. &prebuiltSubdirProperties{},
  379. )
  380. android.InitDefaultsModule(module)
  381. return module
  382. }
  383. // prebuilt_etc_host is for a host prebuilt artifact that is installed in
  384. // $(HOST_OUT)/etc/<sub_dir> directory.
  385. func PrebuiltEtcHostFactory() android.Module {
  386. module := &PrebuiltEtc{}
  387. InitPrebuiltEtcModule(module, "etc")
  388. // This module is host-only
  389. android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon)
  390. android.InitDefaultableModule(module)
  391. android.InitBazelModule(module)
  392. return module
  393. }
  394. // prebuilt_etc_host is for a host prebuilt artifact that is installed in
  395. // <partition>/etc/<sub_dir> directory.
  396. func PrebuiltEtcCaCertsFactory() android.Module {
  397. module := &PrebuiltEtc{}
  398. InitPrebuiltEtcModule(module, "cacerts")
  399. // This module is device-only
  400. android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
  401. android.InitBazelModule(module)
  402. return module
  403. }
  404. // prebuilt_root is for a prebuilt artifact that is installed in
  405. // <partition>/ directory. Can't have any sub directories.
  406. func PrebuiltRootFactory() android.Module {
  407. module := &PrebuiltEtc{}
  408. InitPrebuiltRootModule(module)
  409. // This module is device-only
  410. android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
  411. android.InitDefaultableModule(module)
  412. return module
  413. }
  414. // prebuilt_root_host is for a host prebuilt artifact that is installed in $(HOST_OUT)/<sub_dir>
  415. // directory.
  416. func PrebuiltRootHostFactory() android.Module {
  417. module := &PrebuiltEtc{}
  418. InitPrebuiltEtcModule(module, ".")
  419. // This module is host-only
  420. android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon)
  421. android.InitDefaultableModule(module)
  422. return module
  423. }
  424. // prebuilt_usr_share is for a prebuilt artifact that is installed in
  425. // <partition>/usr/share/<sub_dir> directory.
  426. func PrebuiltUserShareFactory() android.Module {
  427. module := &PrebuiltEtc{}
  428. InitPrebuiltEtcModule(module, "usr/share")
  429. // This module is device-only
  430. android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
  431. android.InitDefaultableModule(module)
  432. android.InitBazelModule(module)
  433. return module
  434. }
  435. // prebuild_usr_share_host is for a host prebuilt artifact that is installed in
  436. // $(HOST_OUT)/usr/share/<sub_dir> directory.
  437. func PrebuiltUserShareHostFactory() android.Module {
  438. module := &PrebuiltEtc{}
  439. InitPrebuiltEtcModule(module, "usr/share")
  440. // This module is host-only
  441. android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon)
  442. android.InitDefaultableModule(module)
  443. return module
  444. }
  445. // prebuilt_font installs a font in <partition>/fonts directory.
  446. func PrebuiltFontFactory() android.Module {
  447. module := &PrebuiltEtc{}
  448. InitPrebuiltEtcModule(module, "fonts")
  449. // This module is device-only
  450. android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
  451. android.InitDefaultableModule(module)
  452. return module
  453. }
  454. // prebuilt_firmware installs a firmware file to <partition>/etc/firmware directory for system
  455. // image.
  456. // If soc_specific property is set to true, the firmware file is installed to the
  457. // vendor <partition>/firmware directory for vendor image.
  458. func PrebuiltFirmwareFactory() android.Module {
  459. module := &PrebuiltEtc{}
  460. module.socInstallDirBase = "firmware"
  461. InitPrebuiltEtcModule(module, "etc/firmware")
  462. // This module is device-only
  463. android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
  464. android.InitDefaultableModule(module)
  465. return module
  466. }
  467. // prebuilt_dsp installs a DSP related file to <partition>/etc/dsp directory for system image.
  468. // If soc_specific property is set to true, the DSP related file is installed to the
  469. // vendor <partition>/dsp directory for vendor image.
  470. func PrebuiltDSPFactory() android.Module {
  471. module := &PrebuiltEtc{}
  472. module.socInstallDirBase = "dsp"
  473. InitPrebuiltEtcModule(module, "etc/dsp")
  474. // This module is device-only
  475. android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
  476. android.InitDefaultableModule(module)
  477. return module
  478. }
  479. // prebuilt_rfsa installs a firmware file that will be available through Qualcomm's RFSA
  480. // to the <partition>/lib/rfsa directory.
  481. func PrebuiltRFSAFactory() android.Module {
  482. module := &PrebuiltEtc{}
  483. // Ideally these would go in /vendor/dsp, but the /vendor/lib/rfsa paths are hardcoded in too
  484. // many places outside of the application processor. They could be moved to /vendor/dsp once
  485. // that is cleaned up.
  486. InitPrebuiltEtcModule(module, "lib/rfsa")
  487. // This module is device-only
  488. android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
  489. android.InitDefaultableModule(module)
  490. return module
  491. }
  492. // Copy file into the snapshot
  493. func copyFile(ctx android.SingletonContext, path android.Path, out string, fake bool) android.OutputPath {
  494. if fake {
  495. // Create empty file instead for the fake snapshot
  496. return snapshot.WriteStringToFileRule(ctx, "", out)
  497. } else {
  498. return snapshot.CopyFileRule(pctx, ctx, path, out)
  499. }
  500. }
  501. // Check if the module is target of the snapshot
  502. func isSnapshotAware(ctx android.SingletonContext, m *PrebuiltEtc, image snapshot.SnapshotImage) bool {
  503. if !m.Enabled() {
  504. return false
  505. }
  506. // Skip if the module is not included in the image
  507. if !image.InImage(m)() {
  508. return false
  509. }
  510. // When android/prebuilt.go selects between source and prebuilt, it sets
  511. // HideFromMake on the other one to avoid duplicate install rules in make.
  512. if m.IsHideFromMake() {
  513. return false
  514. }
  515. // There are some prebuilt_etc module with multiple definition of same name.
  516. // Check if the target would be included from the build
  517. if !m.ExportedToMake() {
  518. return false
  519. }
  520. // Skip if the module is in the predefined path list to skip
  521. if image.IsProprietaryPath(ctx.ModuleDir(m), ctx.DeviceConfig()) {
  522. return false
  523. }
  524. // Skip if the module should be excluded
  525. if image.ExcludeFromSnapshot(m) || image.ExcludeFromDirectedSnapshot(ctx.DeviceConfig(), m.BaseModuleName()) {
  526. return false
  527. }
  528. // Skip from other exceptional cases
  529. if m.Target().Os.Class != android.Device {
  530. return false
  531. }
  532. if m.Target().NativeBridge == android.NativeBridgeEnabled {
  533. return false
  534. }
  535. return true
  536. }
  537. func generatePrebuiltSnapshot(s snapshot.SnapshotSingleton, ctx android.SingletonContext, snapshotArchDir string) snapshot.SnapshotPaths {
  538. /*
  539. Snapshot zipped artifacts directory structure for etc modules:
  540. {SNAPSHOT_ARCH}/
  541. arch-{TARGET_ARCH}-{TARGET_ARCH_VARIANT}/
  542. etc/
  543. (prebuilt etc files)
  544. arch-{TARGET_2ND_ARCH}-{TARGET_2ND_ARCH_VARIANT}/
  545. etc/
  546. (prebuilt etc files)
  547. NOTICE_FILES/
  548. (notice files)
  549. */
  550. var snapshotOutputs android.Paths
  551. var snapshotNotices android.Paths
  552. installedNotices := make(map[string]bool)
  553. ctx.VisitAllModules(func(module android.Module) {
  554. m, ok := module.(*PrebuiltEtc)
  555. if !ok {
  556. return
  557. }
  558. if !isSnapshotAware(ctx, m, s.Image) {
  559. return
  560. }
  561. targetArch := "arch-" + m.Target().Arch.ArchType.String()
  562. snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, "etc", m.BaseModuleName())
  563. snapshotOutputs = append(snapshotOutputs, copyFile(ctx, m.OutputFile(), snapshotLibOut, s.Fake))
  564. prop := snapshot.SnapshotJsonFlags{}
  565. propOut := snapshotLibOut + ".json"
  566. prop.InitBaseSnapshotProps(m)
  567. prop.RelativeInstallPath = m.SubDir()
  568. if m.properties.Filename != nil {
  569. prop.Filename = *m.properties.Filename
  570. }
  571. j, err := json.Marshal(prop)
  572. if err != nil {
  573. ctx.Errorf("json marshal to %q failed: %#v", propOut, err)
  574. return
  575. }
  576. snapshotOutputs = append(snapshotOutputs, snapshot.WriteStringToFileRule(ctx, string(j), propOut))
  577. for _, notice := range m.EffectiveLicenseFiles() {
  578. if _, ok := installedNotices[notice.String()]; !ok {
  579. installedNotices[notice.String()] = true
  580. snapshotNotices = append(snapshotNotices, notice)
  581. }
  582. }
  583. })
  584. return snapshot.SnapshotPaths{OutputFiles: snapshotOutputs, NoticeFiles: snapshotNotices}
  585. }
  586. // For Bazel / bp2build
  587. type bazelPrebuiltFileAttributes struct {
  588. Src bazel.LabelAttribute
  589. Filename bazel.LabelAttribute
  590. Dir string
  591. Installable bazel.BoolAttribute
  592. Filename_from_src bazel.BoolAttribute
  593. }
  594. // Bp2buildHelper returns a bazelPrebuiltFileAttributes used for the conversion
  595. // of prebuilt_* modules. bazelPrebuiltFileAttributes has the common attributes
  596. // used by both prebuilt_etc_xml and other prebuilt_* moodules
  597. func (module *PrebuiltEtc) Bp2buildHelper(ctx android.TopDownMutatorContext) *bazelPrebuiltFileAttributes {
  598. var src bazel.LabelAttribute
  599. for axis, configToProps := range module.GetArchVariantProperties(ctx, &prebuiltEtcProperties{}) {
  600. for config, p := range configToProps {
  601. props, ok := p.(*prebuiltEtcProperties)
  602. if !ok {
  603. continue
  604. }
  605. if props.Src != nil {
  606. label := android.BazelLabelForModuleSrcSingle(ctx, *props.Src)
  607. src.SetSelectValue(axis, config, label)
  608. }
  609. }
  610. for propName, productConfigProps := range android.ProductVariableProperties(ctx, ctx.Module()) {
  611. for configProp, propVal := range productConfigProps {
  612. if propName == "Src" {
  613. props, ok := propVal.(*string)
  614. if !ok {
  615. ctx.PropertyErrorf(" Expected Property to have type string, but was %s\n", reflect.TypeOf(propVal).String())
  616. continue
  617. }
  618. if props != nil {
  619. label := android.BazelLabelForModuleSrcSingle(ctx, *props)
  620. src.SetSelectValue(configProp.ConfigurationAxis(), configProp.SelectKey(), label)
  621. }
  622. }
  623. }
  624. }
  625. }
  626. var filename string
  627. var filenameFromSrc bool
  628. moduleProps := module.properties
  629. if moduleProps.Filename != nil && *moduleProps.Filename != "" {
  630. filename = *moduleProps.Filename
  631. } else if moduleProps.Filename_from_src != nil && *moduleProps.Filename_from_src {
  632. if moduleProps.Src != nil {
  633. filename = *moduleProps.Src
  634. }
  635. filenameFromSrc = true
  636. } else {
  637. filename = ctx.ModuleName()
  638. }
  639. var dir = module.installDirBase
  640. if subDir := module.subdirProperties.Sub_dir; subDir != nil {
  641. dir = dir + "/" + *subDir
  642. }
  643. var installable bazel.BoolAttribute
  644. if install := module.properties.Installable; install != nil {
  645. installable.Value = install
  646. }
  647. attrs := &bazelPrebuiltFileAttributes{
  648. Src: src,
  649. Dir: dir,
  650. Installable: installable,
  651. }
  652. if filename != "" {
  653. attrs.Filename = bazel.LabelAttribute{Value: &bazel.Label{Label: filename}}
  654. } else if filenameFromSrc {
  655. attrs.Filename_from_src = bazel.BoolAttribute{Value: moduleProps.Filename_from_src}
  656. }
  657. return attrs
  658. }
  659. // ConvertWithBp2build performs bp2build conversion of PrebuiltEtc
  660. // prebuilt_* modules (except prebuilt_etc_xml) are PrebuiltEtc,
  661. // which we treat as *PrebuiltFile*
  662. func (module *PrebuiltEtc) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
  663. var dir = module.installDirBase
  664. // prebuilt_file supports only `etc` or `usr/share`
  665. if !(dir == "etc" || dir == "usr/share") {
  666. return
  667. }
  668. attrs := module.Bp2buildHelper(ctx)
  669. props := bazel.BazelTargetModuleProperties{
  670. Rule_class: "prebuilt_file",
  671. Bzl_load_location: "//build/bazel/rules:prebuilt_file.bzl",
  672. }
  673. ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: module.Name()}, attrs)
  674. }
  675. var _ android.MixedBuildBuildable = (*PrebuiltEtc)(nil)
  676. func (pe *PrebuiltEtc) IsMixedBuildSupported(ctx android.BaseModuleContext) bool {
  677. return true
  678. }
  679. func (pe *PrebuiltEtc) QueueBazelCall(ctx android.BaseModuleContext) {
  680. ctx.Config().BazelContext.QueueBazelRequest(
  681. pe.GetBazelLabel(ctx, pe),
  682. cquery.GetPrebuiltFileInfo,
  683. android.GetConfigKey(ctx),
  684. )
  685. }
  686. func (pe *PrebuiltEtc) ProcessBazelQueryResponse(ctx android.ModuleContext) {
  687. bazelCtx := ctx.Config().BazelContext
  688. pfi, err := bazelCtx.GetPrebuiltFileInfo(pe.GetBazelLabel(ctx, pe), android.GetConfigKey(ctx))
  689. if err != nil {
  690. ctx.ModuleErrorf(err.Error())
  691. return
  692. }
  693. // Set properties for androidmk
  694. pe.installDirPath = android.PathForModuleInstall(ctx, pfi.Dir)
  695. // Installation rules
  696. ip := installProperties{
  697. installable: pfi.Installable,
  698. filename: pfi.Filename,
  699. sourceFilePath: android.PathForSource(ctx, pfi.Src),
  700. // symlinks: pe.properties.Symlinks, // TODO: b/207489266 - Fully support all properties in prebuilt_file
  701. }
  702. pe.addInstallRules(ctx, ip)
  703. }