prebuilt.go 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981
  1. // Copyright (C) 2019 The Android Open Source Project
  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 apex
  15. import (
  16. "fmt"
  17. "io"
  18. "path/filepath"
  19. "strconv"
  20. "strings"
  21. "android/soong/android"
  22. "android/soong/java"
  23. "github.com/google/blueprint"
  24. "github.com/google/blueprint/proptools"
  25. )
  26. var (
  27. extractMatchingApex = pctx.StaticRule(
  28. "extractMatchingApex",
  29. blueprint.RuleParams{
  30. Command: `rm -rf "$out" && ` +
  31. `${extract_apks} -o "${out}" -allow-prereleased=${allow-prereleased} ` +
  32. `-sdk-version=${sdk-version} -abis=${abis} -screen-densities=all -extract-single ` +
  33. `${in}`,
  34. CommandDeps: []string{"${extract_apks}"},
  35. },
  36. "abis", "allow-prereleased", "sdk-version")
  37. )
  38. type prebuilt interface {
  39. isForceDisabled() bool
  40. InstallFilename() string
  41. }
  42. type prebuiltCommon struct {
  43. android.ModuleBase
  44. prebuilt android.Prebuilt
  45. // Properties common to both prebuilt_apex and apex_set.
  46. prebuiltCommonProperties *PrebuiltCommonProperties
  47. installDir android.InstallPath
  48. installFilename string
  49. installedFile android.InstallPath
  50. outputApex android.WritablePath
  51. // A list of apexFile objects created in prebuiltCommon.initApexFilesForAndroidMk which are used
  52. // to create make modules in prebuiltCommon.AndroidMkEntries.
  53. apexFilesForAndroidMk []apexFile
  54. // Installed locations of symlinks for backward compatibility.
  55. compatSymlinks android.InstallPaths
  56. hostRequired []string
  57. }
  58. type sanitizedPrebuilt interface {
  59. hasSanitizedSource(sanitizer string) bool
  60. }
  61. type PrebuiltCommonProperties struct {
  62. SelectedApexProperties
  63. // Canonical name of this APEX. Used to determine the path to the activated APEX on
  64. // device (/apex/<apex_name>). If unspecified, follows the name property.
  65. Apex_name *string
  66. ForceDisable bool `blueprint:"mutated"`
  67. // whether the extracted apex file is installable.
  68. Installable *bool
  69. // optional name for the installed apex. If unspecified, name of the
  70. // module is used as the file name
  71. Filename *string
  72. // names of modules to be overridden. Listed modules can only be other binaries
  73. // (in Make or Soong).
  74. // This does not completely prevent installation of the overridden binaries, but if both
  75. // binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
  76. // from PRODUCT_PACKAGES.
  77. Overrides []string
  78. // List of java libraries that are embedded inside this prebuilt APEX bundle and for which this
  79. // APEX bundle will create an APEX variant and provide dex implementation jars for use by
  80. // dexpreopt and boot jars package check.
  81. Exported_java_libs []string
  82. // List of bootclasspath fragments inside this prebuilt APEX bundle and for which this APEX
  83. // bundle will create an APEX variant.
  84. Exported_bootclasspath_fragments []string
  85. // List of systemserverclasspath fragments inside this prebuilt APEX bundle and for which this
  86. // APEX bundle will create an APEX variant.
  87. Exported_systemserverclasspath_fragments []string
  88. }
  89. // initPrebuiltCommon initializes the prebuiltCommon structure and performs initialization of the
  90. // module that is common to Prebuilt and ApexSet.
  91. func (p *prebuiltCommon) initPrebuiltCommon(module android.Module, properties *PrebuiltCommonProperties) {
  92. p.prebuiltCommonProperties = properties
  93. android.InitSingleSourcePrebuiltModule(module.(android.PrebuiltInterface), properties, "Selected_apex")
  94. android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
  95. }
  96. func (p *prebuiltCommon) ApexVariationName() string {
  97. return proptools.StringDefault(p.prebuiltCommonProperties.Apex_name, p.ModuleBase.BaseModuleName())
  98. }
  99. func (p *prebuiltCommon) Prebuilt() *android.Prebuilt {
  100. return &p.prebuilt
  101. }
  102. func (p *prebuiltCommon) isForceDisabled() bool {
  103. return p.prebuiltCommonProperties.ForceDisable
  104. }
  105. func (p *prebuiltCommon) checkForceDisable(ctx android.ModuleContext) bool {
  106. // If the device is configured to use flattened APEX, force disable the prebuilt because
  107. // the prebuilt is a non-flattened one.
  108. forceDisable := ctx.Config().FlattenApex()
  109. // Force disable the prebuilts when we are doing unbundled build. We do unbundled build
  110. // to build the prebuilts themselves.
  111. forceDisable = forceDisable || ctx.Config().UnbundledBuild()
  112. // b/137216042 don't use prebuilts when address sanitizer is on, unless the prebuilt has a sanitized source
  113. sanitized := ctx.Module().(sanitizedPrebuilt)
  114. forceDisable = forceDisable || (android.InList("address", ctx.Config().SanitizeDevice()) && !sanitized.hasSanitizedSource("address"))
  115. forceDisable = forceDisable || (android.InList("hwaddress", ctx.Config().SanitizeDevice()) && !sanitized.hasSanitizedSource("hwaddress"))
  116. if forceDisable && p.prebuilt.SourceExists() {
  117. p.prebuiltCommonProperties.ForceDisable = true
  118. return true
  119. }
  120. return false
  121. }
  122. func (p *prebuiltCommon) InstallFilename() string {
  123. return proptools.StringDefault(p.prebuiltCommonProperties.Filename, p.BaseModuleName()+imageApexSuffix)
  124. }
  125. func (p *prebuiltCommon) Name() string {
  126. return p.prebuilt.Name(p.ModuleBase.Name())
  127. }
  128. func (p *prebuiltCommon) Overrides() []string {
  129. return p.prebuiltCommonProperties.Overrides
  130. }
  131. func (p *prebuiltCommon) installable() bool {
  132. return proptools.BoolDefault(p.prebuiltCommonProperties.Installable, true)
  133. }
  134. // initApexFilesForAndroidMk initializes the prebuiltCommon.apexFilesForAndroidMk field from the
  135. // modules that this depends upon.
  136. func (p *prebuiltCommon) initApexFilesForAndroidMk(ctx android.ModuleContext) {
  137. // Walk the dependencies of this module looking for the java modules that it exports.
  138. ctx.WalkDeps(func(child, parent android.Module) bool {
  139. tag := ctx.OtherModuleDependencyTag(child)
  140. name := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(child))
  141. if java.IsBootclasspathFragmentContentDepTag(tag) ||
  142. java.IsSystemServerClasspathFragmentContentDepTag(tag) || tag == exportedJavaLibTag {
  143. // If the exported java module provides a dex jar path then add it to the list of apexFiles.
  144. path := child.(interface {
  145. DexJarBuildPath() java.OptionalDexJarPath
  146. }).DexJarBuildPath()
  147. if path.IsSet() {
  148. af := apexFile{
  149. module: child,
  150. moduleDir: ctx.OtherModuleDir(child),
  151. androidMkModuleName: name,
  152. builtFile: path.Path(),
  153. class: javaSharedLib,
  154. }
  155. if module, ok := child.(java.DexpreopterInterface); ok {
  156. for _, install := range module.DexpreoptBuiltInstalledForApex() {
  157. af.requiredModuleNames = append(af.requiredModuleNames, install.FullModuleName())
  158. }
  159. }
  160. p.apexFilesForAndroidMk = append(p.apexFilesForAndroidMk, af)
  161. }
  162. } else if tag == exportedBootclasspathFragmentTag ||
  163. tag == exportedSystemserverclasspathFragmentTag {
  164. // Visit the children of the bootclasspath_fragment and systemserver_fragment.
  165. return true
  166. }
  167. return false
  168. })
  169. }
  170. func (p *prebuiltCommon) addRequiredModules(entries *android.AndroidMkEntries) {
  171. for _, fi := range p.apexFilesForAndroidMk {
  172. entries.AddStrings("LOCAL_REQUIRED_MODULES", fi.requiredModuleNames...)
  173. entries.AddStrings("LOCAL_TARGET_REQUIRED_MODULES", fi.targetRequiredModuleNames...)
  174. entries.AddStrings("LOCAL_HOST_REQUIRED_MODULES", fi.hostRequiredModuleNames...)
  175. }
  176. }
  177. func (p *prebuiltCommon) AndroidMkEntries() []android.AndroidMkEntries {
  178. entriesList := []android.AndroidMkEntries{
  179. {
  180. Class: "ETC",
  181. OutputFile: android.OptionalPathForPath(p.outputApex),
  182. Include: "$(BUILD_PREBUILT)",
  183. Host_required: p.hostRequired,
  184. ExtraEntries: []android.AndroidMkExtraEntriesFunc{
  185. func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
  186. entries.SetString("LOCAL_MODULE_PATH", p.installDir.String())
  187. entries.SetString("LOCAL_MODULE_STEM", p.installFilename)
  188. entries.SetPath("LOCAL_SOONG_INSTALLED_MODULE", p.installedFile)
  189. entries.SetString("LOCAL_SOONG_INSTALL_PAIRS", p.outputApex.String()+":"+p.installedFile.String())
  190. entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", !p.installable())
  191. entries.AddStrings("LOCAL_OVERRIDES_MODULES", p.prebuiltCommonProperties.Overrides...)
  192. p.addRequiredModules(entries)
  193. },
  194. },
  195. },
  196. }
  197. // Iterate over the apexFilesForAndroidMk list and create an AndroidMkEntries struct for each
  198. // file. This provides similar behavior to that provided in apexBundle.AndroidMk() as it makes the
  199. // apex specific variants of the exported java modules available for use from within make.
  200. apexName := p.BaseModuleName()
  201. for _, fi := range p.apexFilesForAndroidMk {
  202. entries := p.createEntriesForApexFile(fi, apexName)
  203. entriesList = append(entriesList, entries)
  204. }
  205. return entriesList
  206. }
  207. // createEntriesForApexFile creates an AndroidMkEntries for the supplied apexFile
  208. func (p *prebuiltCommon) createEntriesForApexFile(fi apexFile, apexName string) android.AndroidMkEntries {
  209. moduleName := fi.androidMkModuleName + "." + apexName
  210. entries := android.AndroidMkEntries{
  211. Class: fi.class.nameInMake(),
  212. OverrideName: moduleName,
  213. OutputFile: android.OptionalPathForPath(fi.builtFile),
  214. Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
  215. ExtraEntries: []android.AndroidMkExtraEntriesFunc{
  216. func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
  217. entries.SetString("LOCAL_MODULE_PATH", p.installDir.String())
  218. entries.SetString("LOCAL_SOONG_INSTALLED_MODULE", filepath.Join(p.installDir.String(), fi.stem()))
  219. entries.SetString("LOCAL_SOONG_INSTALL_PAIRS",
  220. fi.builtFile.String()+":"+filepath.Join(p.installDir.String(), fi.stem()))
  221. // soong_java_prebuilt.mk sets LOCAL_MODULE_SUFFIX := .jar Therefore
  222. // we need to remove the suffix from LOCAL_MODULE_STEM, otherwise
  223. // we will have foo.jar.jar
  224. entries.SetString("LOCAL_MODULE_STEM", strings.TrimSuffix(fi.stem(), ".jar"))
  225. entries.SetString("LOCAL_SOONG_DEX_JAR", fi.builtFile.String())
  226. entries.SetString("LOCAL_DEX_PREOPT", "false")
  227. },
  228. },
  229. ExtraFooters: []android.AndroidMkExtraFootersFunc{
  230. func(w io.Writer, name, prefix, moduleDir string) {
  231. // m <module_name> will build <module_name>.<apex_name> as well.
  232. if fi.androidMkModuleName != moduleName {
  233. fmt.Fprintf(w, ".PHONY: %s\n", fi.androidMkModuleName)
  234. fmt.Fprintf(w, "%s: %s\n", fi.androidMkModuleName, moduleName)
  235. }
  236. },
  237. },
  238. }
  239. return entries
  240. }
  241. // prebuiltApexModuleCreator defines the methods that need to be implemented by prebuilt_apex and
  242. // apex_set in order to create the modules needed to provide access to the prebuilt .apex file.
  243. type prebuiltApexModuleCreator interface {
  244. createPrebuiltApexModules(ctx android.TopDownMutatorContext)
  245. }
  246. // prebuiltApexModuleCreatorMutator is the mutator responsible for invoking the
  247. // prebuiltApexModuleCreator's createPrebuiltApexModules method.
  248. //
  249. // It is registered as a pre-arch mutator as it must run after the ComponentDepsMutator because it
  250. // will need to access dependencies added by that (exported modules) but must run before the
  251. // DepsMutator so that the deapexer module it creates can add dependencies onto itself from the
  252. // exported modules.
  253. func prebuiltApexModuleCreatorMutator(ctx android.TopDownMutatorContext) {
  254. module := ctx.Module()
  255. if creator, ok := module.(prebuiltApexModuleCreator); ok {
  256. creator.createPrebuiltApexModules(ctx)
  257. }
  258. }
  259. func (p *prebuiltCommon) getExportedDependencies() map[string]exportedDependencyTag {
  260. dependencies := make(map[string]exportedDependencyTag)
  261. for _, dep := range p.prebuiltCommonProperties.Exported_java_libs {
  262. dependencies[dep] = exportedJavaLibTag
  263. }
  264. for _, dep := range p.prebuiltCommonProperties.Exported_bootclasspath_fragments {
  265. dependencies[dep] = exportedBootclasspathFragmentTag
  266. }
  267. for _, dep := range p.prebuiltCommonProperties.Exported_systemserverclasspath_fragments {
  268. dependencies[dep] = exportedSystemserverclasspathFragmentTag
  269. }
  270. return dependencies
  271. }
  272. // prebuiltApexContentsDeps adds dependencies onto the prebuilt apex module's contents.
  273. func (p *prebuiltCommon) prebuiltApexContentsDeps(ctx android.BottomUpMutatorContext) {
  274. module := ctx.Module()
  275. for dep, tag := range p.getExportedDependencies() {
  276. prebuiltDep := android.PrebuiltNameFromSource(dep)
  277. ctx.AddDependency(module, tag, prebuiltDep)
  278. }
  279. }
  280. // Implements android.DepInInSameApex
  281. func (p *prebuiltCommon) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
  282. tag := ctx.OtherModuleDependencyTag(dep)
  283. _, ok := tag.(exportedDependencyTag)
  284. return ok
  285. }
  286. // apexInfoMutator marks any modules for which this apex exports a file as requiring an apex
  287. // specific variant and checks that they are supported.
  288. //
  289. // The apexMutator will ensure that the ApexInfo objects passed to BuildForApex(ApexInfo) are
  290. // associated with the apex specific variant using the ApexInfoProvider for later retrieval.
  291. //
  292. // Unlike the source apex module type the prebuilt_apex module type cannot share compatible variants
  293. // across prebuilt_apex modules. That is because there is no way to determine whether two
  294. // prebuilt_apex modules that export files for the same module are compatible. e.g. they could have
  295. // been built from different source at different times or they could have been built with different
  296. // build options that affect the libraries.
  297. //
  298. // While it may be possible to provide sufficient information to determine whether two prebuilt_apex
  299. // modules were compatible it would be a lot of work and would not provide much benefit for a couple
  300. // of reasons:
  301. // * The number of prebuilt_apex modules that will be exporting files for the same module will be
  302. // low as the prebuilt_apex only exports files for the direct dependencies that require it and
  303. // very few modules are direct dependencies of multiple prebuilt_apex modules, e.g. there are a
  304. // few com.android.art* apex files that contain the same contents and could export files for the
  305. // same modules but only one of them needs to do so. Contrast that with source apex modules which
  306. // need apex specific variants for every module that contributes code to the apex, whether direct
  307. // or indirect.
  308. // * The build cost of a prebuilt_apex variant is generally low as at worst it will involve some
  309. // extra copying of files. Contrast that with source apex modules that has to build each variant
  310. // from source.
  311. func (p *prebuiltCommon) apexInfoMutator(mctx android.TopDownMutatorContext) {
  312. // Collect direct dependencies into contents.
  313. contents := make(map[string]android.ApexMembership)
  314. // Collect the list of dependencies.
  315. var dependencies []android.ApexModule
  316. mctx.WalkDeps(func(child, parent android.Module) bool {
  317. // If the child is not in the same apex as the parent then exit immediately and do not visit
  318. // any of the child's dependencies.
  319. if !android.IsDepInSameApex(mctx, parent, child) {
  320. return false
  321. }
  322. tag := mctx.OtherModuleDependencyTag(child)
  323. depName := mctx.OtherModuleName(child)
  324. if exportedTag, ok := tag.(exportedDependencyTag); ok {
  325. propertyName := exportedTag.name
  326. // It is an error if the other module is not a prebuilt.
  327. if !android.IsModulePrebuilt(child) {
  328. mctx.PropertyErrorf(propertyName, "%q is not a prebuilt module", depName)
  329. return false
  330. }
  331. // It is an error if the other module is not an ApexModule.
  332. if _, ok := child.(android.ApexModule); !ok {
  333. mctx.PropertyErrorf(propertyName, "%q is not usable within an apex", depName)
  334. return false
  335. }
  336. }
  337. // Ignore any modules that do not implement ApexModule as they cannot have an APEX specific
  338. // variant.
  339. if _, ok := child.(android.ApexModule); !ok {
  340. return false
  341. }
  342. // Strip off the prebuilt_ prefix if present before storing content to ensure consistent
  343. // behavior whether there is a corresponding source module present or not.
  344. depName = android.RemoveOptionalPrebuiltPrefix(depName)
  345. // Remember if this module was added as a direct dependency.
  346. direct := parent == mctx.Module()
  347. contents[depName] = contents[depName].Add(direct)
  348. // Add the module to the list of dependencies that need to have an APEX variant.
  349. dependencies = append(dependencies, child.(android.ApexModule))
  350. return true
  351. })
  352. // Create contents for the prebuilt_apex and store it away for later use.
  353. apexContents := android.NewApexContents(contents)
  354. mctx.SetProvider(ApexBundleInfoProvider, ApexBundleInfo{
  355. Contents: apexContents,
  356. })
  357. // Create an ApexInfo for the prebuilt_apex.
  358. apexVariationName := p.ApexVariationName()
  359. apexInfo := android.ApexInfo{
  360. ApexVariationName: apexVariationName,
  361. InApexVariants: []string{apexVariationName},
  362. InApexModules: []string{p.ModuleBase.BaseModuleName()}, // BaseModuleName() to avoid the prebuilt_ prefix.
  363. ApexContents: []*android.ApexContents{apexContents},
  364. ForPrebuiltApex: true,
  365. }
  366. // Mark the dependencies of this module as requiring a variant for this module.
  367. for _, am := range dependencies {
  368. am.BuildForApex(apexInfo)
  369. }
  370. }
  371. // prebuiltApexSelectorModule is a private module type that is only created by the prebuilt_apex
  372. // module. It selects the apex to use and makes it available for use by prebuilt_apex and the
  373. // deapexer.
  374. type prebuiltApexSelectorModule struct {
  375. android.ModuleBase
  376. apexFileProperties ApexFileProperties
  377. inputApex android.Path
  378. }
  379. func privateApexSelectorModuleFactory() android.Module {
  380. module := &prebuiltApexSelectorModule{}
  381. module.AddProperties(
  382. &module.apexFileProperties,
  383. )
  384. android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
  385. return module
  386. }
  387. func (p *prebuiltApexSelectorModule) Srcs() android.Paths {
  388. return android.Paths{p.inputApex}
  389. }
  390. func (p *prebuiltApexSelectorModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
  391. p.inputApex = android.SingleSourcePathFromSupplier(ctx, p.apexFileProperties.prebuiltApexSelector, "src")
  392. }
  393. type Prebuilt struct {
  394. prebuiltCommon
  395. properties PrebuiltProperties
  396. inputApex android.Path
  397. }
  398. type ApexFileProperties struct {
  399. // the path to the prebuilt .apex file to import.
  400. //
  401. // This cannot be marked as `android:"arch_variant"` because the `prebuilt_apex` is only mutated
  402. // for android_common. That is so that it will have the same arch variant as, and so be compatible
  403. // with, the source `apex` module type that it replaces.
  404. Src *string `android:"path"`
  405. Arch struct {
  406. Arm struct {
  407. Src *string `android:"path"`
  408. }
  409. Arm64 struct {
  410. Src *string `android:"path"`
  411. }
  412. X86 struct {
  413. Src *string `android:"path"`
  414. }
  415. X86_64 struct {
  416. Src *string `android:"path"`
  417. }
  418. }
  419. }
  420. // prebuiltApexSelector selects the correct prebuilt APEX file for the build target.
  421. //
  422. // The ctx parameter can be for any module not just the prebuilt module so care must be taken not
  423. // to use methods on it that are specific to the current module.
  424. //
  425. // See the ApexFileProperties.Src property.
  426. func (p *ApexFileProperties) prebuiltApexSelector(ctx android.BaseModuleContext, prebuilt android.Module) []string {
  427. multiTargets := prebuilt.MultiTargets()
  428. if len(multiTargets) != 1 {
  429. ctx.OtherModuleErrorf(prebuilt, "compile_multilib shouldn't be \"both\" for prebuilt_apex")
  430. return nil
  431. }
  432. var src string
  433. switch multiTargets[0].Arch.ArchType {
  434. case android.Arm:
  435. src = String(p.Arch.Arm.Src)
  436. case android.Arm64:
  437. src = String(p.Arch.Arm64.Src)
  438. case android.X86:
  439. src = String(p.Arch.X86.Src)
  440. case android.X86_64:
  441. src = String(p.Arch.X86_64.Src)
  442. }
  443. if src == "" {
  444. src = String(p.Src)
  445. }
  446. if src == "" {
  447. ctx.OtherModuleErrorf(prebuilt, "prebuilt_apex does not support %q", multiTargets[0].Arch.String())
  448. // Drop through to return an empty string as the src (instead of nil) to avoid the prebuilt
  449. // logic from reporting a more general, less useful message.
  450. }
  451. return []string{src}
  452. }
  453. type PrebuiltProperties struct {
  454. ApexFileProperties
  455. PrebuiltCommonProperties
  456. }
  457. func (a *Prebuilt) hasSanitizedSource(sanitizer string) bool {
  458. return false
  459. }
  460. func (p *Prebuilt) OutputFiles(tag string) (android.Paths, error) {
  461. switch tag {
  462. case "":
  463. return android.Paths{p.outputApex}, nil
  464. default:
  465. return nil, fmt.Errorf("unsupported module reference tag %q", tag)
  466. }
  467. }
  468. // prebuilt_apex imports an `.apex` file into the build graph as if it was built with apex.
  469. func PrebuiltFactory() android.Module {
  470. module := &Prebuilt{}
  471. module.AddProperties(&module.properties)
  472. module.initPrebuiltCommon(module, &module.properties.PrebuiltCommonProperties)
  473. return module
  474. }
  475. func createApexSelectorModule(ctx android.TopDownMutatorContext, name string, apexFileProperties *ApexFileProperties) {
  476. props := struct {
  477. Name *string
  478. }{
  479. Name: proptools.StringPtr(name),
  480. }
  481. ctx.CreateModule(privateApexSelectorModuleFactory,
  482. &props,
  483. apexFileProperties,
  484. )
  485. }
  486. // createDeapexerModuleIfNeeded will create a deapexer module if it is needed.
  487. //
  488. // A deapexer module is only needed when the prebuilt apex specifies one or more modules in either
  489. // the `exported_java_libs` or `exported_bootclasspath_fragments` properties as that indicates that
  490. // the listed modules need access to files from within the prebuilt .apex file.
  491. func (p *prebuiltCommon) createDeapexerModuleIfNeeded(ctx android.TopDownMutatorContext, deapexerName string, apexFileSource string) {
  492. // Only create the deapexer module if it is needed.
  493. if len(p.getExportedDependencies()) == 0 {
  494. return
  495. }
  496. // Compute the deapexer properties from the transitive dependencies of this module.
  497. commonModules := []string{}
  498. exportedFiles := []string{}
  499. ctx.WalkDeps(func(child, parent android.Module) bool {
  500. tag := ctx.OtherModuleDependencyTag(child)
  501. // If the child is not in the same apex as the parent then ignore it and all its children.
  502. if !android.IsDepInSameApex(ctx, parent, child) {
  503. return false
  504. }
  505. name := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(child))
  506. if _, ok := tag.(android.RequiresFilesFromPrebuiltApexTag); ok {
  507. commonModules = append(commonModules, name)
  508. requiredFiles := child.(android.RequiredFilesFromPrebuiltApex).RequiredFilesFromPrebuiltApex(ctx)
  509. exportedFiles = append(exportedFiles, requiredFiles...)
  510. // Visit the dependencies of this module just in case they also require files from the
  511. // prebuilt apex.
  512. return true
  513. }
  514. return false
  515. })
  516. // Create properties for deapexer module.
  517. deapexerProperties := &DeapexerProperties{
  518. // Remove any duplicates from the common modules lists as a module may be included via a direct
  519. // dependency as well as transitive ones.
  520. CommonModules: android.SortedUniqueStrings(commonModules),
  521. }
  522. // Populate the exported files property in a fixed order.
  523. deapexerProperties.ExportedFiles = android.SortedUniqueStrings(exportedFiles)
  524. props := struct {
  525. Name *string
  526. Selected_apex *string
  527. }{
  528. Name: proptools.StringPtr(deapexerName),
  529. Selected_apex: proptools.StringPtr(apexFileSource),
  530. }
  531. ctx.CreateModule(privateDeapexerFactory,
  532. &props,
  533. deapexerProperties,
  534. )
  535. }
  536. func apexSelectorModuleName(baseModuleName string) string {
  537. return baseModuleName + ".apex.selector"
  538. }
  539. func prebuiltApexExportedModuleName(ctx android.BottomUpMutatorContext, name string) string {
  540. // The prebuilt_apex should be depending on prebuilt modules but as this runs after
  541. // prebuilt_rename the prebuilt module may or may not be using the prebuilt_ prefixed named. So,
  542. // check to see if the prefixed name is in use first, if it is then use that, otherwise assume
  543. // the unprefixed name is the one to use. If the unprefixed one turns out to be a source module
  544. // and not a renamed prebuilt module then that will be detected and reported as an error when
  545. // processing the dependency in ApexInfoMutator().
  546. prebuiltName := android.PrebuiltNameFromSource(name)
  547. if ctx.OtherModuleExists(prebuiltName) {
  548. name = prebuiltName
  549. }
  550. return name
  551. }
  552. type exportedDependencyTag struct {
  553. blueprint.BaseDependencyTag
  554. name string
  555. }
  556. // Mark this tag so dependencies that use it are excluded from visibility enforcement.
  557. //
  558. // This does allow any prebuilt_apex to reference any module which does open up a small window for
  559. // restricted visibility modules to be referenced from the wrong prebuilt_apex. However, doing so
  560. // avoids opening up a much bigger window by widening the visibility of modules that need files
  561. // provided by the prebuilt_apex to include all the possible locations they may be defined, which
  562. // could include everything below vendor/.
  563. //
  564. // A prebuilt_apex that references a module via this tag will have to contain the appropriate files
  565. // corresponding to that module, otherwise it will fail when attempting to retrieve the files from
  566. // the .apex file. It will also have to be included in the module's apex_available property too.
  567. // That makes it highly unlikely that a prebuilt_apex would reference a restricted module
  568. // incorrectly.
  569. func (t exportedDependencyTag) ExcludeFromVisibilityEnforcement() {}
  570. func (t exportedDependencyTag) RequiresFilesFromPrebuiltApex() {}
  571. var _ android.RequiresFilesFromPrebuiltApexTag = exportedDependencyTag{}
  572. var (
  573. exportedJavaLibTag = exportedDependencyTag{name: "exported_java_libs"}
  574. exportedBootclasspathFragmentTag = exportedDependencyTag{name: "exported_bootclasspath_fragments"}
  575. exportedSystemserverclasspathFragmentTag = exportedDependencyTag{name: "exported_systemserverclasspath_fragments"}
  576. )
  577. var _ prebuiltApexModuleCreator = (*Prebuilt)(nil)
  578. // createPrebuiltApexModules creates modules necessary to export files from the prebuilt apex to the
  579. // build.
  580. //
  581. // If this needs to make files from within a `.apex` file available for use by other Soong modules,
  582. // e.g. make dex implementation jars available for java_import modules listed in exported_java_libs,
  583. // it does so as follows:
  584. //
  585. // 1. It creates a `deapexer` module that actually extracts the files from the `.apex` file and
  586. // makes them available for use by other modules, at both Soong and ninja levels.
  587. //
  588. // 2. It adds a dependency onto those modules and creates an apex specific variant similar to what
  589. // an `apex` module does. That ensures that code which looks for specific apex variant, e.g.
  590. // dexpreopt, will work the same way from source and prebuilt.
  591. //
  592. // 3. The `deapexer` module adds a dependency from the modules that require the exported files onto
  593. // itself so that they can retrieve the file paths to those files.
  594. //
  595. // It also creates a child module `selector` that is responsible for selecting the appropriate
  596. // input apex for both the prebuilt_apex and the deapexer. That is needed for a couple of reasons:
  597. // 1. To dedup the selection logic so it only runs in one module.
  598. // 2. To allow the deapexer to be wired up to a different source for the input apex, e.g. an
  599. // `apex_set`.
  600. //
  601. // prebuilt_apex
  602. // / | \
  603. // / | \
  604. // V V V
  605. // selector <--- deapexer <--- exported java lib
  606. //
  607. func (p *Prebuilt) createPrebuiltApexModules(ctx android.TopDownMutatorContext) {
  608. baseModuleName := p.BaseModuleName()
  609. apexSelectorModuleName := apexSelectorModuleName(baseModuleName)
  610. createApexSelectorModule(ctx, apexSelectorModuleName, &p.properties.ApexFileProperties)
  611. apexFileSource := ":" + apexSelectorModuleName
  612. p.createDeapexerModuleIfNeeded(ctx, deapexerModuleName(baseModuleName), apexFileSource)
  613. // Add a source reference to retrieve the selected apex from the selector module.
  614. p.prebuiltCommonProperties.Selected_apex = proptools.StringPtr(apexFileSource)
  615. }
  616. func (p *Prebuilt) ComponentDepsMutator(ctx android.BottomUpMutatorContext) {
  617. p.prebuiltApexContentsDeps(ctx)
  618. }
  619. var _ ApexInfoMutator = (*Prebuilt)(nil)
  620. func (p *Prebuilt) ApexInfoMutator(mctx android.TopDownMutatorContext) {
  621. p.apexInfoMutator(mctx)
  622. }
  623. func (p *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
  624. // TODO(jungjw): Check the key validity.
  625. p.inputApex = android.OptionalPathForModuleSrc(ctx, p.prebuiltCommonProperties.Selected_apex).Path()
  626. p.installDir = android.PathForModuleInstall(ctx, "apex")
  627. p.installFilename = p.InstallFilename()
  628. if !strings.HasSuffix(p.installFilename, imageApexSuffix) {
  629. ctx.ModuleErrorf("filename should end in %s for prebuilt_apex", imageApexSuffix)
  630. }
  631. p.outputApex = android.PathForModuleOut(ctx, p.installFilename)
  632. ctx.Build(pctx, android.BuildParams{
  633. Rule: android.Cp,
  634. Input: p.inputApex,
  635. Output: p.outputApex,
  636. })
  637. if p.prebuiltCommon.checkForceDisable(ctx) {
  638. p.HideFromMake()
  639. return
  640. }
  641. // Save the files that need to be made available to Make.
  642. p.initApexFilesForAndroidMk(ctx)
  643. // in case that prebuilt_apex replaces source apex (using prefer: prop)
  644. p.compatSymlinks = makeCompatSymlinks(p.BaseModuleName(), ctx, true)
  645. // or that prebuilt_apex overrides other apexes (using overrides: prop)
  646. for _, overridden := range p.prebuiltCommonProperties.Overrides {
  647. p.compatSymlinks = append(p.compatSymlinks, makeCompatSymlinks(overridden, ctx, true)...)
  648. }
  649. if p.installable() {
  650. p.installedFile = ctx.InstallFile(p.installDir, p.installFilename, p.inputApex, p.compatSymlinks.Paths()...)
  651. }
  652. }
  653. // prebuiltApexExtractorModule is a private module type that is only created by the prebuilt_apex
  654. // module. It extracts the correct apex to use and makes it available for use by apex_set.
  655. type prebuiltApexExtractorModule struct {
  656. android.ModuleBase
  657. properties ApexExtractorProperties
  658. extractedApex android.WritablePath
  659. }
  660. func privateApexExtractorModuleFactory() android.Module {
  661. module := &prebuiltApexExtractorModule{}
  662. module.AddProperties(
  663. &module.properties,
  664. )
  665. android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
  666. return module
  667. }
  668. func (p *prebuiltApexExtractorModule) Srcs() android.Paths {
  669. return android.Paths{p.extractedApex}
  670. }
  671. func (p *prebuiltApexExtractorModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
  672. srcsSupplier := func(ctx android.BaseModuleContext, prebuilt android.Module) []string {
  673. return p.properties.prebuiltSrcs(ctx)
  674. }
  675. apexSet := android.SingleSourcePathFromSupplier(ctx, srcsSupplier, "set")
  676. p.extractedApex = android.PathForModuleOut(ctx, "extracted", apexSet.Base())
  677. ctx.Build(pctx,
  678. android.BuildParams{
  679. Rule: extractMatchingApex,
  680. Description: "Extract an apex from an apex set",
  681. Inputs: android.Paths{apexSet},
  682. Output: p.extractedApex,
  683. Args: map[string]string{
  684. "abis": strings.Join(java.SupportedAbis(ctx), ","),
  685. "allow-prereleased": strconv.FormatBool(proptools.Bool(p.properties.Prerelease)),
  686. "sdk-version": ctx.Config().PlatformSdkVersion().String(),
  687. },
  688. })
  689. }
  690. type ApexSet struct {
  691. prebuiltCommon
  692. properties ApexSetProperties
  693. }
  694. type ApexExtractorProperties struct {
  695. // the .apks file path that contains prebuilt apex files to be extracted.
  696. Set *string
  697. Sanitized struct {
  698. None struct {
  699. Set *string
  700. }
  701. Address struct {
  702. Set *string
  703. }
  704. Hwaddress struct {
  705. Set *string
  706. }
  707. }
  708. // apexes in this set use prerelease SDK version
  709. Prerelease *bool
  710. }
  711. func (e *ApexExtractorProperties) prebuiltSrcs(ctx android.BaseModuleContext) []string {
  712. var srcs []string
  713. if e.Set != nil {
  714. srcs = append(srcs, *e.Set)
  715. }
  716. var sanitizers []string
  717. if ctx.Host() {
  718. sanitizers = ctx.Config().SanitizeHost()
  719. } else {
  720. sanitizers = ctx.Config().SanitizeDevice()
  721. }
  722. if android.InList("address", sanitizers) && e.Sanitized.Address.Set != nil {
  723. srcs = append(srcs, *e.Sanitized.Address.Set)
  724. } else if android.InList("hwaddress", sanitizers) && e.Sanitized.Hwaddress.Set != nil {
  725. srcs = append(srcs, *e.Sanitized.Hwaddress.Set)
  726. } else if e.Sanitized.None.Set != nil {
  727. srcs = append(srcs, *e.Sanitized.None.Set)
  728. }
  729. return srcs
  730. }
  731. type ApexSetProperties struct {
  732. ApexExtractorProperties
  733. PrebuiltCommonProperties
  734. }
  735. func (a *ApexSet) hasSanitizedSource(sanitizer string) bool {
  736. if sanitizer == "address" {
  737. return a.properties.Sanitized.Address.Set != nil
  738. }
  739. if sanitizer == "hwaddress" {
  740. return a.properties.Sanitized.Hwaddress.Set != nil
  741. }
  742. return false
  743. }
  744. // prebuilt_apex imports an `.apex` file into the build graph as if it was built with apex.
  745. func apexSetFactory() android.Module {
  746. module := &ApexSet{}
  747. module.AddProperties(&module.properties)
  748. module.initPrebuiltCommon(module, &module.properties.PrebuiltCommonProperties)
  749. return module
  750. }
  751. func createApexExtractorModule(ctx android.TopDownMutatorContext, name string, apexExtractorProperties *ApexExtractorProperties) {
  752. props := struct {
  753. Name *string
  754. }{
  755. Name: proptools.StringPtr(name),
  756. }
  757. ctx.CreateModule(privateApexExtractorModuleFactory,
  758. &props,
  759. apexExtractorProperties,
  760. )
  761. }
  762. func apexExtractorModuleName(baseModuleName string) string {
  763. return baseModuleName + ".apex.extractor"
  764. }
  765. var _ prebuiltApexModuleCreator = (*ApexSet)(nil)
  766. // createPrebuiltApexModules creates modules necessary to export files from the apex set to other
  767. // modules.
  768. //
  769. // This effectively does for apex_set what Prebuilt.createPrebuiltApexModules does for a
  770. // prebuilt_apex except that instead of creating a selector module which selects one .apex file
  771. // from those provided this creates an extractor module which extracts the appropriate .apex file
  772. // from the zip file containing them.
  773. func (a *ApexSet) createPrebuiltApexModules(ctx android.TopDownMutatorContext) {
  774. baseModuleName := a.BaseModuleName()
  775. apexExtractorModuleName := apexExtractorModuleName(baseModuleName)
  776. createApexExtractorModule(ctx, apexExtractorModuleName, &a.properties.ApexExtractorProperties)
  777. apexFileSource := ":" + apexExtractorModuleName
  778. a.createDeapexerModuleIfNeeded(ctx, deapexerModuleName(baseModuleName), apexFileSource)
  779. // After passing the arch specific src properties to the creating the apex selector module
  780. a.prebuiltCommonProperties.Selected_apex = proptools.StringPtr(apexFileSource)
  781. }
  782. func (a *ApexSet) ComponentDepsMutator(ctx android.BottomUpMutatorContext) {
  783. a.prebuiltApexContentsDeps(ctx)
  784. }
  785. var _ ApexInfoMutator = (*ApexSet)(nil)
  786. func (a *ApexSet) ApexInfoMutator(mctx android.TopDownMutatorContext) {
  787. a.apexInfoMutator(mctx)
  788. }
  789. func (a *ApexSet) GenerateAndroidBuildActions(ctx android.ModuleContext) {
  790. a.installFilename = a.InstallFilename()
  791. if !strings.HasSuffix(a.installFilename, imageApexSuffix) && !strings.HasSuffix(a.installFilename, imageCapexSuffix) {
  792. ctx.ModuleErrorf("filename should end in %s or %s for apex_set", imageApexSuffix, imageCapexSuffix)
  793. }
  794. inputApex := android.OptionalPathForModuleSrc(ctx, a.prebuiltCommonProperties.Selected_apex).Path()
  795. a.outputApex = android.PathForModuleOut(ctx, a.installFilename)
  796. ctx.Build(pctx, android.BuildParams{
  797. Rule: android.Cp,
  798. Input: inputApex,
  799. Output: a.outputApex,
  800. })
  801. if a.prebuiltCommon.checkForceDisable(ctx) {
  802. a.HideFromMake()
  803. return
  804. }
  805. // Save the files that need to be made available to Make.
  806. a.initApexFilesForAndroidMk(ctx)
  807. a.installDir = android.PathForModuleInstall(ctx, "apex")
  808. if a.installable() {
  809. a.installedFile = ctx.InstallFile(a.installDir, a.installFilename, a.outputApex)
  810. }
  811. // in case that apex_set replaces source apex (using prefer: prop)
  812. a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx, true)
  813. // or that apex_set overrides other apexes (using overrides: prop)
  814. for _, overridden := range a.prebuiltCommonProperties.Overrides {
  815. a.compatSymlinks = append(a.compatSymlinks, makeCompatSymlinks(overridden, ctx, true)...)
  816. }
  817. }
  818. type systemExtContext struct {
  819. android.ModuleContext
  820. }
  821. func (*systemExtContext) SystemExtSpecific() bool {
  822. return true
  823. }