aar.go 37 KB

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