aar.go 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913
  1. // Copyright 2018 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 java
  15. import (
  16. "fmt"
  17. "path/filepath"
  18. "strconv"
  19. "strings"
  20. "android/soong/android"
  21. "android/soong/dexpreopt"
  22. "github.com/google/blueprint"
  23. "github.com/google/blueprint/proptools"
  24. )
  25. type AndroidLibraryDependency interface {
  26. ExportPackage() android.Path
  27. ExportedProguardFlagFiles() android.Paths
  28. ExportedRRODirs() []rroDir
  29. ExportedStaticPackages() android.Paths
  30. ExportedManifests() android.Paths
  31. ExportedAssets() android.OptionalPath
  32. SetRROEnforcedForDependent(enforce bool)
  33. IsRROEnforced(ctx android.BaseModuleContext) bool
  34. }
  35. func init() {
  36. RegisterAARBuildComponents(android.InitRegistrationContext)
  37. }
  38. func RegisterAARBuildComponents(ctx android.RegistrationContext) {
  39. ctx.RegisterModuleType("android_library_import", AARImportFactory)
  40. ctx.RegisterModuleType("android_library", AndroidLibraryFactory)
  41. ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
  42. ctx.TopDown("propagate_rro_enforcement", propagateRROEnforcementMutator).Parallel()
  43. })
  44. }
  45. //
  46. // AAR (android library)
  47. //
  48. type androidLibraryProperties struct {
  49. BuildAAR bool `blueprint:"mutated"`
  50. }
  51. type aaptProperties struct {
  52. // flags passed to aapt when creating the apk
  53. Aaptflags []string
  54. // include all resource configurations, not just the product-configured
  55. // ones.
  56. Aapt_include_all_resources *bool
  57. // list of directories relative to the Blueprints file containing assets.
  58. // Defaults to ["assets"] if a directory called assets exists. Set to []
  59. // to disable the default.
  60. Asset_dirs []string
  61. // list of directories relative to the Blueprints file containing
  62. // Android resources. Defaults to ["res"] if a directory called res exists.
  63. // Set to [] to disable the default.
  64. Resource_dirs []string
  65. // list of zip files containing Android resources.
  66. Resource_zips []string `android:"path"`
  67. // path to AndroidManifest.xml. If unset, defaults to "AndroidManifest.xml".
  68. Manifest *string `android:"path"`
  69. // paths to additional manifest files to merge with main manifest.
  70. Additional_manifests []string `android:"path"`
  71. // do not include AndroidManifest from dependent libraries
  72. Dont_merge_manifests *bool
  73. // true if RRO is enforced for any of the dependent modules
  74. RROEnforcedForDependent bool `blueprint:"mutated"`
  75. }
  76. type aapt struct {
  77. aaptSrcJar android.Path
  78. exportPackage android.Path
  79. manifestPath android.Path
  80. transitiveManifestPaths android.Paths
  81. proguardOptionsFile android.Path
  82. rroDirs []rroDir
  83. rTxt android.Path
  84. extraAaptPackagesFile android.Path
  85. mergedManifestFile android.Path
  86. noticeFile android.OptionalPath
  87. assetPackage android.OptionalPath
  88. isLibrary bool
  89. defaultManifestVersion string
  90. useEmbeddedNativeLibs bool
  91. useEmbeddedDex bool
  92. usesNonSdkApis bool
  93. hasNoCode bool
  94. LoggingParent string
  95. resourceFiles android.Paths
  96. splitNames []string
  97. splits []split
  98. aaptProperties aaptProperties
  99. }
  100. type split struct {
  101. name string
  102. suffix string
  103. path android.Path
  104. }
  105. // Propagate RRO enforcement flag to static lib dependencies transitively.
  106. func propagateRROEnforcementMutator(ctx android.TopDownMutatorContext) {
  107. m := ctx.Module()
  108. if d, ok := m.(AndroidLibraryDependency); ok && d.IsRROEnforced(ctx) {
  109. ctx.VisitDirectDepsWithTag(staticLibTag, func(d android.Module) {
  110. if a, ok := d.(AndroidLibraryDependency); ok {
  111. a.SetRROEnforcedForDependent(true)
  112. }
  113. })
  114. }
  115. }
  116. func (a *aapt) ExportPackage() android.Path {
  117. return a.exportPackage
  118. }
  119. func (a *aapt) ExportedRRODirs() []rroDir {
  120. return a.rroDirs
  121. }
  122. func (a *aapt) ExportedManifests() android.Paths {
  123. return a.transitiveManifestPaths
  124. }
  125. func (a *aapt) ExportedAssets() android.OptionalPath {
  126. return a.assetPackage
  127. }
  128. func (a *aapt) SetRROEnforcedForDependent(enforce bool) {
  129. a.aaptProperties.RROEnforcedForDependent = enforce
  130. }
  131. func (a *aapt) IsRROEnforced(ctx android.BaseModuleContext) bool {
  132. // True if RRO is enforced for this module or...
  133. return ctx.Config().EnforceRROForModule(ctx.ModuleName()) ||
  134. // if RRO is enforced for any of its dependents.
  135. a.aaptProperties.RROEnforcedForDependent
  136. }
  137. func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext android.SdkContext,
  138. manifestPath android.Path) (compileFlags, linkFlags []string, linkDeps android.Paths,
  139. resDirs, overlayDirs []globbedResourceDir, rroDirs []rroDir, resZips android.Paths) {
  140. hasVersionCode := android.PrefixInList(a.aaptProperties.Aaptflags, "--version-code")
  141. hasVersionName := android.PrefixInList(a.aaptProperties.Aaptflags, "--version-name")
  142. // Flags specified in Android.bp
  143. linkFlags = append(linkFlags, a.aaptProperties.Aaptflags...)
  144. linkFlags = append(linkFlags, "--no-static-lib-packages")
  145. // Find implicit or explicit asset and resource dirs
  146. assetDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Asset_dirs, "assets")
  147. resourceDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Resource_dirs, "res")
  148. resourceZips := android.PathsForModuleSrc(ctx, a.aaptProperties.Resource_zips)
  149. // Glob directories into lists of paths
  150. for _, dir := range resourceDirs {
  151. resDirs = append(resDirs, globbedResourceDir{
  152. dir: dir,
  153. files: androidResourceGlob(ctx, dir),
  154. })
  155. resOverlayDirs, resRRODirs := overlayResourceGlob(ctx, a, dir)
  156. overlayDirs = append(overlayDirs, resOverlayDirs...)
  157. rroDirs = append(rroDirs, resRRODirs...)
  158. }
  159. var assetDeps android.Paths
  160. for i, dir := range assetDirs {
  161. // Add a dependency on every file in the asset directory. This ensures the aapt2
  162. // rule will be rerun if one of the files in the asset directory is modified.
  163. assetDeps = append(assetDeps, androidResourceGlob(ctx, dir)...)
  164. // Add a dependency on a file that contains a list of all the files in the asset directory.
  165. // This ensures the aapt2 rule will be run if a file is removed from the asset directory,
  166. // or a file is added whose timestamp is older than the output of aapt2.
  167. assetFileListFile := android.PathForModuleOut(ctx, "asset_dir_globs", strconv.Itoa(i)+".glob")
  168. androidResourceGlobList(ctx, dir, assetFileListFile)
  169. assetDeps = append(assetDeps, assetFileListFile)
  170. }
  171. assetDirStrings := assetDirs.Strings()
  172. if a.noticeFile.Valid() {
  173. assetDirStrings = append(assetDirStrings, filepath.Dir(a.noticeFile.Path().String()))
  174. assetDeps = append(assetDeps, a.noticeFile.Path())
  175. }
  176. linkFlags = append(linkFlags, "--manifest "+manifestPath.String())
  177. linkDeps = append(linkDeps, manifestPath)
  178. linkFlags = append(linkFlags, android.JoinWithPrefix(assetDirStrings, "-A "))
  179. linkDeps = append(linkDeps, assetDeps...)
  180. // SDK version flags
  181. minSdkVersion, err := sdkContext.MinSdkVersion(ctx).EffectiveVersionString(ctx)
  182. if err != nil {
  183. ctx.ModuleErrorf("invalid minSdkVersion: %s", err)
  184. }
  185. linkFlags = append(linkFlags, "--min-sdk-version "+minSdkVersion)
  186. linkFlags = append(linkFlags, "--target-sdk-version "+minSdkVersion)
  187. // Version code
  188. if !hasVersionCode {
  189. linkFlags = append(linkFlags, "--version-code", ctx.Config().PlatformSdkVersion().String())
  190. }
  191. if !hasVersionName {
  192. var versionName string
  193. if ctx.ModuleName() == "framework-res" {
  194. // Some builds set AppsDefaultVersionName() to include the build number ("O-123456"). aapt2 copies the
  195. // version name of framework-res into app manifests as compileSdkVersionCodename, which confuses things
  196. // if it contains the build number. Use the PlatformVersionName instead.
  197. versionName = ctx.Config().PlatformVersionName()
  198. } else {
  199. versionName = ctx.Config().AppsDefaultVersionName()
  200. }
  201. versionName = proptools.NinjaEscape(versionName)
  202. linkFlags = append(linkFlags, "--version-name ", versionName)
  203. }
  204. linkFlags, compileFlags = android.FilterList(linkFlags, []string{"--legacy"})
  205. // Always set --pseudo-localize, it will be stripped out later for release
  206. // builds that don't want it.
  207. compileFlags = append(compileFlags, "--pseudo-localize")
  208. return compileFlags, linkFlags, linkDeps, resDirs, overlayDirs, rroDirs, resourceZips
  209. }
  210. func (a *aapt) deps(ctx android.BottomUpMutatorContext, sdkDep sdkDep) {
  211. if sdkDep.frameworkResModule != "" {
  212. ctx.AddVariationDependencies(nil, frameworkResTag, sdkDep.frameworkResModule)
  213. }
  214. }
  215. var extractAssetsRule = pctx.AndroidStaticRule("extractAssets",
  216. blueprint.RuleParams{
  217. Command: `${config.Zip2ZipCmd} -i ${in} -o ${out} "assets/**/*"`,
  218. CommandDeps: []string{"${config.Zip2ZipCmd}"},
  219. })
  220. func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkContext,
  221. classLoaderContexts dexpreopt.ClassLoaderContextMap, excludedLibs []string,
  222. extraLinkFlags ...string) {
  223. transitiveStaticLibs, transitiveStaticLibManifests, staticRRODirs, assetPackages, libDeps, libFlags :=
  224. aaptLibs(ctx, sdkContext, classLoaderContexts)
  225. // Exclude any libraries from the supplied list.
  226. classLoaderContexts = classLoaderContexts.ExcludeLibs(excludedLibs)
  227. // App manifest file
  228. manifestFile := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml")
  229. manifestSrcPath := android.PathForModuleSrc(ctx, manifestFile)
  230. manifestPath := ManifestFixer(ctx, manifestSrcPath, ManifestFixerParams{
  231. SdkContext: sdkContext,
  232. ClassLoaderContexts: classLoaderContexts,
  233. IsLibrary: a.isLibrary,
  234. DefaultManifestVersion: a.defaultManifestVersion,
  235. UseEmbeddedNativeLibs: a.useEmbeddedNativeLibs,
  236. UsesNonSdkApis: a.usesNonSdkApis,
  237. UseEmbeddedDex: a.useEmbeddedDex,
  238. HasNoCode: a.hasNoCode,
  239. LoggingParent: a.LoggingParent,
  240. })
  241. // Add additional manifest files to transitive manifests.
  242. additionalManifests := android.PathsForModuleSrc(ctx, a.aaptProperties.Additional_manifests)
  243. a.transitiveManifestPaths = append(android.Paths{manifestPath}, additionalManifests...)
  244. a.transitiveManifestPaths = append(a.transitiveManifestPaths, transitiveStaticLibManifests...)
  245. if len(a.transitiveManifestPaths) > 1 && !Bool(a.aaptProperties.Dont_merge_manifests) {
  246. a.mergedManifestFile = manifestMerger(ctx, a.transitiveManifestPaths[0], a.transitiveManifestPaths[1:], a.isLibrary)
  247. if !a.isLibrary {
  248. // Only use the merged manifest for applications. For libraries, the transitive closure of manifests
  249. // will be propagated to the final application and merged there. The merged manifest for libraries is
  250. // only passed to Make, which can't handle transitive dependencies.
  251. manifestPath = a.mergedManifestFile
  252. }
  253. } else {
  254. a.mergedManifestFile = manifestPath
  255. }
  256. compileFlags, linkFlags, linkDeps, resDirs, overlayDirs, rroDirs, resZips := a.aapt2Flags(ctx, sdkContext, manifestPath)
  257. rroDirs = append(rroDirs, staticRRODirs...)
  258. linkFlags = append(linkFlags, libFlags...)
  259. linkDeps = append(linkDeps, libDeps...)
  260. linkFlags = append(linkFlags, extraLinkFlags...)
  261. if a.isLibrary {
  262. linkFlags = append(linkFlags, "--static-lib")
  263. }
  264. packageRes := android.PathForModuleOut(ctx, "package-res.apk")
  265. // the subdir "android" is required to be filtered by package names
  266. srcJar := android.PathForModuleGen(ctx, "android", "R.srcjar")
  267. proguardOptionsFile := android.PathForModuleGen(ctx, "proguard.options")
  268. rTxt := android.PathForModuleOut(ctx, "R.txt")
  269. // This file isn't used by Soong, but is generated for exporting
  270. extraPackages := android.PathForModuleOut(ctx, "extra_packages")
  271. var compiledResDirs []android.Paths
  272. for _, dir := range resDirs {
  273. a.resourceFiles = append(a.resourceFiles, dir.files...)
  274. compiledResDirs = append(compiledResDirs, aapt2Compile(ctx, dir.dir, dir.files, compileFlags).Paths())
  275. }
  276. for i, zip := range resZips {
  277. flata := android.PathForModuleOut(ctx, fmt.Sprintf("reszip.%d.flata", i))
  278. aapt2CompileZip(ctx, flata, zip, "", compileFlags)
  279. compiledResDirs = append(compiledResDirs, android.Paths{flata})
  280. }
  281. var compiledRes, compiledOverlay android.Paths
  282. compiledOverlay = append(compiledOverlay, transitiveStaticLibs...)
  283. if len(transitiveStaticLibs) > 0 {
  284. // If we are using static android libraries, every source file becomes an overlay.
  285. // This is to emulate old AAPT behavior which simulated library support.
  286. for _, compiledResDir := range compiledResDirs {
  287. compiledOverlay = append(compiledOverlay, compiledResDir...)
  288. }
  289. } else if a.isLibrary {
  290. // Otherwise, for a static library we treat all the resources equally with no overlay.
  291. for _, compiledResDir := range compiledResDirs {
  292. compiledRes = append(compiledRes, compiledResDir...)
  293. }
  294. } else if len(compiledResDirs) > 0 {
  295. // Without static libraries, the first directory is our directory, which can then be
  296. // overlaid by the rest.
  297. compiledRes = append(compiledRes, compiledResDirs[0]...)
  298. for _, compiledResDir := range compiledResDirs[1:] {
  299. compiledOverlay = append(compiledOverlay, compiledResDir...)
  300. }
  301. }
  302. for _, dir := range overlayDirs {
  303. compiledOverlay = append(compiledOverlay, aapt2Compile(ctx, dir.dir, dir.files, compileFlags).Paths()...)
  304. }
  305. var splitPackages android.WritablePaths
  306. var splits []split
  307. for _, s := range a.splitNames {
  308. suffix := strings.Replace(s, ",", "_", -1)
  309. path := android.PathForModuleOut(ctx, "package_"+suffix+".apk")
  310. linkFlags = append(linkFlags, "--split", path.String()+":"+s)
  311. splitPackages = append(splitPackages, path)
  312. splits = append(splits, split{
  313. name: s,
  314. suffix: suffix,
  315. path: path,
  316. })
  317. }
  318. aapt2Link(ctx, packageRes, srcJar, proguardOptionsFile, rTxt, extraPackages,
  319. linkFlags, linkDeps, compiledRes, compiledOverlay, assetPackages, splitPackages)
  320. // Extract assets from the resource package output so that they can be used later in aapt2link
  321. // for modules that depend on this one.
  322. if android.PrefixInList(linkFlags, "-A ") || len(assetPackages) > 0 {
  323. assets := android.PathForModuleOut(ctx, "assets.zip")
  324. ctx.Build(pctx, android.BuildParams{
  325. Rule: extractAssetsRule,
  326. Input: packageRes,
  327. Output: assets,
  328. Description: "extract assets from built resource file",
  329. })
  330. a.assetPackage = android.OptionalPathForPath(assets)
  331. }
  332. a.aaptSrcJar = srcJar
  333. a.exportPackage = packageRes
  334. a.manifestPath = manifestPath
  335. a.proguardOptionsFile = proguardOptionsFile
  336. a.rroDirs = rroDirs
  337. a.extraAaptPackagesFile = extraPackages
  338. a.rTxt = rTxt
  339. a.splits = splits
  340. }
  341. // aaptLibs collects libraries from dependencies and sdk_version and converts them into paths
  342. func aaptLibs(ctx android.ModuleContext, sdkContext android.SdkContext, classLoaderContexts dexpreopt.ClassLoaderContextMap) (
  343. transitiveStaticLibs, transitiveStaticLibManifests android.Paths, staticRRODirs []rroDir, assets, deps android.Paths, flags []string) {
  344. var sharedLibs android.Paths
  345. if classLoaderContexts == nil {
  346. // Not all callers need to compute class loader context, those who don't just pass nil.
  347. // Create a temporary class loader context here (it will be computed, but not used).
  348. classLoaderContexts = make(dexpreopt.ClassLoaderContextMap)
  349. }
  350. sdkDep := decodeSdkDep(ctx, sdkContext)
  351. if sdkDep.useFiles {
  352. sharedLibs = append(sharedLibs, sdkDep.jars...)
  353. }
  354. ctx.VisitDirectDeps(func(module android.Module) {
  355. depTag := ctx.OtherModuleDependencyTag(module)
  356. var exportPackage android.Path
  357. aarDep, _ := module.(AndroidLibraryDependency)
  358. if aarDep != nil {
  359. exportPackage = aarDep.ExportPackage()
  360. }
  361. switch depTag {
  362. case instrumentationForTag:
  363. // Nothing, instrumentationForTag is treated as libTag for javac but not for aapt2.
  364. case libTag:
  365. if exportPackage != nil {
  366. sharedLibs = append(sharedLibs, exportPackage)
  367. }
  368. case frameworkResTag:
  369. if exportPackage != nil {
  370. sharedLibs = append(sharedLibs, exportPackage)
  371. }
  372. case staticLibTag:
  373. if exportPackage != nil {
  374. transitiveStaticLibs = append(transitiveStaticLibs, aarDep.ExportedStaticPackages()...)
  375. transitiveStaticLibs = append(transitiveStaticLibs, exportPackage)
  376. transitiveStaticLibManifests = append(transitiveStaticLibManifests, aarDep.ExportedManifests()...)
  377. if aarDep.ExportedAssets().Valid() {
  378. assets = append(assets, aarDep.ExportedAssets().Path())
  379. }
  380. outer:
  381. for _, d := range aarDep.ExportedRRODirs() {
  382. for _, e := range staticRRODirs {
  383. if d.path == e.path {
  384. continue outer
  385. }
  386. }
  387. staticRRODirs = append(staticRRODirs, d)
  388. }
  389. }
  390. }
  391. addCLCFromDep(ctx, module, classLoaderContexts)
  392. })
  393. deps = append(deps, sharedLibs...)
  394. deps = append(deps, transitiveStaticLibs...)
  395. if len(transitiveStaticLibs) > 0 {
  396. flags = append(flags, "--auto-add-overlay")
  397. }
  398. for _, sharedLib := range sharedLibs {
  399. flags = append(flags, "-I "+sharedLib.String())
  400. }
  401. transitiveStaticLibs = android.FirstUniquePaths(transitiveStaticLibs)
  402. transitiveStaticLibManifests = android.FirstUniquePaths(transitiveStaticLibManifests)
  403. return transitiveStaticLibs, transitiveStaticLibManifests, staticRRODirs, assets, deps, flags
  404. }
  405. type AndroidLibrary struct {
  406. Library
  407. aapt
  408. androidLibraryProperties androidLibraryProperties
  409. aarFile android.WritablePath
  410. exportedProguardFlagFiles android.Paths
  411. exportedStaticPackages android.Paths
  412. }
  413. var _ android.OutputFileProducer = (*AndroidLibrary)(nil)
  414. // For OutputFileProducer interface
  415. func (a *AndroidLibrary) OutputFiles(tag string) (android.Paths, error) {
  416. switch tag {
  417. case ".aar":
  418. return []android.Path{a.aarFile}, nil
  419. default:
  420. return a.Library.OutputFiles(tag)
  421. }
  422. }
  423. func (a *AndroidLibrary) ExportedProguardFlagFiles() android.Paths {
  424. return a.exportedProguardFlagFiles
  425. }
  426. func (a *AndroidLibrary) ExportedStaticPackages() android.Paths {
  427. return a.exportedStaticPackages
  428. }
  429. var _ AndroidLibraryDependency = (*AndroidLibrary)(nil)
  430. func (a *AndroidLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
  431. a.Module.deps(ctx)
  432. sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
  433. if sdkDep.hasFrameworkLibs() {
  434. a.aapt.deps(ctx, sdkDep)
  435. }
  436. a.usesLibrary.deps(ctx, sdkDep.hasFrameworkLibs())
  437. }
  438. func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
  439. a.aapt.isLibrary = true
  440. a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
  441. a.aapt.buildActions(ctx, android.SdkContext(a), a.classLoaderContexts, nil)
  442. a.hideApexVariantFromMake = !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform()
  443. ctx.CheckbuildFile(a.proguardOptionsFile)
  444. ctx.CheckbuildFile(a.exportPackage)
  445. ctx.CheckbuildFile(a.aaptSrcJar)
  446. // apps manifests are handled by aapt, don't let Module see them
  447. a.properties.Manifest = nil
  448. a.linter.mergedManifest = a.aapt.mergedManifestFile
  449. a.linter.manifest = a.aapt.manifestPath
  450. a.linter.resources = a.aapt.resourceFiles
  451. a.Module.extraProguardFlagFiles = append(a.Module.extraProguardFlagFiles,
  452. a.proguardOptionsFile)
  453. a.Module.compile(ctx, a.aaptSrcJar)
  454. a.aarFile = android.PathForModuleOut(ctx, ctx.ModuleName()+".aar")
  455. var res android.Paths
  456. if a.androidLibraryProperties.BuildAAR {
  457. BuildAAR(ctx, a.aarFile, a.outputFile, a.manifestPath, a.rTxt, res)
  458. ctx.CheckbuildFile(a.aarFile)
  459. }
  460. a.exportedProguardFlagFiles = append(a.exportedProguardFlagFiles,
  461. android.PathsForModuleSrc(ctx, a.dexProperties.Optimize.Proguard_flags_files)...)
  462. ctx.VisitDirectDeps(func(m android.Module) {
  463. if lib, ok := m.(AndroidLibraryDependency); ok && ctx.OtherModuleDependencyTag(m) == staticLibTag {
  464. a.exportedProguardFlagFiles = append(a.exportedProguardFlagFiles, lib.ExportedProguardFlagFiles()...)
  465. a.exportedStaticPackages = append(a.exportedStaticPackages, lib.ExportPackage())
  466. a.exportedStaticPackages = append(a.exportedStaticPackages, lib.ExportedStaticPackages()...)
  467. }
  468. })
  469. a.exportedProguardFlagFiles = android.FirstUniquePaths(a.exportedProguardFlagFiles)
  470. a.exportedStaticPackages = android.FirstUniquePaths(a.exportedStaticPackages)
  471. }
  472. // android_library builds and links sources into a `.jar` file for the device along with Android resources.
  473. //
  474. // An android_library has a single variant that produces a `.jar` file containing `.class` files that were
  475. // compiled against the device bootclasspath, along with a `package-res.apk` file containing Android resources compiled
  476. // with aapt2. This module is not suitable for installing on a device, but can be used as a `static_libs` dependency of
  477. // an android_app module.
  478. func AndroidLibraryFactory() android.Module {
  479. module := &AndroidLibrary{}
  480. module.Module.addHostAndDeviceProperties()
  481. module.AddProperties(
  482. &module.aaptProperties,
  483. &module.androidLibraryProperties)
  484. module.androidLibraryProperties.BuildAAR = true
  485. module.Module.linter.library = true
  486. android.InitApexModule(module)
  487. InitJavaModule(module, android.DeviceSupported)
  488. return module
  489. }
  490. //
  491. // AAR (android library) prebuilts
  492. //
  493. // Properties for android_library_import
  494. type AARImportProperties struct {
  495. // ARR (android library prebuilt) filepath. Exactly one ARR is required.
  496. Aars []string `android:"path"`
  497. // If not blank, set to the version of the sdk to compile against.
  498. // Defaults to private.
  499. // Values are of one of the following forms:
  500. // 1) numerical API level, "current", "none", or "core_platform"
  501. // 2) An SDK kind with an API level: "<sdk kind>_<API level>"
  502. // See build/soong/android/sdk_version.go for the complete and up to date list of SDK kinds.
  503. // If the SDK kind is empty, it will be set to public
  504. Sdk_version *string
  505. // If not blank, set the minimum version of the sdk that the compiled artifacts will run against.
  506. // Defaults to sdk_version if not set. See sdk_version for possible values.
  507. Min_sdk_version *string
  508. // List of java static libraries that the included ARR (android library prebuilts) has dependencies to.
  509. Static_libs []string
  510. // List of java libraries that the included ARR (android library prebuilts) has dependencies to.
  511. Libs []string
  512. // If set to true, run Jetifier against .aar file. Defaults to false.
  513. Jetifier *bool
  514. }
  515. type AARImport struct {
  516. android.ModuleBase
  517. android.DefaultableModuleBase
  518. android.ApexModuleBase
  519. prebuilt android.Prebuilt
  520. // Functionality common to Module and Import.
  521. embeddableInModuleAndImport
  522. properties AARImportProperties
  523. classpathFile android.WritablePath
  524. proguardFlags android.WritablePath
  525. exportPackage android.WritablePath
  526. extraAaptPackagesFile android.WritablePath
  527. manifest android.WritablePath
  528. assetsPackage android.WritablePath
  529. exportedStaticPackages android.Paths
  530. hideApexVariantFromMake bool
  531. aarPath android.Path
  532. sdkVersion android.SdkSpec
  533. minSdkVersion android.SdkSpec
  534. }
  535. var _ android.OutputFileProducer = (*AARImport)(nil)
  536. // For OutputFileProducer interface
  537. func (a *AARImport) OutputFiles(tag string) (android.Paths, error) {
  538. switch tag {
  539. case ".aar":
  540. return []android.Path{a.aarPath}, nil
  541. case "":
  542. return []android.Path{a.classpathFile}, nil
  543. default:
  544. return nil, fmt.Errorf("unsupported module reference tag %q", tag)
  545. }
  546. }
  547. func (a *AARImport) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
  548. return android.SdkSpecFrom(ctx, String(a.properties.Sdk_version))
  549. }
  550. func (a *AARImport) SystemModules() string {
  551. return ""
  552. }
  553. func (a *AARImport) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
  554. if a.properties.Min_sdk_version != nil {
  555. return android.SdkSpecFrom(ctx, *a.properties.Min_sdk_version)
  556. }
  557. return a.SdkVersion(ctx)
  558. }
  559. func (a *AARImport) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.SdkSpec {
  560. return android.SdkSpecFrom(ctx, "")
  561. }
  562. func (a *AARImport) TargetSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
  563. return a.SdkVersion(ctx)
  564. }
  565. func (a *AARImport) javaVersion() string {
  566. return ""
  567. }
  568. var _ AndroidLibraryDependency = (*AARImport)(nil)
  569. func (a *AARImport) ExportPackage() android.Path {
  570. return a.exportPackage
  571. }
  572. func (a *AARImport) ExportedProguardFlagFiles() android.Paths {
  573. return android.Paths{a.proguardFlags}
  574. }
  575. func (a *AARImport) ExportedRRODirs() []rroDir {
  576. return nil
  577. }
  578. func (a *AARImport) ExportedStaticPackages() android.Paths {
  579. return a.exportedStaticPackages
  580. }
  581. func (a *AARImport) ExportedManifests() android.Paths {
  582. return android.Paths{a.manifest}
  583. }
  584. func (a *AARImport) ExportedAssets() android.OptionalPath {
  585. return android.OptionalPathForPath(a.assetsPackage)
  586. }
  587. // RRO enforcement is not available on aar_import since its RRO dirs are not
  588. // exported.
  589. func (a *AARImport) SetRROEnforcedForDependent(enforce bool) {
  590. }
  591. // RRO enforcement is not available on aar_import since its RRO dirs are not
  592. // exported.
  593. func (a *AARImport) IsRROEnforced(ctx android.BaseModuleContext) bool {
  594. return false
  595. }
  596. func (a *AARImport) Prebuilt() *android.Prebuilt {
  597. return &a.prebuilt
  598. }
  599. func (a *AARImport) Name() string {
  600. return a.prebuilt.Name(a.ModuleBase.Name())
  601. }
  602. func (a *AARImport) JacocoReportClassesFile() android.Path {
  603. return nil
  604. }
  605. func (a *AARImport) DepsMutator(ctx android.BottomUpMutatorContext) {
  606. if !ctx.Config().AlwaysUsePrebuiltSdks() {
  607. sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
  608. if sdkDep.useModule && sdkDep.frameworkResModule != "" {
  609. ctx.AddVariationDependencies(nil, frameworkResTag, sdkDep.frameworkResModule)
  610. }
  611. }
  612. ctx.AddVariationDependencies(nil, libTag, a.properties.Libs...)
  613. ctx.AddVariationDependencies(nil, staticLibTag, a.properties.Static_libs...)
  614. }
  615. // Unzip an AAR into its constituent files and directories. Any files in Outputs that don't exist in the AAR will be
  616. // touched to create an empty file. The res directory is not extracted, as it will be extracted in its own rule.
  617. var unzipAAR = pctx.AndroidStaticRule("unzipAAR",
  618. blueprint.RuleParams{
  619. Command: `rm -rf $outDir && mkdir -p $outDir && ` +
  620. `unzip -qoDD -d $outDir $in && rm -rf $outDir/res && touch $out && ` +
  621. `${config.Zip2ZipCmd} -i $in -o $assetsPackage 'assets/**/*' && ` +
  622. `${config.MergeZipsCmd} $combinedClassesJar $$(ls $outDir/classes.jar 2> /dev/null) $$(ls $outDir/libs/*.jar 2> /dev/null)`,
  623. CommandDeps: []string{"${config.MergeZipsCmd}", "${config.Zip2ZipCmd}"},
  624. },
  625. "outDir", "combinedClassesJar", "assetsPackage")
  626. func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
  627. if len(a.properties.Aars) != 1 {
  628. ctx.PropertyErrorf("aars", "exactly one aar is required")
  629. return
  630. }
  631. a.sdkVersion = a.SdkVersion(ctx)
  632. a.minSdkVersion = a.MinSdkVersion(ctx)
  633. a.hideApexVariantFromMake = !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform()
  634. aarName := ctx.ModuleName() + ".aar"
  635. a.aarPath = android.PathForModuleSrc(ctx, a.properties.Aars[0])
  636. if Bool(a.properties.Jetifier) {
  637. inputFile := a.aarPath
  638. a.aarPath = android.PathForModuleOut(ctx, "jetifier", aarName)
  639. TransformJetifier(ctx, a.aarPath.(android.WritablePath), inputFile)
  640. }
  641. extractedAARDir := android.PathForModuleOut(ctx, "aar")
  642. a.classpathFile = extractedAARDir.Join(ctx, "classes-combined.jar")
  643. a.proguardFlags = extractedAARDir.Join(ctx, "proguard.txt")
  644. a.manifest = extractedAARDir.Join(ctx, "AndroidManifest.xml")
  645. a.assetsPackage = android.PathForModuleOut(ctx, "assets.zip")
  646. ctx.Build(pctx, android.BuildParams{
  647. Rule: unzipAAR,
  648. Input: a.aarPath,
  649. Outputs: android.WritablePaths{a.classpathFile, a.proguardFlags, a.manifest, a.assetsPackage},
  650. Description: "unzip AAR",
  651. Args: map[string]string{
  652. "outDir": extractedAARDir.String(),
  653. "combinedClassesJar": a.classpathFile.String(),
  654. "assetsPackage": a.assetsPackage.String(),
  655. },
  656. })
  657. // Always set --pseudo-localize, it will be stripped out later for release
  658. // builds that don't want it.
  659. compileFlags := []string{"--pseudo-localize"}
  660. compiledResDir := android.PathForModuleOut(ctx, "flat-res")
  661. flata := compiledResDir.Join(ctx, "gen_res.flata")
  662. aapt2CompileZip(ctx, flata, a.aarPath, "res", compileFlags)
  663. a.exportPackage = android.PathForModuleOut(ctx, "package-res.apk")
  664. // the subdir "android" is required to be filtered by package names
  665. srcJar := android.PathForModuleGen(ctx, "android", "R.srcjar")
  666. proguardOptionsFile := android.PathForModuleGen(ctx, "proguard.options")
  667. rTxt := android.PathForModuleOut(ctx, "R.txt")
  668. a.extraAaptPackagesFile = android.PathForModuleOut(ctx, "extra_packages")
  669. var linkDeps android.Paths
  670. linkFlags := []string{
  671. "--static-lib",
  672. "--no-static-lib-packages",
  673. "--auto-add-overlay",
  674. }
  675. linkFlags = append(linkFlags, "--manifest "+a.manifest.String())
  676. linkDeps = append(linkDeps, a.manifest)
  677. transitiveStaticLibs, staticLibManifests, staticRRODirs, transitiveAssets, libDeps, libFlags :=
  678. aaptLibs(ctx, android.SdkContext(a), nil)
  679. _ = staticLibManifests
  680. _ = staticRRODirs
  681. linkDeps = append(linkDeps, libDeps...)
  682. linkFlags = append(linkFlags, libFlags...)
  683. overlayRes := append(android.Paths{flata}, transitiveStaticLibs...)
  684. aapt2Link(ctx, a.exportPackage, srcJar, proguardOptionsFile, rTxt, a.extraAaptPackagesFile,
  685. linkFlags, linkDeps, nil, overlayRes, transitiveAssets, nil)
  686. // Merge this import's assets with its dependencies' assets (if there are any).
  687. if len(transitiveAssets) > 0 {
  688. mergedAssets := android.PathForModuleOut(ctx, "merged-assets.zip")
  689. inputZips := append(android.Paths{a.assetsPackage}, transitiveAssets...)
  690. ctx.Build(pctx, android.BuildParams{
  691. Rule: mergeAssetsRule,
  692. Inputs: inputZips,
  693. Output: mergedAssets,
  694. Description: "merge assets from dependencies and self",
  695. })
  696. a.assetsPackage = mergedAssets
  697. }
  698. ctx.SetProvider(JavaInfoProvider, JavaInfo{
  699. HeaderJars: android.PathsIfNonNil(a.classpathFile),
  700. ImplementationAndResourcesJars: android.PathsIfNonNil(a.classpathFile),
  701. ImplementationJars: android.PathsIfNonNil(a.classpathFile),
  702. })
  703. }
  704. func (a *AARImport) HeaderJars() android.Paths {
  705. return android.Paths{a.classpathFile}
  706. }
  707. func (a *AARImport) ImplementationAndResourcesJars() android.Paths {
  708. return android.Paths{a.classpathFile}
  709. }
  710. func (a *AARImport) DexJarBuildPath() android.Path {
  711. return nil
  712. }
  713. func (a *AARImport) DexJarInstallPath() android.Path {
  714. return nil
  715. }
  716. func (a *AARImport) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap {
  717. return nil
  718. }
  719. var _ android.ApexModule = (*AARImport)(nil)
  720. // Implements android.ApexModule
  721. func (a *AARImport) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
  722. return a.depIsInSameApex(ctx, dep)
  723. }
  724. // Implements android.ApexModule
  725. func (g *AARImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
  726. sdkVersion android.ApiLevel) error {
  727. return nil
  728. }
  729. var _ android.PrebuiltInterface = (*AARImport)(nil)
  730. // android_library_import imports an `.aar` file into the build graph as if it was built with android_library.
  731. //
  732. // This module is not suitable for installing on a device, but can be used as a `static_libs` dependency of
  733. // an android_app module.
  734. func AARImportFactory() android.Module {
  735. module := &AARImport{}
  736. module.AddProperties(&module.properties)
  737. android.InitPrebuiltModule(module, &module.properties.Aars)
  738. android.InitApexModule(module)
  739. InitJavaModule(module, android.DeviceSupported)
  740. return module
  741. }