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