dexpreopt_bootjars.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  1. // Copyright 2019 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. "path/filepath"
  17. "strings"
  18. "android/soong/android"
  19. "android/soong/dexpreopt"
  20. "github.com/google/blueprint/proptools"
  21. )
  22. func init() {
  23. android.RegisterSingletonType("dex_bootjars", dexpreoptBootJarsFactory)
  24. }
  25. // The image "location" is a symbolic path that with multiarchitecture
  26. // support doesn't really exist on the device. Typically it is
  27. // /system/framework/boot.art and should be the same for all supported
  28. // architectures on the device. The concrete architecture specific
  29. // content actually ends up in a "filename" that contains an
  30. // architecture specific directory name such as arm, arm64, x86, x86_64.
  31. //
  32. // Here are some example values for an x86_64 / x86 configuration:
  33. //
  34. // bootImages["x86_64"] = "out/soong/generic_x86_64/dex_bootjars/system/framework/x86_64/boot.art"
  35. // dexpreopt.PathToLocation(bootImages["x86_64"], "x86_64") = "out/soong/generic_x86_64/dex_bootjars/system/framework/boot.art"
  36. //
  37. // bootImages["x86"] = "out/soong/generic_x86_64/dex_bootjars/system/framework/x86/boot.art"
  38. // dexpreopt.PathToLocation(bootImages["x86"])= "out/soong/generic_x86_64/dex_bootjars/system/framework/boot.art"
  39. //
  40. // The location is passed as an argument to the ART tools like dex2oat instead of the real path. The ART tools
  41. // will then reconstruct the real path, so the rules must have a dependency on the real path.
  42. // Target-independent description of pre-compiled boot image.
  43. type bootImageConfig struct {
  44. // Whether this image is an extension.
  45. extension bool
  46. // Image name (used in directory names and ninja rule names).
  47. name string
  48. // Basename of the image: the resulting filenames are <stem>[-<jar>].{art,oat,vdex}.
  49. stem string
  50. // Output directory for the image files.
  51. dir android.OutputPath
  52. // Output directory for the image files with debug symbols.
  53. symbolsDir android.OutputPath
  54. // Subdirectory where the image files are installed.
  55. installSubdir string
  56. // The names of jars that constitute this image.
  57. modules []string
  58. // The "locations" of jars.
  59. dexLocations []string // for this image
  60. dexLocationsDeps []string // for the dependency images and in this image
  61. // File paths to jars.
  62. dexPaths android.WritablePaths // for this image
  63. dexPathsDeps android.WritablePaths // for the dependency images and in this image
  64. // The "locations" of the dependency images and in this image.
  65. imageLocations []string
  66. // File path to a zip archive with all image files (or nil, if not needed).
  67. zip android.WritablePath
  68. // Rules which should be used in make to install the outputs.
  69. profileInstalls android.RuleBuilderInstalls
  70. // Target-dependent fields.
  71. variants []*bootImageVariant
  72. }
  73. // Target-dependent description of pre-compiled boot image.
  74. type bootImageVariant struct {
  75. *bootImageConfig
  76. // Target for which the image is generated.
  77. target android.Target
  78. // Paths to image files.
  79. images android.OutputPath // first image file
  80. imagesDeps android.OutputPaths // all files
  81. // Only for extensions, paths to the primary boot images.
  82. primaryImages android.OutputPath
  83. // Rules which should be used in make to install the outputs.
  84. installs android.RuleBuilderInstalls
  85. vdexInstalls android.RuleBuilderInstalls
  86. unstrippedInstalls android.RuleBuilderInstalls
  87. }
  88. func (image bootImageConfig) getVariant(target android.Target) *bootImageVariant {
  89. for _, variant := range image.variants {
  90. if variant.target.Os == target.Os && variant.target.Arch.ArchType == target.Arch.ArchType {
  91. return variant
  92. }
  93. }
  94. return nil
  95. }
  96. func (image bootImageConfig) moduleName(idx int) string {
  97. // Dexpreopt on the boot class path produces multiple files. The first dex file
  98. // is converted into 'name'.art (to match the legacy assumption that 'name'.art
  99. // exists), and the rest are converted to 'name'-<jar>.art.
  100. m := image.modules[idx]
  101. name := image.stem
  102. if idx != 0 || image.extension {
  103. name += "-" + stemOf(m)
  104. }
  105. return name
  106. }
  107. func (image bootImageConfig) firstModuleNameOrStem() string {
  108. if len(image.modules) > 0 {
  109. return image.moduleName(0)
  110. } else {
  111. return image.stem
  112. }
  113. }
  114. func (image bootImageConfig) moduleFiles(ctx android.PathContext, dir android.OutputPath, exts ...string) android.OutputPaths {
  115. ret := make(android.OutputPaths, 0, len(image.modules)*len(exts))
  116. for i := range image.modules {
  117. name := image.moduleName(i)
  118. for _, ext := range exts {
  119. ret = append(ret, dir.Join(ctx, name+ext))
  120. }
  121. }
  122. return ret
  123. }
  124. func concat(lists ...[]string) []string {
  125. var size int
  126. for _, l := range lists {
  127. size += len(l)
  128. }
  129. ret := make([]string, 0, size)
  130. for _, l := range lists {
  131. ret = append(ret, l...)
  132. }
  133. return ret
  134. }
  135. func dexpreoptBootJarsFactory() android.Singleton {
  136. return &dexpreoptBootJars{}
  137. }
  138. func skipDexpreoptBootJars(ctx android.PathContext) bool {
  139. if dexpreopt.GetGlobalConfig(ctx).DisablePreopt {
  140. return true
  141. }
  142. if ctx.Config().UnbundledBuild() {
  143. return true
  144. }
  145. if len(ctx.Config().Targets[android.Android]) == 0 {
  146. // Host-only build
  147. return true
  148. }
  149. return false
  150. }
  151. type dexpreoptBootJars struct {
  152. defaultBootImage *bootImageConfig
  153. otherImages []*bootImageConfig
  154. dexpreoptConfigForMake android.WritablePath
  155. }
  156. // Accessor function for the apex package. Returns nil if dexpreopt is disabled.
  157. func DexpreoptedArtApexJars(ctx android.BuilderContext) map[android.ArchType]android.OutputPaths {
  158. if skipDexpreoptBootJars(ctx) {
  159. return nil
  160. }
  161. // Include dexpreopt files for the primary boot image.
  162. files := map[android.ArchType]android.OutputPaths{}
  163. for _, variant := range artBootImageConfig(ctx).variants {
  164. files[variant.target.Arch.ArchType] = variant.imagesDeps
  165. }
  166. return files
  167. }
  168. // dexpreoptBoot singleton rules
  169. func (d *dexpreoptBootJars) GenerateBuildActions(ctx android.SingletonContext) {
  170. if skipDexpreoptBootJars(ctx) {
  171. return
  172. }
  173. if dexpreopt.GetCachedGlobalSoongConfig(ctx) == nil {
  174. // No module has enabled dexpreopting, so we assume there will be no boot image to make.
  175. return
  176. }
  177. d.dexpreoptConfigForMake = android.PathForOutput(ctx, ctx.Config().DeviceName(), "dexpreopt.config")
  178. writeGlobalConfigForMake(ctx, d.dexpreoptConfigForMake)
  179. global := dexpreopt.GetGlobalConfig(ctx)
  180. // Skip recompiling the boot image for the second sanitization phase. We'll get separate paths
  181. // and invalidate first-stage artifacts which are crucial to SANITIZE_LITE builds.
  182. // Note: this is technically incorrect. Compiled code contains stack checks which may depend
  183. // on ASAN settings.
  184. if len(ctx.Config().SanitizeDevice()) == 1 &&
  185. ctx.Config().SanitizeDevice()[0] == "address" &&
  186. global.SanitizeLite {
  187. return
  188. }
  189. // Always create the default boot image first, to get a unique profile rule for all images.
  190. d.defaultBootImage = buildBootImage(ctx, defaultBootImageConfig(ctx))
  191. // Create boot image for the ART apex (build artifacts are accessed via the global boot image config).
  192. d.otherImages = append(d.otherImages, buildBootImage(ctx, artBootImageConfig(ctx)))
  193. dumpOatRules(ctx, d.defaultBootImage)
  194. }
  195. // buildBootImage takes a bootImageConfig, creates rules to build it, and returns the image.
  196. func buildBootImage(ctx android.SingletonContext, image *bootImageConfig) *bootImageConfig {
  197. bootDexJars := make(android.Paths, len(image.modules))
  198. ctx.VisitAllModules(func(module android.Module) {
  199. // Collect dex jar paths for the modules listed above.
  200. if j, ok := module.(interface{ DexJar() android.Path }); ok {
  201. name := ctx.ModuleName(module)
  202. if i := android.IndexList(name, image.modules); i != -1 {
  203. bootDexJars[i] = j.DexJar()
  204. }
  205. }
  206. })
  207. var missingDeps []string
  208. // Ensure all modules were converted to paths
  209. for i := range bootDexJars {
  210. if bootDexJars[i] == nil {
  211. if ctx.Config().AllowMissingDependencies() {
  212. missingDeps = append(missingDeps, image.modules[i])
  213. bootDexJars[i] = android.PathForOutput(ctx, "missing")
  214. } else {
  215. ctx.Errorf("failed to find dex jar path for module %q",
  216. image.modules[i])
  217. }
  218. }
  219. }
  220. // The path to bootclasspath dex files needs to be known at module GenerateAndroidBuildAction time, before
  221. // the bootclasspath modules have been compiled. Copy the dex jars there so the module rules that have
  222. // already been set up can find them.
  223. for i := range bootDexJars {
  224. ctx.Build(pctx, android.BuildParams{
  225. Rule: android.Cp,
  226. Input: bootDexJars[i],
  227. Output: image.dexPaths[i],
  228. })
  229. }
  230. profile := bootImageProfileRule(ctx, image, missingDeps)
  231. bootFrameworkProfileRule(ctx, image, missingDeps)
  232. var allFiles android.Paths
  233. for _, variant := range image.variants {
  234. files := buildBootImageVariant(ctx, variant, profile, missingDeps)
  235. allFiles = append(allFiles, files.Paths()...)
  236. }
  237. if image.zip != nil {
  238. rule := android.NewRuleBuilder()
  239. rule.Command().
  240. BuiltTool(ctx, "soong_zip").
  241. FlagWithOutput("-o ", image.zip).
  242. FlagWithArg("-C ", image.dir.String()).
  243. FlagWithInputList("-f ", allFiles, " -f ")
  244. rule.Build(pctx, ctx, "zip_"+image.name, "zip "+image.name+" image")
  245. }
  246. return image
  247. }
  248. func buildBootImageVariant(ctx android.SingletonContext, image *bootImageVariant,
  249. profile android.Path, missingDeps []string) android.WritablePaths {
  250. globalSoong := dexpreopt.GetCachedGlobalSoongConfig(ctx)
  251. global := dexpreopt.GetGlobalConfig(ctx)
  252. arch := image.target.Arch.ArchType
  253. symbolsDir := image.symbolsDir.Join(ctx, image.installSubdir, arch.String())
  254. symbolsFile := symbolsDir.Join(ctx, image.stem+".oat")
  255. outputDir := image.dir.Join(ctx, image.installSubdir, arch.String())
  256. outputPath := outputDir.Join(ctx, image.stem+".oat")
  257. oatLocation := dexpreopt.PathToLocation(outputPath, arch)
  258. imagePath := outputPath.ReplaceExtension(ctx, "art")
  259. rule := android.NewRuleBuilder()
  260. rule.MissingDeps(missingDeps)
  261. rule.Command().Text("mkdir").Flag("-p").Flag(symbolsDir.String())
  262. rule.Command().Text("rm").Flag("-f").
  263. Flag(symbolsDir.Join(ctx, "*.art").String()).
  264. Flag(symbolsDir.Join(ctx, "*.oat").String()).
  265. Flag(symbolsDir.Join(ctx, "*.invocation").String())
  266. rule.Command().Text("rm").Flag("-f").
  267. Flag(outputDir.Join(ctx, "*.art").String()).
  268. Flag(outputDir.Join(ctx, "*.oat").String()).
  269. Flag(outputDir.Join(ctx, "*.invocation").String())
  270. cmd := rule.Command()
  271. extraFlags := ctx.Config().Getenv("ART_BOOT_IMAGE_EXTRA_ARGS")
  272. if extraFlags == "" {
  273. // Use ANDROID_LOG_TAGS to suppress most logging by default...
  274. cmd.Text(`ANDROID_LOG_TAGS="*:e"`)
  275. } else {
  276. // ...unless the boot image is generated specifically for testing, then allow all logging.
  277. cmd.Text(`ANDROID_LOG_TAGS="*:v"`)
  278. }
  279. invocationPath := outputPath.ReplaceExtension(ctx, "invocation")
  280. cmd.Tool(globalSoong.Dex2oat).
  281. Flag("--avoid-storing-invocation").
  282. FlagWithOutput("--write-invocation-to=", invocationPath).ImplicitOutput(invocationPath).
  283. Flag("--runtime-arg").FlagWithArg("-Xms", global.Dex2oatImageXms).
  284. Flag("--runtime-arg").FlagWithArg("-Xmx", global.Dex2oatImageXmx)
  285. if profile != nil {
  286. cmd.FlagWithArg("--compiler-filter=", "speed-profile")
  287. cmd.FlagWithInput("--profile-file=", profile)
  288. }
  289. if global.DirtyImageObjects.Valid() {
  290. cmd.FlagWithInput("--dirty-image-objects=", global.DirtyImageObjects.Path())
  291. }
  292. if image.extension {
  293. artImage := image.primaryImages
  294. cmd.
  295. Flag("--runtime-arg").FlagWithInputList("-Xbootclasspath:", image.dexPathsDeps.Paths(), ":").
  296. Flag("--runtime-arg").FlagWithList("-Xbootclasspath-locations:", image.dexLocationsDeps, ":").
  297. FlagWithArg("--boot-image=", dexpreopt.PathToLocation(artImage, arch)).Implicit(artImage)
  298. } else {
  299. cmd.FlagWithArg("--base=", ctx.Config().LibartImgDeviceBaseAddress())
  300. }
  301. cmd.
  302. FlagForEachInput("--dex-file=", image.dexPaths.Paths()).
  303. FlagForEachArg("--dex-location=", image.dexLocations).
  304. Flag("--generate-debug-info").
  305. Flag("--generate-build-id").
  306. Flag("--image-format=lz4hc").
  307. FlagWithArg("--oat-symbols=", symbolsFile.String()).
  308. Flag("--strip").
  309. FlagWithArg("--oat-file=", outputPath.String()).
  310. FlagWithArg("--oat-location=", oatLocation).
  311. FlagWithArg("--image=", imagePath.String()).
  312. FlagWithArg("--instruction-set=", arch.String()).
  313. FlagWithArg("--instruction-set-variant=", global.CpuVariant[arch]).
  314. FlagWithArg("--instruction-set-features=", global.InstructionSetFeatures[arch]).
  315. FlagWithArg("--android-root=", global.EmptyDirectory).
  316. FlagWithArg("--no-inline-from=", "core-oj.jar").
  317. Flag("--abort-on-hard-verifier-error")
  318. if global.BootFlags != "" {
  319. cmd.Flag(global.BootFlags)
  320. }
  321. if extraFlags != "" {
  322. cmd.Flag(extraFlags)
  323. }
  324. cmd.Textf(`|| ( echo %s ; false )`, proptools.ShellEscape(failureMessage))
  325. installDir := filepath.Join("/", image.installSubdir, arch.String())
  326. vdexInstallDir := filepath.Join("/", image.installSubdir)
  327. var vdexInstalls android.RuleBuilderInstalls
  328. var unstrippedInstalls android.RuleBuilderInstalls
  329. var zipFiles android.WritablePaths
  330. for _, artOrOat := range image.moduleFiles(ctx, outputDir, ".art", ".oat") {
  331. cmd.ImplicitOutput(artOrOat)
  332. zipFiles = append(zipFiles, artOrOat)
  333. // Install the .oat and .art files
  334. rule.Install(artOrOat, filepath.Join(installDir, artOrOat.Base()))
  335. }
  336. for _, vdex := range image.moduleFiles(ctx, outputDir, ".vdex") {
  337. cmd.ImplicitOutput(vdex)
  338. zipFiles = append(zipFiles, vdex)
  339. // The vdex files are identical between architectures, install them to a shared location. The Make rules will
  340. // only use the install rules for one architecture, and will create symlinks into the architecture-specific
  341. // directories.
  342. vdexInstalls = append(vdexInstalls,
  343. android.RuleBuilderInstall{vdex, filepath.Join(vdexInstallDir, vdex.Base())})
  344. }
  345. for _, unstrippedOat := range image.moduleFiles(ctx, symbolsDir, ".oat") {
  346. cmd.ImplicitOutput(unstrippedOat)
  347. // Install the unstripped oat files. The Make rules will put these in $(TARGET_OUT_UNSTRIPPED)
  348. unstrippedInstalls = append(unstrippedInstalls,
  349. android.RuleBuilderInstall{unstrippedOat, filepath.Join(installDir, unstrippedOat.Base())})
  350. }
  351. rule.Build(pctx, ctx, image.name+"JarsDexpreopt_"+arch.String(), "dexpreopt "+image.name+" jars "+arch.String())
  352. // save output and installed files for makevars
  353. image.installs = rule.Installs()
  354. image.vdexInstalls = vdexInstalls
  355. image.unstrippedInstalls = unstrippedInstalls
  356. return zipFiles
  357. }
  358. const failureMessage = `ERROR: Dex2oat failed to compile a boot image.
  359. It is likely that the boot classpath is inconsistent.
  360. Rebuild with ART_BOOT_IMAGE_EXTRA_ARGS="--runtime-arg -verbose:verifier" to see verification errors.`
  361. func bootImageProfileRule(ctx android.SingletonContext, image *bootImageConfig, missingDeps []string) android.WritablePath {
  362. globalSoong := dexpreopt.GetCachedGlobalSoongConfig(ctx)
  363. global := dexpreopt.GetGlobalConfig(ctx)
  364. if global.DisableGenerateProfile || ctx.Config().IsPdkBuild() || ctx.Config().UnbundledBuild() {
  365. return nil
  366. }
  367. profile := ctx.Config().Once(bootImageProfileRuleKey, func() interface{} {
  368. defaultProfile := "frameworks/base/config/boot-image-profile.txt"
  369. rule := android.NewRuleBuilder()
  370. rule.MissingDeps(missingDeps)
  371. var bootImageProfile android.Path
  372. if len(global.BootImageProfiles) > 1 {
  373. combinedBootImageProfile := image.dir.Join(ctx, "boot-image-profile.txt")
  374. rule.Command().Text("cat").Inputs(global.BootImageProfiles).Text(">").Output(combinedBootImageProfile)
  375. bootImageProfile = combinedBootImageProfile
  376. } else if len(global.BootImageProfiles) == 1 {
  377. bootImageProfile = global.BootImageProfiles[0]
  378. } else if path := android.ExistentPathForSource(ctx, defaultProfile); path.Valid() {
  379. bootImageProfile = path.Path()
  380. } else {
  381. // No profile (not even a default one, which is the case on some branches
  382. // like master-art-host that don't have frameworks/base).
  383. // Return nil and continue without profile.
  384. return nil
  385. }
  386. profile := image.dir.Join(ctx, "boot.prof")
  387. rule.Command().
  388. Text(`ANDROID_LOG_TAGS="*:e"`).
  389. Tool(globalSoong.Profman).
  390. FlagWithInput("--create-profile-from=", bootImageProfile).
  391. FlagForEachInput("--apk=", image.dexPathsDeps.Paths()).
  392. FlagForEachArg("--dex-location=", image.dexLocationsDeps).
  393. FlagWithOutput("--reference-profile-file=", profile)
  394. rule.Install(profile, "/system/etc/boot-image.prof")
  395. rule.Build(pctx, ctx, "bootJarsProfile", "profile boot jars")
  396. image.profileInstalls = rule.Installs()
  397. return profile
  398. })
  399. if profile == nil {
  400. return nil // wrap nil into a typed pointer with value nil
  401. }
  402. return profile.(android.WritablePath)
  403. }
  404. var bootImageProfileRuleKey = android.NewOnceKey("bootImageProfileRule")
  405. func bootFrameworkProfileRule(ctx android.SingletonContext, image *bootImageConfig, missingDeps []string) android.WritablePath {
  406. globalSoong := dexpreopt.GetCachedGlobalSoongConfig(ctx)
  407. global := dexpreopt.GetGlobalConfig(ctx)
  408. if global.DisableGenerateProfile || ctx.Config().IsPdkBuild() || ctx.Config().UnbundledBuild() {
  409. return nil
  410. }
  411. return ctx.Config().Once(bootFrameworkProfileRuleKey, func() interface{} {
  412. rule := android.NewRuleBuilder()
  413. rule.MissingDeps(missingDeps)
  414. // Some branches like master-art-host don't have frameworks/base, so manually
  415. // handle the case that the default is missing. Those branches won't attempt to build the profile rule,
  416. // and if they do they'll get a missing deps error.
  417. defaultProfile := "frameworks/base/config/boot-profile.txt"
  418. path := android.ExistentPathForSource(ctx, defaultProfile)
  419. var bootFrameworkProfile android.Path
  420. if path.Valid() {
  421. bootFrameworkProfile = path.Path()
  422. } else {
  423. missingDeps = append(missingDeps, defaultProfile)
  424. bootFrameworkProfile = android.PathForOutput(ctx, "missing")
  425. }
  426. profile := image.dir.Join(ctx, "boot.bprof")
  427. rule.Command().
  428. Text(`ANDROID_LOG_TAGS="*:e"`).
  429. Tool(globalSoong.Profman).
  430. Flag("--generate-boot-profile").
  431. FlagWithInput("--create-profile-from=", bootFrameworkProfile).
  432. FlagForEachInput("--apk=", image.dexPathsDeps.Paths()).
  433. FlagForEachArg("--dex-location=", image.dexLocationsDeps).
  434. FlagWithOutput("--reference-profile-file=", profile)
  435. rule.Install(profile, "/system/etc/boot-image.bprof")
  436. rule.Build(pctx, ctx, "bootFrameworkProfile", "profile boot framework jars")
  437. image.profileInstalls = append(image.profileInstalls, rule.Installs()...)
  438. return profile
  439. }).(android.WritablePath)
  440. }
  441. var bootFrameworkProfileRuleKey = android.NewOnceKey("bootFrameworkProfileRule")
  442. func dumpOatRules(ctx android.SingletonContext, image *bootImageConfig) {
  443. var allPhonies android.Paths
  444. for _, image := range image.variants {
  445. arch := image.target.Arch.ArchType
  446. // Create a rule to call oatdump.
  447. output := android.PathForOutput(ctx, "boot."+arch.String()+".oatdump.txt")
  448. rule := android.NewRuleBuilder()
  449. rule.Command().
  450. // TODO: for now, use the debug version for better error reporting
  451. BuiltTool(ctx, "oatdumpd").
  452. FlagWithInputList("--runtime-arg -Xbootclasspath:", image.dexPathsDeps.Paths(), ":").
  453. FlagWithList("--runtime-arg -Xbootclasspath-locations:", image.dexLocationsDeps, ":").
  454. FlagWithArg("--image=", strings.Join(image.imageLocations, ":")).Implicits(image.imagesDeps.Paths()).
  455. FlagWithOutput("--output=", output).
  456. FlagWithArg("--instruction-set=", arch.String())
  457. rule.Build(pctx, ctx, "dump-oat-boot-"+arch.String(), "dump oat boot "+arch.String())
  458. // Create a phony rule that depends on the output file and prints the path.
  459. phony := android.PathForPhony(ctx, "dump-oat-boot-"+arch.String())
  460. rule = android.NewRuleBuilder()
  461. rule.Command().
  462. Implicit(output).
  463. ImplicitOutput(phony).
  464. Text("echo").FlagWithArg("Output in ", output.String())
  465. rule.Build(pctx, ctx, "phony-dump-oat-boot-"+arch.String(), "dump oat boot "+arch.String())
  466. allPhonies = append(allPhonies, phony)
  467. }
  468. phony := android.PathForPhony(ctx, "dump-oat-boot")
  469. ctx.Build(pctx, android.BuildParams{
  470. Rule: android.Phony,
  471. Output: phony,
  472. Inputs: allPhonies,
  473. Description: "dump-oat-boot",
  474. })
  475. }
  476. func writeGlobalConfigForMake(ctx android.SingletonContext, path android.WritablePath) {
  477. data := dexpreopt.GetGlobalConfigRawData(ctx)
  478. ctx.Build(pctx, android.BuildParams{
  479. Rule: android.WriteFile,
  480. Output: path,
  481. Args: map[string]string{
  482. "content": string(data),
  483. },
  484. })
  485. }
  486. // Export paths for default boot image to Make
  487. func (d *dexpreoptBootJars) MakeVars(ctx android.MakeVarsContext) {
  488. if d.dexpreoptConfigForMake != nil {
  489. ctx.Strict("DEX_PREOPT_CONFIG_FOR_MAKE", d.dexpreoptConfigForMake.String())
  490. ctx.Strict("DEX_PREOPT_SOONG_CONFIG_FOR_MAKE", android.PathForOutput(ctx, "dexpreopt_soong.config").String())
  491. }
  492. image := d.defaultBootImage
  493. if image != nil {
  494. ctx.Strict("DEXPREOPT_IMAGE_PROFILE_BUILT_INSTALLED", image.profileInstalls.String())
  495. ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_FILES", strings.Join(image.dexPathsDeps.Strings(), " "))
  496. ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_LOCATIONS", strings.Join(image.dexLocationsDeps, " "))
  497. var imageNames []string
  498. for _, current := range append(d.otherImages, image) {
  499. imageNames = append(imageNames, current.name)
  500. for _, current := range current.variants {
  501. sfx := current.name + "_" + current.target.Arch.ArchType.String()
  502. ctx.Strict("DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_"+sfx, current.vdexInstalls.String())
  503. ctx.Strict("DEXPREOPT_IMAGE_"+sfx, current.images.String())
  504. ctx.Strict("DEXPREOPT_IMAGE_DEPS_"+sfx, strings.Join(current.imagesDeps.Strings(), " "))
  505. ctx.Strict("DEXPREOPT_IMAGE_BUILT_INSTALLED_"+sfx, current.installs.String())
  506. ctx.Strict("DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_"+sfx, current.unstrippedInstalls.String())
  507. }
  508. ctx.Strict("DEXPREOPT_IMAGE_LOCATIONS_"+current.name, strings.Join(current.imageLocations, ":"))
  509. ctx.Strict("DEXPREOPT_IMAGE_ZIP_"+current.name, current.zip.String())
  510. }
  511. ctx.Strict("DEXPREOPT_IMAGE_NAMES", strings.Join(imageNames, " "))
  512. }
  513. }