prebuilt_etc.go 25 KB

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