dexpreopt_config.go 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  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. )
  21. // dexpreoptTargets returns the list of targets that are relevant to dexpreopting, which excludes architectures
  22. // supported through native bridge.
  23. func dexpreoptTargets(ctx android.PathContext) []android.Target {
  24. var targets []android.Target
  25. for _, target := range ctx.Config().Targets[android.Android] {
  26. if target.NativeBridge == android.NativeBridgeDisabled {
  27. targets = append(targets, target)
  28. }
  29. }
  30. // We may also need the images on host in order to run host-based tests.
  31. for _, target := range ctx.Config().Targets[ctx.Config().BuildOS] {
  32. targets = append(targets, target)
  33. }
  34. return targets
  35. }
  36. var (
  37. bootImageConfigKey = android.NewOnceKey("bootImageConfig")
  38. artBootImageName = "art"
  39. frameworkBootImageName = "boot"
  40. )
  41. // Construct the global boot image configs.
  42. func genBootImageConfigs(ctx android.PathContext) map[string]*bootImageConfig {
  43. return ctx.Config().Once(bootImageConfigKey, func() interface{} {
  44. global := dexpreopt.GetGlobalConfig(ctx)
  45. targets := dexpreoptTargets(ctx)
  46. deviceDir := android.PathForOutput(ctx, ctx.Config().DeviceName())
  47. artModules := global.ArtApexJars
  48. frameworkModules := global.BootJars.RemoveList(artModules)
  49. artDirOnHost := "apex/art_boot_images/javalib"
  50. artDirOnDevice := "apex/com.android.art/javalib"
  51. frameworkSubdir := "system/framework"
  52. // ART config for the primary boot image in the ART apex.
  53. // It includes the Core Libraries.
  54. artCfg := bootImageConfig{
  55. name: artBootImageName,
  56. stem: "boot",
  57. installDirOnHost: artDirOnHost,
  58. installDirOnDevice: artDirOnDevice,
  59. modules: artModules,
  60. }
  61. // Framework config for the boot image extension.
  62. // It includes framework libraries and depends on the ART config.
  63. frameworkCfg := bootImageConfig{
  64. extends: &artCfg,
  65. name: frameworkBootImageName,
  66. stem: "boot",
  67. installDirOnHost: frameworkSubdir,
  68. installDirOnDevice: frameworkSubdir,
  69. modules: frameworkModules,
  70. }
  71. configs := map[string]*bootImageConfig{
  72. artBootImageName: &artCfg,
  73. frameworkBootImageName: &frameworkCfg,
  74. }
  75. // common to all configs
  76. for _, c := range configs {
  77. c.dir = deviceDir.Join(ctx, "dex_"+c.name+"jars")
  78. c.symbolsDir = deviceDir.Join(ctx, "dex_"+c.name+"jars_unstripped")
  79. // expands to <stem>.art for primary image and <stem>-<1st module>.art for extension
  80. imageName := c.firstModuleNameOrStem(ctx) + ".art"
  81. // The path to bootclasspath dex files needs to be known at module
  82. // GenerateAndroidBuildAction time, before the bootclasspath modules have been compiled.
  83. // Set up known paths for them, the singleton rules will copy them there.
  84. // TODO(b/143682396): use module dependencies instead
  85. inputDir := deviceDir.Join(ctx, "dex_"+c.name+"jars_input")
  86. c.dexPaths = c.modules.BuildPaths(ctx, inputDir)
  87. c.dexPathsByModule = c.modules.BuildPathsByModule(ctx, inputDir)
  88. c.dexPathsDeps = c.dexPaths
  89. // Create target-specific variants.
  90. for _, target := range targets {
  91. arch := target.Arch.ArchType
  92. imageDir := c.dir.Join(ctx, target.Os.String(), c.installDirOnHost, arch.String())
  93. variant := &bootImageVariant{
  94. bootImageConfig: c,
  95. target: target,
  96. imagePathOnHost: imageDir.Join(ctx, imageName),
  97. imagePathOnDevice: filepath.Join("/", c.installDirOnDevice, arch.String(), imageName),
  98. imagesDeps: c.moduleFiles(ctx, imageDir, ".art", ".oat", ".vdex"),
  99. dexLocations: c.modules.DevicePaths(ctx.Config(), target.Os),
  100. }
  101. variant.dexLocationsDeps = variant.dexLocations
  102. c.variants = append(c.variants, variant)
  103. }
  104. c.zip = c.dir.Join(ctx, c.name+".zip")
  105. }
  106. // specific to the framework config
  107. frameworkCfg.dexPathsDeps = append(artCfg.dexPathsDeps, frameworkCfg.dexPathsDeps...)
  108. for i := range targets {
  109. frameworkCfg.variants[i].primaryImages = artCfg.variants[i].imagePathOnHost
  110. frameworkCfg.variants[i].primaryImagesDeps = artCfg.variants[i].imagesDeps.Paths()
  111. frameworkCfg.variants[i].dexLocationsDeps = append(artCfg.variants[i].dexLocations, frameworkCfg.variants[i].dexLocationsDeps...)
  112. }
  113. return configs
  114. }).(map[string]*bootImageConfig)
  115. }
  116. func artBootImageConfig(ctx android.PathContext) *bootImageConfig {
  117. return genBootImageConfigs(ctx)[artBootImageName]
  118. }
  119. func defaultBootImageConfig(ctx android.PathContext) *bootImageConfig {
  120. return genBootImageConfigs(ctx)[frameworkBootImageName]
  121. }
  122. // Updatable boot config allows to access build/install paths of updatable boot jars without going
  123. // through the usual trouble of registering dependencies on those modules and extracting build paths
  124. // from those dependencies.
  125. type updatableBootConfig struct {
  126. // A list of updatable boot jars.
  127. modules android.ConfiguredJarList
  128. // A list of predefined build paths to updatable boot jars. They are configured very early,
  129. // before the modules for these jars are processed and the actual paths are generated, and
  130. // later on a singleton adds commands to copy actual jars to the predefined paths.
  131. dexPaths android.WritablePaths
  132. // Map from module name (without prebuilt_ prefix) to the predefined build path.
  133. dexPathsByModule map[string]android.WritablePath
  134. // A list of dex locations (a.k.a. on-device paths) to the boot jars.
  135. dexLocations []string
  136. }
  137. var updatableBootConfigKey = android.NewOnceKey("updatableBootConfig")
  138. // Returns updatable boot config.
  139. func GetUpdatableBootConfig(ctx android.PathContext) updatableBootConfig {
  140. return ctx.Config().Once(updatableBootConfigKey, func() interface{} {
  141. updatableBootJars := dexpreopt.GetGlobalConfig(ctx).UpdatableBootJars
  142. dir := android.PathForOutput(ctx, ctx.Config().DeviceName(), "updatable_bootjars")
  143. dexPaths := updatableBootJars.BuildPaths(ctx, dir)
  144. dexPathsByModuleName := updatableBootJars.BuildPathsByModule(ctx, dir)
  145. dexLocations := updatableBootJars.DevicePaths(ctx.Config(), android.Android)
  146. return updatableBootConfig{updatableBootJars, dexPaths, dexPathsByModuleName, dexLocations}
  147. }).(updatableBootConfig)
  148. }
  149. // Returns a list of paths and a list of locations for the boot jars used in dexpreopt (to be
  150. // passed in -Xbootclasspath and -Xbootclasspath-locations arguments for dex2oat).
  151. func bcpForDexpreopt(ctx android.PathContext, withUpdatable bool) (android.WritablePaths, []string) {
  152. // Non-updatable boot jars (they are used both in the boot image and in dexpreopt).
  153. bootImage := defaultBootImageConfig(ctx)
  154. dexPaths := bootImage.dexPathsDeps
  155. // The dex locations for all Android variants are identical.
  156. dexLocations := bootImage.getAnyAndroidVariant().dexLocationsDeps
  157. if withUpdatable {
  158. // Updatable boot jars (they are used only in dexpreopt, but not in the boot image).
  159. updBootConfig := GetUpdatableBootConfig(ctx)
  160. dexPaths = append(dexPaths, updBootConfig.dexPaths...)
  161. dexLocations = append(dexLocations, updBootConfig.dexLocations...)
  162. }
  163. return dexPaths, dexLocations
  164. }
  165. var defaultBootclasspathKey = android.NewOnceKey("defaultBootclasspath")
  166. var copyOf = android.CopyOf
  167. func init() {
  168. android.RegisterMakeVarsProvider(pctx, dexpreoptConfigMakevars)
  169. }
  170. func dexpreoptConfigMakevars(ctx android.MakeVarsContext) {
  171. ctx.Strict("DEXPREOPT_BOOT_JARS_MODULES", strings.Join(defaultBootImageConfig(ctx).modules.CopyOfApexJarPairs(), ":"))
  172. }