blob: 270fcb473e9084f87cf0bc50c7d248f77636a986 [file] [log] [blame]
Colin Cross44df5812019-02-15 23:06:46 -08001// 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 "android/soong/android"
19 "android/soong/dexpreopt"
20 "path/filepath"
21 "strings"
22)
23
24// dexpreoptGlobalConfig returns the global dexpreopt.config. It is loaded once the first time it is called for any
25// ctx.Config(), and returns the same data for all future calls with the same ctx.Config(). A value can be inserted
26// for tests using setDexpreoptTestGlobalConfig.
27func dexpreoptGlobalConfig(ctx android.PathContext) dexpreopt.GlobalConfig {
28 return ctx.Config().Once(dexpreoptGlobalConfigKey, func() interface{} {
29 if f := ctx.Config().DexpreoptGlobalConfig(); f != "" {
30 ctx.AddNinjaFileDeps(f)
31 globalConfig, err := dexpreopt.LoadGlobalConfig(ctx, f)
32 if err != nil {
33 panic(err)
34 }
35 return globalConfig
36 }
37
38 // No global config filename set, see if there is a test config set
39 return ctx.Config().Once(dexpreoptTestGlobalConfigKey, func() interface{} {
40 // Nope, return a config with preopting disabled
41 return dexpreopt.GlobalConfig{
42 DisablePreopt: true,
43 }
44 })
45 }).(dexpreopt.GlobalConfig)
46}
47
48// setDexpreoptTestGlobalConfig sets a GlobalConfig that future calls to dexpreoptGlobalConfig will return. It must
49// be called before the first call to dexpreoptGlobalConfig for the config.
50func setDexpreoptTestGlobalConfig(config android.Config, globalConfig dexpreopt.GlobalConfig) {
51 config.Once(dexpreoptTestGlobalConfigKey, func() interface{} { return globalConfig })
52}
53
54var dexpreoptGlobalConfigKey = android.NewOnceKey("DexpreoptGlobalConfig")
55var dexpreoptTestGlobalConfigKey = android.NewOnceKey("TestDexpreoptGlobalConfig")
56
57// systemServerClasspath returns the on-device locations of the modules in the system server classpath. It is computed
58// once the first time it is called for any ctx.Config(), and returns the same slice for all future calls with the same
59// ctx.Config().
60func systemServerClasspath(ctx android.PathContext) []string {
61 return ctx.Config().OnceStringSlice(systemServerClasspathKey, func() []string {
62 global := dexpreoptGlobalConfig(ctx)
63
64 var systemServerClasspathLocations []string
65 for _, m := range global.SystemServerJars {
66 systemServerClasspathLocations = append(systemServerClasspathLocations,
67 filepath.Join("/system/framework", m+".jar"))
68 }
69 return systemServerClasspathLocations
70 })
71}
72
73var systemServerClasspathKey = android.NewOnceKey("systemServerClasspath")
74
Colin Crossc11e0c52019-05-08 15:18:22 -070075// dexpreoptTargets returns the list of targets that are relevant to dexpreopting, which excludes architectures
76// supported through native bridge.
77func dexpreoptTargets(ctx android.PathContext) []android.Target {
78 var targets []android.Target
79 for i, target := range ctx.Config().Targets[android.Android] {
80 if ctx.Config().SecondArchIsTranslated() && i > 0 {
81 break
82 }
83
84 if target.NativeBridge == android.NativeBridgeDisabled {
85 targets = append(targets, target)
86 }
87 }
88
89 return targets
90}
91
Colin Cross44df5812019-02-15 23:06:46 -080092// defaultBootImageConfig returns the bootImageConfig that will be used to dexpreopt modules. It is computed once the
93// first time it is called for any ctx.Config(), and returns the same slice for all future calls with the same
94// ctx.Config().
95func defaultBootImageConfig(ctx android.PathContext) bootImageConfig {
96 return ctx.Config().Once(defaultBootImageConfigKey, func() interface{} {
97 global := dexpreoptGlobalConfig(ctx)
98
99 runtimeModules := global.RuntimeApexJars
100 nonFrameworkModules := concat(runtimeModules, global.ProductUpdatableBootModules)
101 frameworkModules := android.RemoveListFromList(global.BootJars, nonFrameworkModules)
102
103 var nonUpdatableBootModules []string
104 var nonUpdatableBootLocations []string
105
106 for _, m := range runtimeModules {
107 nonUpdatableBootModules = append(nonUpdatableBootModules, m)
108 nonUpdatableBootLocations = append(nonUpdatableBootLocations,
109 filepath.Join("/apex/com.android.runtime/javalib", m+".jar"))
110 }
111
112 for _, m := range frameworkModules {
113 nonUpdatableBootModules = append(nonUpdatableBootModules, m)
114 nonUpdatableBootLocations = append(nonUpdatableBootLocations,
115 filepath.Join("/system/framework", m+".jar"))
116 }
117
118 // The path to bootclasspath dex files needs to be known at module GenerateAndroidBuildAction time, before
119 // the bootclasspath modules have been compiled. Set up known paths for them, the singleton rules will copy
120 // them there.
121 // TODO: use module dependencies instead
122 var nonUpdatableBootDexPaths android.WritablePaths
123 for _, m := range nonUpdatableBootModules {
124 nonUpdatableBootDexPaths = append(nonUpdatableBootDexPaths,
125 android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_bootjars_input", m+".jar"))
126 }
127
128 dir := android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_bootjars")
129 symbolsDir := android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_bootjars_unstripped")
130 images := make(map[android.ArchType]android.OutputPath)
Colin Crossdf8eebe2019-04-09 15:29:41 -0700131 zip := dir.Join(ctx, "boot.zip")
Colin Cross44df5812019-02-15 23:06:46 -0800132
Colin Crossc11e0c52019-05-08 15:18:22 -0700133 targets := dexpreoptTargets(ctx)
134
135 for _, target := range targets {
Colin Cross44df5812019-02-15 23:06:46 -0800136 images[target.Arch.ArchType] = dir.Join(ctx,
Colin Cross2cdd5df2019-02-25 10:25:24 -0800137 "system/framework", target.Arch.ArchType.String()).Join(ctx, "boot.art")
Colin Cross44df5812019-02-15 23:06:46 -0800138 }
139
140 return bootImageConfig{
141 name: "boot",
142 modules: nonUpdatableBootModules,
143 dexLocations: nonUpdatableBootLocations,
144 dexPaths: nonUpdatableBootDexPaths,
145 dir: dir,
146 symbolsDir: symbolsDir,
147 images: images,
Colin Crossc11e0c52019-05-08 15:18:22 -0700148 targets: targets,
Colin Crossdf8eebe2019-04-09 15:29:41 -0700149 zip: zip,
Colin Cross44df5812019-02-15 23:06:46 -0800150 }
151 }).(bootImageConfig)
152}
153
154var defaultBootImageConfigKey = android.NewOnceKey("defaultBootImageConfig")
155
Nicolas Geoffray72892f12019-02-22 15:34:40 +0000156func apexBootImageConfig(ctx android.PathContext) bootImageConfig {
157 return ctx.Config().Once(apexBootImageConfigKey, func() interface{} {
158 global := dexpreoptGlobalConfig(ctx)
159
160 runtimeModules := global.RuntimeApexJars
Nicolas Geoffrayfeef2ef2019-04-30 09:43:22 +0100161 nonFrameworkModules := concat(runtimeModules, global.ProductUpdatableBootModules)
162 frameworkModules := android.RemoveListFromList(global.BootJars, nonFrameworkModules)
163 imageModules := concat(runtimeModules, frameworkModules)
Nicolas Geoffray72892f12019-02-22 15:34:40 +0000164
Nicolas Geoffrayfeef2ef2019-04-30 09:43:22 +0100165 var bootLocations []string
Nicolas Geoffray72892f12019-02-22 15:34:40 +0000166
167 for _, m := range runtimeModules {
Nicolas Geoffrayfeef2ef2019-04-30 09:43:22 +0100168 bootLocations = append(bootLocations,
Nicolas Geoffray72892f12019-02-22 15:34:40 +0000169 filepath.Join("/apex/com.android.runtime/javalib", m+".jar"))
170 }
171
Nicolas Geoffrayfeef2ef2019-04-30 09:43:22 +0100172 for _, m := range frameworkModules {
173 bootLocations = append(bootLocations,
174 filepath.Join("/system/framework", m+".jar"))
175 }
176
Nicolas Geoffray72892f12019-02-22 15:34:40 +0000177 // The path to bootclasspath dex files needs to be known at module GenerateAndroidBuildAction time, before
178 // the bootclasspath modules have been compiled. Set up known paths for them, the singleton rules will copy
179 // them there.
180 // TODO: use module dependencies instead
Nicolas Geoffrayfeef2ef2019-04-30 09:43:22 +0100181 var bootDexPaths android.WritablePaths
182 for _, m := range imageModules {
183 bootDexPaths = append(bootDexPaths,
Nicolas Geoffray72892f12019-02-22 15:34:40 +0000184 android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_apexjars_input", m+".jar"))
185 }
186
187 dir := android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_apexjars")
188 symbolsDir := android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_apexjars_unstripped")
189 images := make(map[android.ArchType]android.OutputPath)
190
Colin Crossc11e0c52019-05-08 15:18:22 -0700191 targets := dexpreoptTargets(ctx)
192
193 for _, target := range targets {
Nicolas Geoffray72892f12019-02-22 15:34:40 +0000194 images[target.Arch.ArchType] = dir.Join(ctx,
195 "system/framework", target.Arch.ArchType.String(), "apex.art")
196 }
197
198 return bootImageConfig{
199 name: "apex",
Nicolas Geoffrayfeef2ef2019-04-30 09:43:22 +0100200 modules: imageModules,
201 dexLocations: bootLocations,
202 dexPaths: bootDexPaths,
Nicolas Geoffray72892f12019-02-22 15:34:40 +0000203 dir: dir,
204 symbolsDir: symbolsDir,
Colin Crossc11e0c52019-05-08 15:18:22 -0700205 targets: targets,
Nicolas Geoffray72892f12019-02-22 15:34:40 +0000206 images: images,
207 }
208 }).(bootImageConfig)
209}
210
211var apexBootImageConfigKey = android.NewOnceKey("apexBootImageConfig")
212
Colin Cross44df5812019-02-15 23:06:46 -0800213func defaultBootclasspath(ctx android.PathContext) []string {
214 return ctx.Config().OnceStringSlice(defaultBootclasspathKey, func() []string {
215 global := dexpreoptGlobalConfig(ctx)
216 image := defaultBootImageConfig(ctx)
217 bootclasspath := append(copyOf(image.dexLocations), global.ProductUpdatableBootLocations...)
218 return bootclasspath
219 })
220}
221
222var defaultBootclasspathKey = android.NewOnceKey("defaultBootclasspath")
223
224var copyOf = android.CopyOf
225
226func init() {
227 android.RegisterMakeVarsProvider(pctx, dexpreoptConfigMakevars)
228}
229
230func dexpreoptConfigMakevars(ctx android.MakeVarsContext) {
231 ctx.Strict("PRODUCT_BOOTCLASSPATH", strings.Join(defaultBootclasspath(ctx), ":"))
Nicolas Geoffray07b40072019-02-22 16:57:42 +0000232 ctx.Strict("PRODUCT_DEX2OAT_BOOTCLASSPATH", strings.Join(defaultBootImageConfig(ctx).dexLocations, ":"))
Colin Cross44df5812019-02-15 23:06:46 -0800233 ctx.Strict("PRODUCT_SYSTEM_SERVER_CLASSPATH", strings.Join(systemServerClasspath(ctx), ":"))
Colin Cross9be41522019-02-20 10:40:13 -0800234
235 ctx.Strict("DEXPREOPT_BOOT_JARS_MODULES", strings.Join(defaultBootImageConfig(ctx).modules, ":"))
Colin Cross44df5812019-02-15 23:06:46 -0800236}