• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
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
75// defaultBootImageConfig returns the bootImageConfig that will be used to dexpreopt modules.  It is computed once the
76// first time it is called for any ctx.Config(), and returns the same slice for all future calls with the same
77// ctx.Config().
78func defaultBootImageConfig(ctx android.PathContext) bootImageConfig {
79	return ctx.Config().Once(defaultBootImageConfigKey, func() interface{} {
80		global := dexpreoptGlobalConfig(ctx)
81
82		runtimeModules := global.RuntimeApexJars
83		nonFrameworkModules := concat(runtimeModules, global.ProductUpdatableBootModules)
84		frameworkModules := android.RemoveListFromList(global.BootJars, nonFrameworkModules)
85
86		var nonUpdatableBootModules []string
87		var nonUpdatableBootLocations []string
88
89		for _, m := range runtimeModules {
90			nonUpdatableBootModules = append(nonUpdatableBootModules, m)
91			nonUpdatableBootLocations = append(nonUpdatableBootLocations,
92				filepath.Join("/apex/com.android.runtime/javalib", m+".jar"))
93		}
94
95		for _, m := range frameworkModules {
96			nonUpdatableBootModules = append(nonUpdatableBootModules, m)
97			nonUpdatableBootLocations = append(nonUpdatableBootLocations,
98				filepath.Join("/system/framework", m+".jar"))
99		}
100
101		// The path to bootclasspath dex files needs to be known at module GenerateAndroidBuildAction time, before
102		// the bootclasspath modules have been compiled.  Set up known paths for them, the singleton rules will copy
103		// them there.
104		// TODO: use module dependencies instead
105		var nonUpdatableBootDexPaths android.WritablePaths
106		for _, m := range nonUpdatableBootModules {
107			nonUpdatableBootDexPaths = append(nonUpdatableBootDexPaths,
108				android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_bootjars_input", m+".jar"))
109		}
110
111		dir := android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_bootjars")
112		symbolsDir := android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_bootjars_unstripped")
113		images := make(map[android.ArchType]android.OutputPath)
114
115		for _, target := range ctx.Config().Targets[android.Android] {
116			images[target.Arch.ArchType] = dir.Join(ctx,
117				"system/framework", target.Arch.ArchType.String()).Join(ctx, "boot.art")
118		}
119
120		return bootImageConfig{
121			name:         "boot",
122			modules:      nonUpdatableBootModules,
123			dexLocations: nonUpdatableBootLocations,
124			dexPaths:     nonUpdatableBootDexPaths,
125			dir:          dir,
126			symbolsDir:   symbolsDir,
127			images:       images,
128		}
129	}).(bootImageConfig)
130}
131
132var defaultBootImageConfigKey = android.NewOnceKey("defaultBootImageConfig")
133
134func apexBootImageConfig(ctx android.PathContext) bootImageConfig {
135	return ctx.Config().Once(apexBootImageConfigKey, func() interface{} {
136		global := dexpreoptGlobalConfig(ctx)
137
138		runtimeModules := global.RuntimeApexJars
139		nonFrameworkModules := concat(runtimeModules, global.ProductUpdatableBootModules)
140		frameworkModules := android.RemoveListFromList(global.BootJars, nonFrameworkModules)
141		imageModules := concat(runtimeModules, frameworkModules)
142
143		var bootLocations []string
144
145		for _, m := range runtimeModules {
146			bootLocations = append(bootLocations,
147				filepath.Join("/apex/com.android.runtime/javalib", m+".jar"))
148		}
149
150		for _, m := range frameworkModules {
151			bootLocations = append(bootLocations,
152				filepath.Join("/system/framework", m+".jar"))
153		}
154
155		// The path to bootclasspath dex files needs to be known at module GenerateAndroidBuildAction time, before
156		// the bootclasspath modules have been compiled.  Set up known paths for them, the singleton rules will copy
157		// them there.
158		// TODO: use module dependencies instead
159		var bootDexPaths android.WritablePaths
160		for _, m := range imageModules {
161			bootDexPaths = append(bootDexPaths,
162				android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_apexjars_input", m+".jar"))
163		}
164
165		dir := android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_apexjars")
166		symbolsDir := android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_apexjars_unstripped")
167		images := make(map[android.ArchType]android.OutputPath)
168
169		for _, target := range ctx.Config().Targets[android.Android] {
170			images[target.Arch.ArchType] = dir.Join(ctx,
171				"system/framework", target.Arch.ArchType.String(), "apex.art")
172		}
173
174		return bootImageConfig{
175			name:         "apex",
176			modules:      imageModules,
177			dexLocations: bootLocations,
178			dexPaths:     bootDexPaths,
179			dir:          dir,
180			symbolsDir:   symbolsDir,
181			images:       images,
182		}
183	}).(bootImageConfig)
184}
185
186var apexBootImageConfigKey = android.NewOnceKey("apexBootImageConfig")
187
188func defaultBootclasspath(ctx android.PathContext) []string {
189	return ctx.Config().OnceStringSlice(defaultBootclasspathKey, func() []string {
190		global := dexpreoptGlobalConfig(ctx)
191		image := defaultBootImageConfig(ctx)
192		bootclasspath := append(copyOf(image.dexLocations), global.ProductUpdatableBootLocations...)
193		return bootclasspath
194	})
195}
196
197var defaultBootclasspathKey = android.NewOnceKey("defaultBootclasspath")
198
199var copyOf = android.CopyOf
200
201func init() {
202	android.RegisterMakeVarsProvider(pctx, dexpreoptConfigMakevars)
203}
204
205func dexpreoptConfigMakevars(ctx android.MakeVarsContext) {
206	ctx.Strict("PRODUCT_BOOTCLASSPATH", strings.Join(defaultBootclasspath(ctx), ":"))
207	ctx.Strict("PRODUCT_DEX2OAT_BOOTCLASSPATH", strings.Join(defaultBootImageConfig(ctx).dexLocations, ":"))
208	ctx.Strict("PRODUCT_SYSTEM_SERVER_CLASSPATH", strings.Join(systemServerClasspath(ctx), ":"))
209
210	ctx.Strict("DEXPREOPT_BOOT_JARS_MODULES", strings.Join(defaultBootImageConfig(ctx).modules, ":"))
211}
212