xref: /aosp_15_r20/build/soong/dexpreopt/config.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright 2018 Google Inc. All rights reserved.
2*333d2b36SAndroid Build Coastguard Worker//
3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*333d2b36SAndroid Build Coastguard Worker//
7*333d2b36SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*333d2b36SAndroid Build Coastguard Worker//
9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*333d2b36SAndroid Build Coastguard Worker// limitations under the License.
14*333d2b36SAndroid Build Coastguard Worker
15*333d2b36SAndroid Build Coastguard Workerpackage dexpreopt
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Workerimport (
18*333d2b36SAndroid Build Coastguard Worker	"encoding/json"
19*333d2b36SAndroid Build Coastguard Worker	"fmt"
20*333d2b36SAndroid Build Coastguard Worker	"reflect"
21*333d2b36SAndroid Build Coastguard Worker	"strings"
22*333d2b36SAndroid Build Coastguard Worker
23*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint"
24*333d2b36SAndroid Build Coastguard Worker
25*333d2b36SAndroid Build Coastguard Worker	"android/soong/android"
26*333d2b36SAndroid Build Coastguard Worker)
27*333d2b36SAndroid Build Coastguard Worker
28*333d2b36SAndroid Build Coastguard Worker// GlobalConfig stores the configuration for dex preopting. The fields are set
29*333d2b36SAndroid Build Coastguard Worker// from product variables via dex_preopt_config.mk.
30*333d2b36SAndroid Build Coastguard Workertype GlobalConfig struct {
31*333d2b36SAndroid Build Coastguard Worker	DisablePreopt           bool     // disable preopt for all modules (excluding boot images)
32*333d2b36SAndroid Build Coastguard Worker	DisablePreoptBootImages bool     // disable prepot for boot images
33*333d2b36SAndroid Build Coastguard Worker	DisablePreoptModules    []string // modules with preopt disabled by product-specific config
34*333d2b36SAndroid Build Coastguard Worker
35*333d2b36SAndroid Build Coastguard Worker	OnlyPreoptArtBootImage bool // only preopt jars in the ART boot image
36*333d2b36SAndroid Build Coastguard Worker
37*333d2b36SAndroid Build Coastguard Worker	PreoptWithUpdatableBcp bool // If updatable boot jars are included in dexpreopt or not.
38*333d2b36SAndroid Build Coastguard Worker
39*333d2b36SAndroid Build Coastguard Worker	HasSystemOther        bool     // store odex files that match PatternsOnSystemOther on the system_other partition
40*333d2b36SAndroid Build Coastguard Worker	PatternsOnSystemOther []string // patterns (using '%' to denote a prefix match) to put odex on the system_other partition
41*333d2b36SAndroid Build Coastguard Worker
42*333d2b36SAndroid Build Coastguard Worker	DisableGenerateProfile bool   // don't generate profiles
43*333d2b36SAndroid Build Coastguard Worker	ProfileDir             string // directory to find profiles in
44*333d2b36SAndroid Build Coastguard Worker
45*333d2b36SAndroid Build Coastguard Worker	BootJars     android.ConfiguredJarList // modules for jars that form the boot class path
46*333d2b36SAndroid Build Coastguard Worker	ApexBootJars android.ConfiguredJarList // jars within apex that form the boot class path
47*333d2b36SAndroid Build Coastguard Worker
48*333d2b36SAndroid Build Coastguard Worker	ArtApexJars              android.ConfiguredJarList // modules for jars that are in the ART APEX
49*333d2b36SAndroid Build Coastguard Worker	TestOnlyArtBootImageJars android.ConfiguredJarList // modules for jars to be included in the ART boot image for testing
50*333d2b36SAndroid Build Coastguard Worker
51*333d2b36SAndroid Build Coastguard Worker	SystemServerJars               android.ConfiguredJarList // system_server classpath jars on the platform
52*333d2b36SAndroid Build Coastguard Worker	SystemServerApps               []string                  // apps that are loaded into system server
53*333d2b36SAndroid Build Coastguard Worker	ApexSystemServerJars           android.ConfiguredJarList // system_server classpath jars delivered via apex
54*333d2b36SAndroid Build Coastguard Worker	StandaloneSystemServerJars     android.ConfiguredJarList // jars on the platform that system_server loads dynamically using separate classloaders
55*333d2b36SAndroid Build Coastguard Worker	ApexStandaloneSystemServerJars android.ConfiguredJarList // jars delivered via apex that system_server loads dynamically using separate classloaders
56*333d2b36SAndroid Build Coastguard Worker	SpeedApps                      []string                  // apps that should be speed optimized
57*333d2b36SAndroid Build Coastguard Worker
58*333d2b36SAndroid Build Coastguard Worker	BrokenSuboptimalOrderOfSystemServerJars bool // if true, sub-optimal order does not cause a build error
59*333d2b36SAndroid Build Coastguard Worker
60*333d2b36SAndroid Build Coastguard Worker	PreoptFlags []string // global dex2oat flags that should be used if no module-specific dex2oat flags are specified
61*333d2b36SAndroid Build Coastguard Worker
62*333d2b36SAndroid Build Coastguard Worker	DefaultCompilerFilter      string // default compiler filter to pass to dex2oat, overridden by --compiler-filter= in module-specific dex2oat flags
63*333d2b36SAndroid Build Coastguard Worker	SystemServerCompilerFilter string // default compiler filter to pass to dex2oat for system server jars
64*333d2b36SAndroid Build Coastguard Worker
65*333d2b36SAndroid Build Coastguard Worker	GenerateDMFiles bool // generate Dex Metadata files
66*333d2b36SAndroid Build Coastguard Worker
67*333d2b36SAndroid Build Coastguard Worker	NoDebugInfo                 bool // don't generate debug info by default
68*333d2b36SAndroid Build Coastguard Worker	DontResolveStartupStrings   bool // don't resolve string literals loaded during application startup.
69*333d2b36SAndroid Build Coastguard Worker	AlwaysSystemServerDebugInfo bool // always generate mini debug info for system server modules (overrides NoDebugInfo=true)
70*333d2b36SAndroid Build Coastguard Worker	NeverSystemServerDebugInfo  bool // never generate mini debug info for system server modules (overrides NoDebugInfo=false)
71*333d2b36SAndroid Build Coastguard Worker	AlwaysOtherDebugInfo        bool // always generate mini debug info for non-system server modules (overrides NoDebugInfo=true)
72*333d2b36SAndroid Build Coastguard Worker	NeverOtherDebugInfo         bool // never generate mini debug info for non-system server modules (overrides NoDebugInfo=true)
73*333d2b36SAndroid Build Coastguard Worker
74*333d2b36SAndroid Build Coastguard Worker	IsEng        bool // build is a eng variant
75*333d2b36SAndroid Build Coastguard Worker	SanitizeLite bool // build is the second phase of a SANITIZE_LITE build
76*333d2b36SAndroid Build Coastguard Worker
77*333d2b36SAndroid Build Coastguard Worker	DefaultAppImages bool // build app images (TODO: .art files?) by default
78*333d2b36SAndroid Build Coastguard Worker
79*333d2b36SAndroid Build Coastguard Worker	Dex2oatXmx string // max heap size for dex2oat
80*333d2b36SAndroid Build Coastguard Worker	Dex2oatXms string // initial heap size for dex2oat
81*333d2b36SAndroid Build Coastguard Worker
82*333d2b36SAndroid Build Coastguard Worker	EmptyDirectory string // path to an empty directory
83*333d2b36SAndroid Build Coastguard Worker
84*333d2b36SAndroid Build Coastguard Worker	CpuVariant             map[android.ArchType]string // cpu variant for each architecture
85*333d2b36SAndroid Build Coastguard Worker	InstructionSetFeatures map[android.ArchType]string // instruction set for each architecture
86*333d2b36SAndroid Build Coastguard Worker
87*333d2b36SAndroid Build Coastguard Worker	BootImageProfiles android.Paths // path to a boot-image-profile.txt file
88*333d2b36SAndroid Build Coastguard Worker	BootFlags         string        // extra flags to pass to dex2oat for the boot image
89*333d2b36SAndroid Build Coastguard Worker	Dex2oatImageXmx   string        // max heap size for dex2oat for the boot image
90*333d2b36SAndroid Build Coastguard Worker	Dex2oatImageXms   string        // initial heap size for dex2oat for the boot image
91*333d2b36SAndroid Build Coastguard Worker
92*333d2b36SAndroid Build Coastguard Worker	// If true, downgrade the compiler filter of dexpreopt to "verify" when verify_uses_libraries
93*333d2b36SAndroid Build Coastguard Worker	// check fails, instead of failing the build. This will disable any AOT-compilation.
94*333d2b36SAndroid Build Coastguard Worker	//
95*333d2b36SAndroid Build Coastguard Worker	// The intended use case for this flag is to have a smoother migration path for the Java
96*333d2b36SAndroid Build Coastguard Worker	// modules that need to add <uses-library> information in their build files. The flag allows to
97*333d2b36SAndroid Build Coastguard Worker	// quickly silence build errors. This flag should be used with caution and only as a temporary
98*333d2b36SAndroid Build Coastguard Worker	// measure, as it masks real errors and affects performance.
99*333d2b36SAndroid Build Coastguard Worker	RelaxUsesLibraryCheck bool
100*333d2b36SAndroid Build Coastguard Worker
101*333d2b36SAndroid Build Coastguard Worker	// "true" to force preopt with CMC GC (a.k.a., UFFD GC); "false" to force preopt with CC GC;
102*333d2b36SAndroid Build Coastguard Worker	// "default" to determine the GC type based on the kernel version file.
103*333d2b36SAndroid Build Coastguard Worker	EnableUffdGc string
104*333d2b36SAndroid Build Coastguard Worker}
105*333d2b36SAndroid Build Coastguard Worker
106*333d2b36SAndroid Build Coastguard Workervar allPlatformSystemServerJarsKey = android.NewOnceKey("allPlatformSystemServerJars")
107*333d2b36SAndroid Build Coastguard Worker
108*333d2b36SAndroid Build Coastguard Worker// Returns all jars on the platform that system_server loads, including those on classpath and those
109*333d2b36SAndroid Build Coastguard Worker// loaded dynamically.
110*333d2b36SAndroid Build Coastguard Workerfunc (g *GlobalConfig) AllPlatformSystemServerJars(ctx android.PathContext) *android.ConfiguredJarList {
111*333d2b36SAndroid Build Coastguard Worker	return ctx.Config().Once(allPlatformSystemServerJarsKey, func() interface{} {
112*333d2b36SAndroid Build Coastguard Worker		res := g.SystemServerJars.AppendList(&g.StandaloneSystemServerJars)
113*333d2b36SAndroid Build Coastguard Worker		return &res
114*333d2b36SAndroid Build Coastguard Worker	}).(*android.ConfiguredJarList)
115*333d2b36SAndroid Build Coastguard Worker}
116*333d2b36SAndroid Build Coastguard Worker
117*333d2b36SAndroid Build Coastguard Workervar allApexSystemServerJarsKey = android.NewOnceKey("allApexSystemServerJars")
118*333d2b36SAndroid Build Coastguard Worker
119*333d2b36SAndroid Build Coastguard Worker// Returns all jars delivered via apex that system_server loads, including those on classpath and
120*333d2b36SAndroid Build Coastguard Worker// those loaded dynamically.
121*333d2b36SAndroid Build Coastguard Workerfunc (g *GlobalConfig) AllApexSystemServerJars(ctx android.PathContext) *android.ConfiguredJarList {
122*333d2b36SAndroid Build Coastguard Worker	return ctx.Config().Once(allApexSystemServerJarsKey, func() interface{} {
123*333d2b36SAndroid Build Coastguard Worker		res := g.ApexSystemServerJars.AppendList(&g.ApexStandaloneSystemServerJars)
124*333d2b36SAndroid Build Coastguard Worker		return &res
125*333d2b36SAndroid Build Coastguard Worker	}).(*android.ConfiguredJarList)
126*333d2b36SAndroid Build Coastguard Worker}
127*333d2b36SAndroid Build Coastguard Worker
128*333d2b36SAndroid Build Coastguard Workervar allSystemServerClasspathJarsKey = android.NewOnceKey("allSystemServerClasspathJars")
129*333d2b36SAndroid Build Coastguard Worker
130*333d2b36SAndroid Build Coastguard Worker// Returns all system_server classpath jars.
131*333d2b36SAndroid Build Coastguard Workerfunc (g *GlobalConfig) AllSystemServerClasspathJars(ctx android.PathContext) *android.ConfiguredJarList {
132*333d2b36SAndroid Build Coastguard Worker	return ctx.Config().Once(allSystemServerClasspathJarsKey, func() interface{} {
133*333d2b36SAndroid Build Coastguard Worker		res := g.SystemServerJars.AppendList(&g.ApexSystemServerJars)
134*333d2b36SAndroid Build Coastguard Worker		return &res
135*333d2b36SAndroid Build Coastguard Worker	}).(*android.ConfiguredJarList)
136*333d2b36SAndroid Build Coastguard Worker}
137*333d2b36SAndroid Build Coastguard Worker
138*333d2b36SAndroid Build Coastguard Workervar allSystemServerJarsKey = android.NewOnceKey("allSystemServerJars")
139*333d2b36SAndroid Build Coastguard Worker
140*333d2b36SAndroid Build Coastguard Worker// Returns all jars that system_server loads.
141*333d2b36SAndroid Build Coastguard Workerfunc (g *GlobalConfig) AllSystemServerJars(ctx android.PathContext) *android.ConfiguredJarList {
142*333d2b36SAndroid Build Coastguard Worker	return ctx.Config().Once(allSystemServerJarsKey, func() interface{} {
143*333d2b36SAndroid Build Coastguard Worker		res := g.AllPlatformSystemServerJars(ctx).AppendList(g.AllApexSystemServerJars(ctx))
144*333d2b36SAndroid Build Coastguard Worker		return &res
145*333d2b36SAndroid Build Coastguard Worker	}).(*android.ConfiguredJarList)
146*333d2b36SAndroid Build Coastguard Worker}
147*333d2b36SAndroid Build Coastguard Worker
148*333d2b36SAndroid Build Coastguard Worker// GlobalSoongConfig contains the global config that is generated from Soong,
149*333d2b36SAndroid Build Coastguard Worker// stored in dexpreopt_soong.config.
150*333d2b36SAndroid Build Coastguard Workertype GlobalSoongConfig struct {
151*333d2b36SAndroid Build Coastguard Worker	// Paths to tools possibly used by the generated commands.
152*333d2b36SAndroid Build Coastguard Worker	Profman          android.Path
153*333d2b36SAndroid Build Coastguard Worker	Dex2oat          android.Path
154*333d2b36SAndroid Build Coastguard Worker	Aapt             android.Path
155*333d2b36SAndroid Build Coastguard Worker	SoongZip         android.Path
156*333d2b36SAndroid Build Coastguard Worker	Zip2zip          android.Path
157*333d2b36SAndroid Build Coastguard Worker	ManifestCheck    android.Path
158*333d2b36SAndroid Build Coastguard Worker	ConstructContext android.Path
159*333d2b36SAndroid Build Coastguard Worker	UffdGcFlag       android.WritablePath
160*333d2b36SAndroid Build Coastguard Worker}
161*333d2b36SAndroid Build Coastguard Worker
162*333d2b36SAndroid Build Coastguard Workertype ModuleConfig struct {
163*333d2b36SAndroid Build Coastguard Worker	Name            string
164*333d2b36SAndroid Build Coastguard Worker	DexLocation     string // dex location on device
165*333d2b36SAndroid Build Coastguard Worker	BuildPath       android.OutputPath
166*333d2b36SAndroid Build Coastguard Worker	DexPath         android.Path
167*333d2b36SAndroid Build Coastguard Worker	ManifestPath    android.OptionalPath
168*333d2b36SAndroid Build Coastguard Worker	UncompressedDex bool
169*333d2b36SAndroid Build Coastguard Worker	HasApkLibraries bool
170*333d2b36SAndroid Build Coastguard Worker	PreoptFlags     []string
171*333d2b36SAndroid Build Coastguard Worker
172*333d2b36SAndroid Build Coastguard Worker	ProfileClassListing  android.OptionalPath
173*333d2b36SAndroid Build Coastguard Worker	ProfileIsTextListing bool
174*333d2b36SAndroid Build Coastguard Worker	ProfileBootListing   android.OptionalPath
175*333d2b36SAndroid Build Coastguard Worker
176*333d2b36SAndroid Build Coastguard Worker	EnforceUsesLibraries           bool         // turn on build-time verify_uses_libraries check
177*333d2b36SAndroid Build Coastguard Worker	EnforceUsesLibrariesStatusFile android.Path // a file with verify_uses_libraries errors (if any)
178*333d2b36SAndroid Build Coastguard Worker	ProvidesUsesLibrary            string       // library name (usually the same as module name)
179*333d2b36SAndroid Build Coastguard Worker	ClassLoaderContexts            ClassLoaderContextMap
180*333d2b36SAndroid Build Coastguard Worker
181*333d2b36SAndroid Build Coastguard Worker	Archs               []android.ArchType
182*333d2b36SAndroid Build Coastguard Worker	DexPreoptImagesDeps []android.OutputPaths
183*333d2b36SAndroid Build Coastguard Worker
184*333d2b36SAndroid Build Coastguard Worker	DexPreoptImageLocationsOnHost   []string // boot image location on host (file path without the arch subdirectory)
185*333d2b36SAndroid Build Coastguard Worker	DexPreoptImageLocationsOnDevice []string // boot image location on device (file path without the arch subdirectory)
186*333d2b36SAndroid Build Coastguard Worker
187*333d2b36SAndroid Build Coastguard Worker	PreoptBootClassPathDexFiles     android.Paths // file paths of boot class path files
188*333d2b36SAndroid Build Coastguard Worker	PreoptBootClassPathDexLocations []string      // virtual locations of boot class path files
189*333d2b36SAndroid Build Coastguard Worker
190*333d2b36SAndroid Build Coastguard Worker	NoCreateAppImage    bool
191*333d2b36SAndroid Build Coastguard Worker	ForceCreateAppImage bool
192*333d2b36SAndroid Build Coastguard Worker
193*333d2b36SAndroid Build Coastguard Worker	PresignedPrebuilt bool
194*333d2b36SAndroid Build Coastguard Worker
195*333d2b36SAndroid Build Coastguard Worker	// ApexPartition is the partition in which the dexpreopt files of apex system server jars (if any) are installed.
196*333d2b36SAndroid Build Coastguard Worker	// This is a noop unless the module is apex system server jar.
197*333d2b36SAndroid Build Coastguard Worker	ApexPartition string
198*333d2b36SAndroid Build Coastguard Worker}
199*333d2b36SAndroid Build Coastguard Worker
200*333d2b36SAndroid Build Coastguard Workertype globalSoongConfigSingleton struct{}
201*333d2b36SAndroid Build Coastguard Worker
202*333d2b36SAndroid Build Coastguard Workervar pctx = android.NewPackageContext("android/soong/dexpreopt")
203*333d2b36SAndroid Build Coastguard Worker
204*333d2b36SAndroid Build Coastguard Workerfunc init() {
205*333d2b36SAndroid Build Coastguard Worker	pctx.Import("android/soong/android")
206*333d2b36SAndroid Build Coastguard Worker	android.RegisterParallelSingletonType("dexpreopt-soong-config", func() android.Singleton {
207*333d2b36SAndroid Build Coastguard Worker		return &globalSoongConfigSingleton{}
208*333d2b36SAndroid Build Coastguard Worker	})
209*333d2b36SAndroid Build Coastguard Worker}
210*333d2b36SAndroid Build Coastguard Worker
211*333d2b36SAndroid Build Coastguard Workerfunc constructPath(ctx android.PathContext, path string) android.Path {
212*333d2b36SAndroid Build Coastguard Worker	buildDirPrefix := ctx.Config().SoongOutDir() + "/"
213*333d2b36SAndroid Build Coastguard Worker	if path == "" {
214*333d2b36SAndroid Build Coastguard Worker		return nil
215*333d2b36SAndroid Build Coastguard Worker	} else if strings.HasPrefix(path, buildDirPrefix) {
216*333d2b36SAndroid Build Coastguard Worker		return android.PathForOutput(ctx, strings.TrimPrefix(path, buildDirPrefix))
217*333d2b36SAndroid Build Coastguard Worker	} else {
218*333d2b36SAndroid Build Coastguard Worker		return android.PathForSource(ctx, path)
219*333d2b36SAndroid Build Coastguard Worker	}
220*333d2b36SAndroid Build Coastguard Worker}
221*333d2b36SAndroid Build Coastguard Worker
222*333d2b36SAndroid Build Coastguard Workerfunc constructPaths(ctx android.PathContext, paths []string) android.Paths {
223*333d2b36SAndroid Build Coastguard Worker	var ret android.Paths
224*333d2b36SAndroid Build Coastguard Worker	for _, path := range paths {
225*333d2b36SAndroid Build Coastguard Worker		ret = append(ret, constructPath(ctx, path))
226*333d2b36SAndroid Build Coastguard Worker	}
227*333d2b36SAndroid Build Coastguard Worker	return ret
228*333d2b36SAndroid Build Coastguard Worker}
229*333d2b36SAndroid Build Coastguard Worker
230*333d2b36SAndroid Build Coastguard Workerfunc constructWritablePath(ctx android.PathContext, path string) android.WritablePath {
231*333d2b36SAndroid Build Coastguard Worker	if path == "" {
232*333d2b36SAndroid Build Coastguard Worker		return nil
233*333d2b36SAndroid Build Coastguard Worker	}
234*333d2b36SAndroid Build Coastguard Worker	return constructPath(ctx, path).(android.WritablePath)
235*333d2b36SAndroid Build Coastguard Worker}
236*333d2b36SAndroid Build Coastguard Worker
237*333d2b36SAndroid Build Coastguard Worker// ParseGlobalConfig parses the given data assumed to be read from the global
238*333d2b36SAndroid Build Coastguard Worker// dexpreopt.config file into a GlobalConfig struct.
239*333d2b36SAndroid Build Coastguard Workerfunc ParseGlobalConfig(ctx android.PathContext, data []byte) (*GlobalConfig, error) {
240*333d2b36SAndroid Build Coastguard Worker	type GlobalJSONConfig struct {
241*333d2b36SAndroid Build Coastguard Worker		*GlobalConfig
242*333d2b36SAndroid Build Coastguard Worker
243*333d2b36SAndroid Build Coastguard Worker		// Copies of entries in GlobalConfig that are not constructable without extra parameters.  They will be
244*333d2b36SAndroid Build Coastguard Worker		// used to construct the real value manually below.
245*333d2b36SAndroid Build Coastguard Worker		BootImageProfiles []string
246*333d2b36SAndroid Build Coastguard Worker	}
247*333d2b36SAndroid Build Coastguard Worker
248*333d2b36SAndroid Build Coastguard Worker	config := GlobalJSONConfig{}
249*333d2b36SAndroid Build Coastguard Worker	err := json.Unmarshal(data, &config)
250*333d2b36SAndroid Build Coastguard Worker	if err != nil {
251*333d2b36SAndroid Build Coastguard Worker		return config.GlobalConfig, err
252*333d2b36SAndroid Build Coastguard Worker	}
253*333d2b36SAndroid Build Coastguard Worker
254*333d2b36SAndroid Build Coastguard Worker	// Construct paths that require a PathContext.
255*333d2b36SAndroid Build Coastguard Worker	config.GlobalConfig.BootImageProfiles = constructPaths(ctx, config.BootImageProfiles)
256*333d2b36SAndroid Build Coastguard Worker
257*333d2b36SAndroid Build Coastguard Worker	return config.GlobalConfig, nil
258*333d2b36SAndroid Build Coastguard Worker}
259*333d2b36SAndroid Build Coastguard Worker
260*333d2b36SAndroid Build Coastguard Workertype globalConfigAndRaw struct {
261*333d2b36SAndroid Build Coastguard Worker	global     *GlobalConfig
262*333d2b36SAndroid Build Coastguard Worker	data       []byte
263*333d2b36SAndroid Build Coastguard Worker	pathErrors []error
264*333d2b36SAndroid Build Coastguard Worker}
265*333d2b36SAndroid Build Coastguard Worker
266*333d2b36SAndroid Build Coastguard Worker// GetGlobalConfig returns the global dexpreopt.config that's created in the
267*333d2b36SAndroid Build Coastguard Worker// make config phase. It is loaded once the first time it is called for any
268*333d2b36SAndroid Build Coastguard Worker// ctx.Config(), and returns the same data for all future calls with the same
269*333d2b36SAndroid Build Coastguard Worker// ctx.Config(). A value can be inserted for tests using
270*333d2b36SAndroid Build Coastguard Worker// setDexpreoptTestGlobalConfig.
271*333d2b36SAndroid Build Coastguard Workerfunc GetGlobalConfig(ctx android.PathContext) *GlobalConfig {
272*333d2b36SAndroid Build Coastguard Worker	return getGlobalConfigRaw(ctx).global
273*333d2b36SAndroid Build Coastguard Worker}
274*333d2b36SAndroid Build Coastguard Worker
275*333d2b36SAndroid Build Coastguard Worker// GetGlobalConfigRawData is the same as GetGlobalConfig, except that it returns
276*333d2b36SAndroid Build Coastguard Worker// the literal content of dexpreopt.config.
277*333d2b36SAndroid Build Coastguard Workerfunc GetGlobalConfigRawData(ctx android.PathContext) []byte {
278*333d2b36SAndroid Build Coastguard Worker	return getGlobalConfigRaw(ctx).data
279*333d2b36SAndroid Build Coastguard Worker}
280*333d2b36SAndroid Build Coastguard Worker
281*333d2b36SAndroid Build Coastguard Workervar globalConfigOnceKey = android.NewOnceKey("DexpreoptGlobalConfig")
282*333d2b36SAndroid Build Coastguard Workervar testGlobalConfigOnceKey = android.NewOnceKey("TestDexpreoptGlobalConfig")
283*333d2b36SAndroid Build Coastguard Worker
284*333d2b36SAndroid Build Coastguard Workertype pathContextErrorCollector struct {
285*333d2b36SAndroid Build Coastguard Worker	android.PathContext
286*333d2b36SAndroid Build Coastguard Worker	errors []error
287*333d2b36SAndroid Build Coastguard Worker}
288*333d2b36SAndroid Build Coastguard Worker
289*333d2b36SAndroid Build Coastguard Workerfunc (p *pathContextErrorCollector) Errorf(format string, args ...interface{}) {
290*333d2b36SAndroid Build Coastguard Worker	p.errors = append(p.errors, fmt.Errorf(format, args...))
291*333d2b36SAndroid Build Coastguard Worker}
292*333d2b36SAndroid Build Coastguard Worker
293*333d2b36SAndroid Build Coastguard Workerfunc getGlobalConfigRaw(ctx android.PathContext) globalConfigAndRaw {
294*333d2b36SAndroid Build Coastguard Worker	config := ctx.Config().Once(globalConfigOnceKey, func() interface{} {
295*333d2b36SAndroid Build Coastguard Worker		if data, err := ctx.Config().DexpreoptGlobalConfig(ctx); err != nil {
296*333d2b36SAndroid Build Coastguard Worker			panic(err)
297*333d2b36SAndroid Build Coastguard Worker		} else if data != nil {
298*333d2b36SAndroid Build Coastguard Worker			pathErrorCollectorCtx := &pathContextErrorCollector{PathContext: ctx}
299*333d2b36SAndroid Build Coastguard Worker			globalConfig, err := ParseGlobalConfig(pathErrorCollectorCtx, data)
300*333d2b36SAndroid Build Coastguard Worker			if err != nil {
301*333d2b36SAndroid Build Coastguard Worker				panic(err)
302*333d2b36SAndroid Build Coastguard Worker			}
303*333d2b36SAndroid Build Coastguard Worker			return globalConfigAndRaw{globalConfig, data, pathErrorCollectorCtx.errors}
304*333d2b36SAndroid Build Coastguard Worker		}
305*333d2b36SAndroid Build Coastguard Worker
306*333d2b36SAndroid Build Coastguard Worker		// No global config filename set, see if there is a test config set
307*333d2b36SAndroid Build Coastguard Worker		return ctx.Config().Once(testGlobalConfigOnceKey, func() interface{} {
308*333d2b36SAndroid Build Coastguard Worker			// Nope, return a config with preopting disabled
309*333d2b36SAndroid Build Coastguard Worker			return globalConfigAndRaw{&GlobalConfig{
310*333d2b36SAndroid Build Coastguard Worker				DisablePreopt:           true,
311*333d2b36SAndroid Build Coastguard Worker				DisablePreoptBootImages: true,
312*333d2b36SAndroid Build Coastguard Worker				DisableGenerateProfile:  true,
313*333d2b36SAndroid Build Coastguard Worker			}, nil, nil}
314*333d2b36SAndroid Build Coastguard Worker		})
315*333d2b36SAndroid Build Coastguard Worker	}).(globalConfigAndRaw)
316*333d2b36SAndroid Build Coastguard Worker
317*333d2b36SAndroid Build Coastguard Worker	// Avoid non-deterministic errors by reporting cached path errors on all callers.
318*333d2b36SAndroid Build Coastguard Worker	for _, err := range config.pathErrors {
319*333d2b36SAndroid Build Coastguard Worker		if ctx.Config().AllowMissingDependencies() {
320*333d2b36SAndroid Build Coastguard Worker			// When AllowMissingDependencies it set, report errors through AddMissingDependencies.
321*333d2b36SAndroid Build Coastguard Worker			// If AddMissingDependencies doesn't exist on the current context (for example when
322*333d2b36SAndroid Build Coastguard Worker			// called with a SingletonContext), just swallow the errors since there is no way to
323*333d2b36SAndroid Build Coastguard Worker			// report them.
324*333d2b36SAndroid Build Coastguard Worker			if missingDepsCtx, ok := ctx.(interface {
325*333d2b36SAndroid Build Coastguard Worker				AddMissingDependencies(missingDeps []string)
326*333d2b36SAndroid Build Coastguard Worker			}); ok {
327*333d2b36SAndroid Build Coastguard Worker				missingDepsCtx.AddMissingDependencies([]string{err.Error()})
328*333d2b36SAndroid Build Coastguard Worker			}
329*333d2b36SAndroid Build Coastguard Worker		} else {
330*333d2b36SAndroid Build Coastguard Worker			android.ReportPathErrorf(ctx, "%s", err)
331*333d2b36SAndroid Build Coastguard Worker		}
332*333d2b36SAndroid Build Coastguard Worker	}
333*333d2b36SAndroid Build Coastguard Worker
334*333d2b36SAndroid Build Coastguard Worker	return config
335*333d2b36SAndroid Build Coastguard Worker}
336*333d2b36SAndroid Build Coastguard Worker
337*333d2b36SAndroid Build Coastguard Worker// SetTestGlobalConfig sets a GlobalConfig that future calls to GetGlobalConfig
338*333d2b36SAndroid Build Coastguard Worker// will return. It must be called before the first call to GetGlobalConfig for
339*333d2b36SAndroid Build Coastguard Worker// the config.
340*333d2b36SAndroid Build Coastguard Workerfunc SetTestGlobalConfig(config android.Config, globalConfig *GlobalConfig) {
341*333d2b36SAndroid Build Coastguard Worker	config.Once(testGlobalConfigOnceKey, func() interface{} { return globalConfigAndRaw{globalConfig, nil, nil} })
342*333d2b36SAndroid Build Coastguard Worker}
343*333d2b36SAndroid Build Coastguard Worker
344*333d2b36SAndroid Build Coastguard Worker// This struct is required to convert ModuleConfig from/to JSON.
345*333d2b36SAndroid Build Coastguard Worker// The types of fields in ModuleConfig are not convertible,
346*333d2b36SAndroid Build Coastguard Worker// so moduleJSONConfig has those fields as a convertible type.
347*333d2b36SAndroid Build Coastguard Workertype moduleJSONConfig struct {
348*333d2b36SAndroid Build Coastguard Worker	*ModuleConfig
349*333d2b36SAndroid Build Coastguard Worker
350*333d2b36SAndroid Build Coastguard Worker	BuildPath    string
351*333d2b36SAndroid Build Coastguard Worker	DexPath      string
352*333d2b36SAndroid Build Coastguard Worker	ManifestPath string
353*333d2b36SAndroid Build Coastguard Worker
354*333d2b36SAndroid Build Coastguard Worker	ProfileClassListing string
355*333d2b36SAndroid Build Coastguard Worker	ProfileBootListing  string
356*333d2b36SAndroid Build Coastguard Worker
357*333d2b36SAndroid Build Coastguard Worker	EnforceUsesLibrariesStatusFile string
358*333d2b36SAndroid Build Coastguard Worker	ClassLoaderContexts            jsonClassLoaderContextMap
359*333d2b36SAndroid Build Coastguard Worker
360*333d2b36SAndroid Build Coastguard Worker	DexPreoptImagesDeps [][]string
361*333d2b36SAndroid Build Coastguard Worker
362*333d2b36SAndroid Build Coastguard Worker	PreoptBootClassPathDexFiles []string
363*333d2b36SAndroid Build Coastguard Worker}
364*333d2b36SAndroid Build Coastguard Worker
365*333d2b36SAndroid Build Coastguard Worker// ParseModuleConfig parses a per-module dexpreopt.config file into a
366*333d2b36SAndroid Build Coastguard Worker// ModuleConfig struct. It is not used in Soong, which receives a ModuleConfig
367*333d2b36SAndroid Build Coastguard Worker// struct directly from java/dexpreopt.go. It is used in dexpreopt_gen called
368*333d2b36SAndroid Build Coastguard Worker// from Make to read the module dexpreopt.config written in the Make config
369*333d2b36SAndroid Build Coastguard Worker// stage.
370*333d2b36SAndroid Build Coastguard Workerfunc ParseModuleConfig(ctx android.PathContext, data []byte) (*ModuleConfig, error) {
371*333d2b36SAndroid Build Coastguard Worker	config := moduleJSONConfig{}
372*333d2b36SAndroid Build Coastguard Worker
373*333d2b36SAndroid Build Coastguard Worker	err := json.Unmarshal(data, &config)
374*333d2b36SAndroid Build Coastguard Worker	if err != nil {
375*333d2b36SAndroid Build Coastguard Worker		return config.ModuleConfig, err
376*333d2b36SAndroid Build Coastguard Worker	}
377*333d2b36SAndroid Build Coastguard Worker
378*333d2b36SAndroid Build Coastguard Worker	// Construct paths that require a PathContext.
379*333d2b36SAndroid Build Coastguard Worker	config.ModuleConfig.BuildPath = constructPath(ctx, config.BuildPath).(android.OutputPath)
380*333d2b36SAndroid Build Coastguard Worker	config.ModuleConfig.DexPath = constructPath(ctx, config.DexPath)
381*333d2b36SAndroid Build Coastguard Worker	config.ModuleConfig.ManifestPath = android.OptionalPathForPath(constructPath(ctx, config.ManifestPath))
382*333d2b36SAndroid Build Coastguard Worker	config.ModuleConfig.ProfileClassListing = android.OptionalPathForPath(constructPath(ctx, config.ProfileClassListing))
383*333d2b36SAndroid Build Coastguard Worker	config.ModuleConfig.EnforceUsesLibrariesStatusFile = constructPath(ctx, config.EnforceUsesLibrariesStatusFile)
384*333d2b36SAndroid Build Coastguard Worker	config.ModuleConfig.ClassLoaderContexts = fromJsonClassLoaderContext(ctx, config.ClassLoaderContexts)
385*333d2b36SAndroid Build Coastguard Worker	config.ModuleConfig.PreoptBootClassPathDexFiles = constructPaths(ctx, config.PreoptBootClassPathDexFiles)
386*333d2b36SAndroid Build Coastguard Worker
387*333d2b36SAndroid Build Coastguard Worker	// This needs to exist, but dependencies are already handled in Make, so we don't need to pass them through JSON.
388*333d2b36SAndroid Build Coastguard Worker	config.ModuleConfig.DexPreoptImagesDeps = make([]android.OutputPaths, len(config.ModuleConfig.Archs))
389*333d2b36SAndroid Build Coastguard Worker
390*333d2b36SAndroid Build Coastguard Worker	return config.ModuleConfig, nil
391*333d2b36SAndroid Build Coastguard Worker}
392*333d2b36SAndroid Build Coastguard Worker
393*333d2b36SAndroid Build Coastguard Workerfunc pathsListToStringLists(pathsList []android.OutputPaths) [][]string {
394*333d2b36SAndroid Build Coastguard Worker	ret := make([][]string, 0, len(pathsList))
395*333d2b36SAndroid Build Coastguard Worker	for _, paths := range pathsList {
396*333d2b36SAndroid Build Coastguard Worker		ret = append(ret, paths.Strings())
397*333d2b36SAndroid Build Coastguard Worker	}
398*333d2b36SAndroid Build Coastguard Worker	return ret
399*333d2b36SAndroid Build Coastguard Worker}
400*333d2b36SAndroid Build Coastguard Worker
401*333d2b36SAndroid Build Coastguard Workerfunc moduleConfigToJSON(config *ModuleConfig) ([]byte, error) {
402*333d2b36SAndroid Build Coastguard Worker	return json.MarshalIndent(&moduleJSONConfig{
403*333d2b36SAndroid Build Coastguard Worker		BuildPath:                      config.BuildPath.String(),
404*333d2b36SAndroid Build Coastguard Worker		DexPath:                        config.DexPath.String(),
405*333d2b36SAndroid Build Coastguard Worker		ManifestPath:                   config.ManifestPath.String(),
406*333d2b36SAndroid Build Coastguard Worker		ProfileClassListing:            config.ProfileClassListing.String(),
407*333d2b36SAndroid Build Coastguard Worker		ProfileBootListing:             config.ProfileBootListing.String(),
408*333d2b36SAndroid Build Coastguard Worker		EnforceUsesLibrariesStatusFile: config.EnforceUsesLibrariesStatusFile.String(),
409*333d2b36SAndroid Build Coastguard Worker		ClassLoaderContexts:            toJsonClassLoaderContext(config.ClassLoaderContexts),
410*333d2b36SAndroid Build Coastguard Worker		DexPreoptImagesDeps:            pathsListToStringLists(config.DexPreoptImagesDeps),
411*333d2b36SAndroid Build Coastguard Worker		PreoptBootClassPathDexFiles:    config.PreoptBootClassPathDexFiles.Strings(),
412*333d2b36SAndroid Build Coastguard Worker		ModuleConfig:                   config,
413*333d2b36SAndroid Build Coastguard Worker	}, "", "    ")
414*333d2b36SAndroid Build Coastguard Worker}
415*333d2b36SAndroid Build Coastguard Worker
416*333d2b36SAndroid Build Coastguard Worker// WriteModuleConfig serializes a ModuleConfig into a per-module dexpreopt.config JSON file.
417*333d2b36SAndroid Build Coastguard Worker// These config files are used for post-processing.
418*333d2b36SAndroid Build Coastguard Workerfunc WriteModuleConfig(ctx android.ModuleContext, config *ModuleConfig, path android.WritablePath) {
419*333d2b36SAndroid Build Coastguard Worker	if path == nil {
420*333d2b36SAndroid Build Coastguard Worker		return
421*333d2b36SAndroid Build Coastguard Worker	}
422*333d2b36SAndroid Build Coastguard Worker
423*333d2b36SAndroid Build Coastguard Worker	data, err := moduleConfigToJSON(config)
424*333d2b36SAndroid Build Coastguard Worker	if err != nil {
425*333d2b36SAndroid Build Coastguard Worker		ctx.ModuleErrorf("failed to JSON marshal module dexpreopt.config: %v", err)
426*333d2b36SAndroid Build Coastguard Worker		return
427*333d2b36SAndroid Build Coastguard Worker	}
428*333d2b36SAndroid Build Coastguard Worker
429*333d2b36SAndroid Build Coastguard Worker	android.WriteFileRule(ctx, path, string(data))
430*333d2b36SAndroid Build Coastguard Worker}
431*333d2b36SAndroid Build Coastguard Worker
432*333d2b36SAndroid Build Coastguard Worker// dex2oatModuleName returns the name of the module to use for the dex2oat host
433*333d2b36SAndroid Build Coastguard Worker// tool. It should be a binary module with public visibility that is compiled
434*333d2b36SAndroid Build Coastguard Worker// and installed for host.
435*333d2b36SAndroid Build Coastguard Workerfunc dex2oatModuleName(config android.Config) string {
436*333d2b36SAndroid Build Coastguard Worker	// Default to the debug variant of dex2oat to help find bugs.
437*333d2b36SAndroid Build Coastguard Worker	// Set USE_DEX2OAT_DEBUG to false for only building non-debug versions.
438*333d2b36SAndroid Build Coastguard Worker	if config.Getenv("USE_DEX2OAT_DEBUG") == "false" {
439*333d2b36SAndroid Build Coastguard Worker		return "dex2oat"
440*333d2b36SAndroid Build Coastguard Worker	} else {
441*333d2b36SAndroid Build Coastguard Worker		return "dex2oatd"
442*333d2b36SAndroid Build Coastguard Worker	}
443*333d2b36SAndroid Build Coastguard Worker}
444*333d2b36SAndroid Build Coastguard Worker
445*333d2b36SAndroid Build Coastguard Workertype dex2oatDependencyTag struct {
446*333d2b36SAndroid Build Coastguard Worker	blueprint.BaseDependencyTag
447*333d2b36SAndroid Build Coastguard Worker	android.LicenseAnnotationToolchainDependencyTag
448*333d2b36SAndroid Build Coastguard Worker}
449*333d2b36SAndroid Build Coastguard Worker
450*333d2b36SAndroid Build Coastguard Workerfunc (d dex2oatDependencyTag) ExcludeFromVisibilityEnforcement() {
451*333d2b36SAndroid Build Coastguard Worker}
452*333d2b36SAndroid Build Coastguard Worker
453*333d2b36SAndroid Build Coastguard Workerfunc (d dex2oatDependencyTag) ExcludeFromApexContents() {
454*333d2b36SAndroid Build Coastguard Worker}
455*333d2b36SAndroid Build Coastguard Worker
456*333d2b36SAndroid Build Coastguard Workerfunc (d dex2oatDependencyTag) AllowDisabledModuleDependency(target android.Module) bool {
457*333d2b36SAndroid Build Coastguard Worker	// RegisterToolDeps may run after the prebuilt mutators and hence register a
458*333d2b36SAndroid Build Coastguard Worker	// dependency on the source module even when the prebuilt is to be used.
459*333d2b36SAndroid Build Coastguard Worker	// dex2oatPathFromDep takes that into account when it retrieves the path to
460*333d2b36SAndroid Build Coastguard Worker	// the binary, but we also need to disable the check for dependencies on
461*333d2b36SAndroid Build Coastguard Worker	// disabled modules.
462*333d2b36SAndroid Build Coastguard Worker	return target.IsReplacedByPrebuilt()
463*333d2b36SAndroid Build Coastguard Worker}
464*333d2b36SAndroid Build Coastguard Worker
465*333d2b36SAndroid Build Coastguard Workerfunc (d dex2oatDependencyTag) AllowDisabledModuleDependencyProxy(
466*333d2b36SAndroid Build Coastguard Worker	ctx android.OtherModuleProviderContext, target android.ModuleProxy) bool {
467*333d2b36SAndroid Build Coastguard Worker	return android.OtherModuleProviderOrDefault(
468*333d2b36SAndroid Build Coastguard Worker		ctx, target, android.CommonModuleInfoKey).ReplacedByPrebuilt
469*333d2b36SAndroid Build Coastguard Worker}
470*333d2b36SAndroid Build Coastguard Worker
471*333d2b36SAndroid Build Coastguard Worker// Dex2oatDepTag represents the dependency onto the dex2oatd module. It is added to any module that
472*333d2b36SAndroid Build Coastguard Worker// needs dexpreopting and so it makes no sense for it to be checked for visibility or included in
473*333d2b36SAndroid Build Coastguard Worker// the apex.
474*333d2b36SAndroid Build Coastguard Workervar Dex2oatDepTag = dex2oatDependencyTag{}
475*333d2b36SAndroid Build Coastguard Worker
476*333d2b36SAndroid Build Coastguard Workervar _ android.ExcludeFromVisibilityEnforcementTag = Dex2oatDepTag
477*333d2b36SAndroid Build Coastguard Workervar _ android.ExcludeFromApexContentsTag = Dex2oatDepTag
478*333d2b36SAndroid Build Coastguard Workervar _ android.AllowDisabledModuleDependency = Dex2oatDepTag
479*333d2b36SAndroid Build Coastguard Worker
480*333d2b36SAndroid Build Coastguard Worker// RegisterToolDeps adds the necessary dependencies to binary modules for tools
481*333d2b36SAndroid Build Coastguard Worker// that are required later when Get(Cached)GlobalSoongConfig is called. It
482*333d2b36SAndroid Build Coastguard Worker// should be called from a mutator that's registered with
483*333d2b36SAndroid Build Coastguard Worker// android.RegistrationContext.FinalDepsMutators.
484*333d2b36SAndroid Build Coastguard Workerfunc RegisterToolDeps(ctx android.BottomUpMutatorContext) {
485*333d2b36SAndroid Build Coastguard Worker	dex2oatBin := dex2oatModuleName(ctx.Config())
486*333d2b36SAndroid Build Coastguard Worker	v := ctx.Config().BuildOSTarget.Variations()
487*333d2b36SAndroid Build Coastguard Worker	ctx.AddFarVariationDependencies(v, Dex2oatDepTag, dex2oatBin)
488*333d2b36SAndroid Build Coastguard Worker}
489*333d2b36SAndroid Build Coastguard Worker
490*333d2b36SAndroid Build Coastguard Workerfunc IsDex2oatNeeded(ctx android.PathContext) bool {
491*333d2b36SAndroid Build Coastguard Worker	global := GetGlobalConfig(ctx)
492*333d2b36SAndroid Build Coastguard Worker	return !global.DisablePreopt || !global.DisablePreoptBootImages
493*333d2b36SAndroid Build Coastguard Worker}
494*333d2b36SAndroid Build Coastguard Worker
495*333d2b36SAndroid Build Coastguard Workerfunc dex2oatPathFromDep(ctx android.ModuleContext) android.Path {
496*333d2b36SAndroid Build Coastguard Worker	if !IsDex2oatNeeded(ctx) {
497*333d2b36SAndroid Build Coastguard Worker		return nil
498*333d2b36SAndroid Build Coastguard Worker	}
499*333d2b36SAndroid Build Coastguard Worker
500*333d2b36SAndroid Build Coastguard Worker	dex2oatBin := dex2oatModuleName(ctx.Config())
501*333d2b36SAndroid Build Coastguard Worker
502*333d2b36SAndroid Build Coastguard Worker	// Find the right dex2oat module, trying to follow PrebuiltDepTag from source
503*333d2b36SAndroid Build Coastguard Worker	// to prebuilt if there is one. We wouldn't have to do this if the
504*333d2b36SAndroid Build Coastguard Worker	// prebuilt_postdeps mutator that replaces source deps with prebuilt deps was
505*333d2b36SAndroid Build Coastguard Worker	// run after RegisterToolDeps above, but changing that leads to ordering
506*333d2b36SAndroid Build Coastguard Worker	// problems between mutators (RegisterToolDeps needs to run late to act on
507*333d2b36SAndroid Build Coastguard Worker	// final variants, while prebuilt_postdeps needs to run before many of the
508*333d2b36SAndroid Build Coastguard Worker	// PostDeps mutators, like the APEX mutators). Hence we need to dig out the
509*333d2b36SAndroid Build Coastguard Worker	// prebuilt explicitly here instead.
510*333d2b36SAndroid Build Coastguard Worker	var dex2oatModule android.Module
511*333d2b36SAndroid Build Coastguard Worker	ctx.WalkDeps(func(child, parent android.Module) bool {
512*333d2b36SAndroid Build Coastguard Worker		if parent == ctx.Module() && ctx.OtherModuleDependencyTag(child) == Dex2oatDepTag {
513*333d2b36SAndroid Build Coastguard Worker			// Found the source module, or prebuilt module that has replaced the source.
514*333d2b36SAndroid Build Coastguard Worker			dex2oatModule = child
515*333d2b36SAndroid Build Coastguard Worker			if android.IsModulePrebuilt(child) {
516*333d2b36SAndroid Build Coastguard Worker				return false // If it's the prebuilt we're done.
517*333d2b36SAndroid Build Coastguard Worker			} else {
518*333d2b36SAndroid Build Coastguard Worker				return true // Recurse to check if the source has a prebuilt dependency.
519*333d2b36SAndroid Build Coastguard Worker			}
520*333d2b36SAndroid Build Coastguard Worker		}
521*333d2b36SAndroid Build Coastguard Worker		if parent == dex2oatModule && ctx.OtherModuleDependencyTag(child) == android.PrebuiltDepTag {
522*333d2b36SAndroid Build Coastguard Worker			if p := android.GetEmbeddedPrebuilt(child); p != nil && p.UsePrebuilt() {
523*333d2b36SAndroid Build Coastguard Worker				dex2oatModule = child // Found a prebuilt that should be used.
524*333d2b36SAndroid Build Coastguard Worker			}
525*333d2b36SAndroid Build Coastguard Worker		}
526*333d2b36SAndroid Build Coastguard Worker		return false
527*333d2b36SAndroid Build Coastguard Worker	})
528*333d2b36SAndroid Build Coastguard Worker
529*333d2b36SAndroid Build Coastguard Worker	if dex2oatModule == nil {
530*333d2b36SAndroid Build Coastguard Worker		// If this happens there's probably a missing call to AddToolDeps in DepsMutator.
531*333d2b36SAndroid Build Coastguard Worker		panic(fmt.Sprintf("Failed to lookup %s dependency", dex2oatBin))
532*333d2b36SAndroid Build Coastguard Worker	}
533*333d2b36SAndroid Build Coastguard Worker
534*333d2b36SAndroid Build Coastguard Worker	dex2oatPath := dex2oatModule.(android.HostToolProvider).HostToolPath()
535*333d2b36SAndroid Build Coastguard Worker	if !dex2oatPath.Valid() {
536*333d2b36SAndroid Build Coastguard Worker		panic(fmt.Sprintf("Failed to find host tool path in %s", dex2oatModule))
537*333d2b36SAndroid Build Coastguard Worker	}
538*333d2b36SAndroid Build Coastguard Worker
539*333d2b36SAndroid Build Coastguard Worker	return dex2oatPath.Path()
540*333d2b36SAndroid Build Coastguard Worker}
541*333d2b36SAndroid Build Coastguard Worker
542*333d2b36SAndroid Build Coastguard Worker// createGlobalSoongConfig creates a GlobalSoongConfig from the current context.
543*333d2b36SAndroid Build Coastguard Worker// Should not be used in dexpreopt_gen.
544*333d2b36SAndroid Build Coastguard Workerfunc createGlobalSoongConfig(ctx android.ModuleContext) *GlobalSoongConfig {
545*333d2b36SAndroid Build Coastguard Worker	return &GlobalSoongConfig{
546*333d2b36SAndroid Build Coastguard Worker		Profman:          ctx.Config().HostToolPath(ctx, "profman"),
547*333d2b36SAndroid Build Coastguard Worker		Dex2oat:          dex2oatPathFromDep(ctx),
548*333d2b36SAndroid Build Coastguard Worker		Aapt:             ctx.Config().HostToolPath(ctx, "aapt2"),
549*333d2b36SAndroid Build Coastguard Worker		SoongZip:         ctx.Config().HostToolPath(ctx, "soong_zip"),
550*333d2b36SAndroid Build Coastguard Worker		Zip2zip:          ctx.Config().HostToolPath(ctx, "zip2zip"),
551*333d2b36SAndroid Build Coastguard Worker		ManifestCheck:    ctx.Config().HostToolPath(ctx, "manifest_check"),
552*333d2b36SAndroid Build Coastguard Worker		ConstructContext: ctx.Config().HostToolPath(ctx, "construct_context"),
553*333d2b36SAndroid Build Coastguard Worker		UffdGcFlag:       getUffdGcFlagPath(ctx),
554*333d2b36SAndroid Build Coastguard Worker	}
555*333d2b36SAndroid Build Coastguard Worker}
556*333d2b36SAndroid Build Coastguard Worker
557*333d2b36SAndroid Build Coastguard Worker// The main reason for this Once cache for GlobalSoongConfig is to make the
558*333d2b36SAndroid Build Coastguard Worker// dex2oat path available to singletons. In ordinary modules we get it through a
559*333d2b36SAndroid Build Coastguard Worker// Dex2oatDepTag dependency, but in singletons there's no simple way to do the
560*333d2b36SAndroid Build Coastguard Worker// same thing and ensure the right variant is selected, hence this cache to make
561*333d2b36SAndroid Build Coastguard Worker// the resolved path available to singletons. This means we depend on there
562*333d2b36SAndroid Build Coastguard Worker// being at least one ordinary module with a Dex2oatDepTag dependency.
563*333d2b36SAndroid Build Coastguard Worker//
564*333d2b36SAndroid Build Coastguard Worker// TODO(b/147613152): Implement a way to deal with dependencies from singletons,
565*333d2b36SAndroid Build Coastguard Worker// and then possibly remove this cache altogether.
566*333d2b36SAndroid Build Coastguard Workervar globalSoongConfigOnceKey = android.NewOnceKey("DexpreoptGlobalSoongConfig")
567*333d2b36SAndroid Build Coastguard Worker
568*333d2b36SAndroid Build Coastguard Worker// GetGlobalSoongConfig creates a GlobalSoongConfig the first time it's called,
569*333d2b36SAndroid Build Coastguard Worker// and later returns the same cached instance.
570*333d2b36SAndroid Build Coastguard Workerfunc GetGlobalSoongConfig(ctx android.ModuleContext) *GlobalSoongConfig {
571*333d2b36SAndroid Build Coastguard Worker	globalSoong := ctx.Config().Once(globalSoongConfigOnceKey, func() interface{} {
572*333d2b36SAndroid Build Coastguard Worker		return createGlobalSoongConfig(ctx)
573*333d2b36SAndroid Build Coastguard Worker	}).(*GlobalSoongConfig)
574*333d2b36SAndroid Build Coastguard Worker
575*333d2b36SAndroid Build Coastguard Worker	// Always resolve the tool path from the dependency, to ensure that every
576*333d2b36SAndroid Build Coastguard Worker	// module has the dependency added properly.
577*333d2b36SAndroid Build Coastguard Worker	myDex2oat := dex2oatPathFromDep(ctx)
578*333d2b36SAndroid Build Coastguard Worker	if myDex2oat != globalSoong.Dex2oat {
579*333d2b36SAndroid Build Coastguard Worker		panic(fmt.Sprintf("Inconsistent dex2oat path in cached config: expected %s, got %s", globalSoong.Dex2oat, myDex2oat))
580*333d2b36SAndroid Build Coastguard Worker	}
581*333d2b36SAndroid Build Coastguard Worker
582*333d2b36SAndroid Build Coastguard Worker	return globalSoong
583*333d2b36SAndroid Build Coastguard Worker}
584*333d2b36SAndroid Build Coastguard Worker
585*333d2b36SAndroid Build Coastguard Worker// GetCachedGlobalSoongConfig returns a cached GlobalSoongConfig created by an
586*333d2b36SAndroid Build Coastguard Worker// earlier GetGlobalSoongConfig call. This function works with any context
587*333d2b36SAndroid Build Coastguard Worker// compatible with a basic PathContext, since it doesn't try to create a
588*333d2b36SAndroid Build Coastguard Worker// GlobalSoongConfig with the proper paths (which requires a full
589*333d2b36SAndroid Build Coastguard Worker// ModuleContext). If there has been no prior call to GetGlobalSoongConfig, nil
590*333d2b36SAndroid Build Coastguard Worker// is returned.
591*333d2b36SAndroid Build Coastguard Workerfunc GetCachedGlobalSoongConfig(ctx android.PathContext) *GlobalSoongConfig {
592*333d2b36SAndroid Build Coastguard Worker	return ctx.Config().Once(globalSoongConfigOnceKey, func() interface{} {
593*333d2b36SAndroid Build Coastguard Worker		return (*GlobalSoongConfig)(nil)
594*333d2b36SAndroid Build Coastguard Worker	}).(*GlobalSoongConfig)
595*333d2b36SAndroid Build Coastguard Worker}
596*333d2b36SAndroid Build Coastguard Worker
597*333d2b36SAndroid Build Coastguard Workertype globalJsonSoongConfig struct {
598*333d2b36SAndroid Build Coastguard Worker	Profman          string
599*333d2b36SAndroid Build Coastguard Worker	Dex2oat          string
600*333d2b36SAndroid Build Coastguard Worker	Aapt             string
601*333d2b36SAndroid Build Coastguard Worker	SoongZip         string
602*333d2b36SAndroid Build Coastguard Worker	Zip2zip          string
603*333d2b36SAndroid Build Coastguard Worker	ManifestCheck    string
604*333d2b36SAndroid Build Coastguard Worker	ConstructContext string
605*333d2b36SAndroid Build Coastguard Worker	UffdGcFlag       string
606*333d2b36SAndroid Build Coastguard Worker}
607*333d2b36SAndroid Build Coastguard Worker
608*333d2b36SAndroid Build Coastguard Worker// ParseGlobalSoongConfig parses the given data assumed to be read from the
609*333d2b36SAndroid Build Coastguard Worker// global dexpreopt_soong.config file into a GlobalSoongConfig struct. It is
610*333d2b36SAndroid Build Coastguard Worker// only used in dexpreopt_gen.
611*333d2b36SAndroid Build Coastguard Workerfunc ParseGlobalSoongConfig(ctx android.PathContext, data []byte) (*GlobalSoongConfig, error) {
612*333d2b36SAndroid Build Coastguard Worker	var jc globalJsonSoongConfig
613*333d2b36SAndroid Build Coastguard Worker
614*333d2b36SAndroid Build Coastguard Worker	err := json.Unmarshal(data, &jc)
615*333d2b36SAndroid Build Coastguard Worker	if err != nil {
616*333d2b36SAndroid Build Coastguard Worker		return &GlobalSoongConfig{}, err
617*333d2b36SAndroid Build Coastguard Worker	}
618*333d2b36SAndroid Build Coastguard Worker
619*333d2b36SAndroid Build Coastguard Worker	config := &GlobalSoongConfig{
620*333d2b36SAndroid Build Coastguard Worker		Profman:          constructPath(ctx, jc.Profman),
621*333d2b36SAndroid Build Coastguard Worker		Dex2oat:          constructPath(ctx, jc.Dex2oat),
622*333d2b36SAndroid Build Coastguard Worker		Aapt:             constructPath(ctx, jc.Aapt),
623*333d2b36SAndroid Build Coastguard Worker		SoongZip:         constructPath(ctx, jc.SoongZip),
624*333d2b36SAndroid Build Coastguard Worker		Zip2zip:          constructPath(ctx, jc.Zip2zip),
625*333d2b36SAndroid Build Coastguard Worker		ManifestCheck:    constructPath(ctx, jc.ManifestCheck),
626*333d2b36SAndroid Build Coastguard Worker		ConstructContext: constructPath(ctx, jc.ConstructContext),
627*333d2b36SAndroid Build Coastguard Worker		UffdGcFlag:       constructWritablePath(ctx, jc.UffdGcFlag),
628*333d2b36SAndroid Build Coastguard Worker	}
629*333d2b36SAndroid Build Coastguard Worker
630*333d2b36SAndroid Build Coastguard Worker	return config, nil
631*333d2b36SAndroid Build Coastguard Worker}
632*333d2b36SAndroid Build Coastguard Worker
633*333d2b36SAndroid Build Coastguard Worker// checkBootJarsConfigConsistency checks the consistency of BootJars and ApexBootJars fields in
634*333d2b36SAndroid Build Coastguard Worker// DexpreoptGlobalConfig and Config.productVariables.
635*333d2b36SAndroid Build Coastguard Workerfunc checkBootJarsConfigConsistency(ctx android.SingletonContext, dexpreoptConfig *GlobalConfig, config android.Config) {
636*333d2b36SAndroid Build Coastguard Worker	compareBootJars := func(property string, dexpreoptJars, variableJars android.ConfiguredJarList) {
637*333d2b36SAndroid Build Coastguard Worker		dexpreoptPairs := dexpreoptJars.CopyOfApexJarPairs()
638*333d2b36SAndroid Build Coastguard Worker		variablePairs := variableJars.CopyOfApexJarPairs()
639*333d2b36SAndroid Build Coastguard Worker		if !reflect.DeepEqual(dexpreoptPairs, variablePairs) {
640*333d2b36SAndroid Build Coastguard Worker			ctx.Errorf("Inconsistent configuration of %[1]s\n"+
641*333d2b36SAndroid Build Coastguard Worker				"    dexpreopt.GlobalConfig.%[1]s = %[2]s\n"+
642*333d2b36SAndroid Build Coastguard Worker				"    productVariables.%[1]s       = %[3]s",
643*333d2b36SAndroid Build Coastguard Worker				property, dexpreoptPairs, variablePairs)
644*333d2b36SAndroid Build Coastguard Worker		}
645*333d2b36SAndroid Build Coastguard Worker	}
646*333d2b36SAndroid Build Coastguard Worker
647*333d2b36SAndroid Build Coastguard Worker	compareBootJars("BootJars", dexpreoptConfig.BootJars, config.NonApexBootJars())
648*333d2b36SAndroid Build Coastguard Worker	compareBootJars("ApexBootJars", dexpreoptConfig.ApexBootJars, config.ApexBootJars())
649*333d2b36SAndroid Build Coastguard Worker}
650*333d2b36SAndroid Build Coastguard Worker
651*333d2b36SAndroid Build Coastguard Workerfunc (s *globalSoongConfigSingleton) GenerateBuildActions(ctx android.SingletonContext) {
652*333d2b36SAndroid Build Coastguard Worker	global := GetGlobalConfig(ctx)
653*333d2b36SAndroid Build Coastguard Worker	checkBootJarsConfigConsistency(ctx, global, ctx.Config())
654*333d2b36SAndroid Build Coastguard Worker
655*333d2b36SAndroid Build Coastguard Worker	if global.DisablePreopt {
656*333d2b36SAndroid Build Coastguard Worker		return
657*333d2b36SAndroid Build Coastguard Worker	}
658*333d2b36SAndroid Build Coastguard Worker
659*333d2b36SAndroid Build Coastguard Worker	buildUffdGcFlag(ctx, global)
660*333d2b36SAndroid Build Coastguard Worker
661*333d2b36SAndroid Build Coastguard Worker	config := GetCachedGlobalSoongConfig(ctx)
662*333d2b36SAndroid Build Coastguard Worker	if config == nil {
663*333d2b36SAndroid Build Coastguard Worker		// No module has enabled dexpreopting, so we assume there will be no calls
664*333d2b36SAndroid Build Coastguard Worker		// to dexpreopt_gen.
665*333d2b36SAndroid Build Coastguard Worker		return
666*333d2b36SAndroid Build Coastguard Worker	}
667*333d2b36SAndroid Build Coastguard Worker
668*333d2b36SAndroid Build Coastguard Worker	jc := globalJsonSoongConfig{
669*333d2b36SAndroid Build Coastguard Worker		Profman:          config.Profman.String(),
670*333d2b36SAndroid Build Coastguard Worker		Dex2oat:          config.Dex2oat.String(),
671*333d2b36SAndroid Build Coastguard Worker		Aapt:             config.Aapt.String(),
672*333d2b36SAndroid Build Coastguard Worker		SoongZip:         config.SoongZip.String(),
673*333d2b36SAndroid Build Coastguard Worker		Zip2zip:          config.Zip2zip.String(),
674*333d2b36SAndroid Build Coastguard Worker		ManifestCheck:    config.ManifestCheck.String(),
675*333d2b36SAndroid Build Coastguard Worker		ConstructContext: config.ConstructContext.String(),
676*333d2b36SAndroid Build Coastguard Worker		UffdGcFlag:       config.UffdGcFlag.String(),
677*333d2b36SAndroid Build Coastguard Worker	}
678*333d2b36SAndroid Build Coastguard Worker
679*333d2b36SAndroid Build Coastguard Worker	data, err := json.Marshal(jc)
680*333d2b36SAndroid Build Coastguard Worker	if err != nil {
681*333d2b36SAndroid Build Coastguard Worker		ctx.Errorf("failed to JSON marshal GlobalSoongConfig: %v", err)
682*333d2b36SAndroid Build Coastguard Worker		return
683*333d2b36SAndroid Build Coastguard Worker	}
684*333d2b36SAndroid Build Coastguard Worker
685*333d2b36SAndroid Build Coastguard Worker	android.WriteFileRule(ctx, android.PathForOutput(ctx, "dexpreopt_soong.config"), string(data))
686*333d2b36SAndroid Build Coastguard Worker}
687*333d2b36SAndroid Build Coastguard Worker
688*333d2b36SAndroid Build Coastguard Workerfunc (s *globalSoongConfigSingleton) MakeVars(ctx android.MakeVarsContext) {
689*333d2b36SAndroid Build Coastguard Worker	if GetGlobalConfig(ctx).DisablePreopt {
690*333d2b36SAndroid Build Coastguard Worker		return
691*333d2b36SAndroid Build Coastguard Worker	}
692*333d2b36SAndroid Build Coastguard Worker
693*333d2b36SAndroid Build Coastguard Worker	config := GetCachedGlobalSoongConfig(ctx)
694*333d2b36SAndroid Build Coastguard Worker	if config == nil {
695*333d2b36SAndroid Build Coastguard Worker		return
696*333d2b36SAndroid Build Coastguard Worker	}
697*333d2b36SAndroid Build Coastguard Worker
698*333d2b36SAndroid Build Coastguard Worker	ctx.Strict("DEX2OAT", config.Dex2oat.String())
699*333d2b36SAndroid Build Coastguard Worker	ctx.Strict("DEXPREOPT_GEN_DEPS", strings.Join([]string{
700*333d2b36SAndroid Build Coastguard Worker		config.Profman.String(),
701*333d2b36SAndroid Build Coastguard Worker		config.Dex2oat.String(),
702*333d2b36SAndroid Build Coastguard Worker		config.Aapt.String(),
703*333d2b36SAndroid Build Coastguard Worker		config.SoongZip.String(),
704*333d2b36SAndroid Build Coastguard Worker		config.Zip2zip.String(),
705*333d2b36SAndroid Build Coastguard Worker		config.ManifestCheck.String(),
706*333d2b36SAndroid Build Coastguard Worker		config.ConstructContext.String(),
707*333d2b36SAndroid Build Coastguard Worker		config.UffdGcFlag.String(),
708*333d2b36SAndroid Build Coastguard Worker	}, " "))
709*333d2b36SAndroid Build Coastguard Worker}
710*333d2b36SAndroid Build Coastguard Worker
711*333d2b36SAndroid Build Coastguard Workerfunc buildUffdGcFlag(ctx android.BuilderContext, global *GlobalConfig) {
712*333d2b36SAndroid Build Coastguard Worker	uffdGcFlag := getUffdGcFlagPath(ctx)
713*333d2b36SAndroid Build Coastguard Worker
714*333d2b36SAndroid Build Coastguard Worker	if global.EnableUffdGc == "true" {
715*333d2b36SAndroid Build Coastguard Worker		android.WriteFileRuleVerbatim(ctx, uffdGcFlag, "--runtime-arg -Xgc:CMC")
716*333d2b36SAndroid Build Coastguard Worker	} else if global.EnableUffdGc == "false" {
717*333d2b36SAndroid Build Coastguard Worker		android.WriteFileRuleVerbatim(ctx, uffdGcFlag, "")
718*333d2b36SAndroid Build Coastguard Worker	} else if global.EnableUffdGc == "default" {
719*333d2b36SAndroid Build Coastguard Worker		// Generated by `build/make/core/Makefile`.
720*333d2b36SAndroid Build Coastguard Worker		kernelVersionFile := android.PathForOutput(ctx, "dexpreopt/kernel_version_for_uffd_gc.txt")
721*333d2b36SAndroid Build Coastguard Worker		// Determine the UFFD GC flag by the kernel version file.
722*333d2b36SAndroid Build Coastguard Worker		rule := android.NewRuleBuilder(pctx, ctx)
723*333d2b36SAndroid Build Coastguard Worker		rule.Command().
724*333d2b36SAndroid Build Coastguard Worker			Tool(ctx.Config().HostToolPath(ctx, "construct_uffd_gc_flag")).
725*333d2b36SAndroid Build Coastguard Worker			Input(kernelVersionFile).
726*333d2b36SAndroid Build Coastguard Worker			Output(uffdGcFlag)
727*333d2b36SAndroid Build Coastguard Worker		rule.Restat().Build("dexpreopt_uffd_gc_flag", "dexpreopt_uffd_gc_flag")
728*333d2b36SAndroid Build Coastguard Worker	} else {
729*333d2b36SAndroid Build Coastguard Worker		panic(fmt.Sprintf("Unknown value of PRODUCT_ENABLE_UFFD_GC: %s", global.EnableUffdGc))
730*333d2b36SAndroid Build Coastguard Worker	}
731*333d2b36SAndroid Build Coastguard Worker}
732*333d2b36SAndroid Build Coastguard Worker
733*333d2b36SAndroid Build Coastguard Workerfunc GlobalConfigForTests(ctx android.PathContext) *GlobalConfig {
734*333d2b36SAndroid Build Coastguard Worker	return &GlobalConfig{
735*333d2b36SAndroid Build Coastguard Worker		DisablePreopt:                  false,
736*333d2b36SAndroid Build Coastguard Worker		DisablePreoptModules:           nil,
737*333d2b36SAndroid Build Coastguard Worker		OnlyPreoptArtBootImage:         false,
738*333d2b36SAndroid Build Coastguard Worker		HasSystemOther:                 false,
739*333d2b36SAndroid Build Coastguard Worker		PatternsOnSystemOther:          nil,
740*333d2b36SAndroid Build Coastguard Worker		DisableGenerateProfile:         false,
741*333d2b36SAndroid Build Coastguard Worker		ProfileDir:                     "",
742*333d2b36SAndroid Build Coastguard Worker		BootJars:                       android.EmptyConfiguredJarList(),
743*333d2b36SAndroid Build Coastguard Worker		ApexBootJars:                   android.EmptyConfiguredJarList(),
744*333d2b36SAndroid Build Coastguard Worker		ArtApexJars:                    android.EmptyConfiguredJarList(),
745*333d2b36SAndroid Build Coastguard Worker		TestOnlyArtBootImageJars:       android.EmptyConfiguredJarList(),
746*333d2b36SAndroid Build Coastguard Worker		SystemServerJars:               android.EmptyConfiguredJarList(),
747*333d2b36SAndroid Build Coastguard Worker		SystemServerApps:               nil,
748*333d2b36SAndroid Build Coastguard Worker		ApexSystemServerJars:           android.EmptyConfiguredJarList(),
749*333d2b36SAndroid Build Coastguard Worker		StandaloneSystemServerJars:     android.EmptyConfiguredJarList(),
750*333d2b36SAndroid Build Coastguard Worker		ApexStandaloneSystemServerJars: android.EmptyConfiguredJarList(),
751*333d2b36SAndroid Build Coastguard Worker		SpeedApps:                      nil,
752*333d2b36SAndroid Build Coastguard Worker		PreoptFlags:                    nil,
753*333d2b36SAndroid Build Coastguard Worker		DefaultCompilerFilter:          "",
754*333d2b36SAndroid Build Coastguard Worker		SystemServerCompilerFilter:     "",
755*333d2b36SAndroid Build Coastguard Worker		GenerateDMFiles:                false,
756*333d2b36SAndroid Build Coastguard Worker		NoDebugInfo:                    false,
757*333d2b36SAndroid Build Coastguard Worker		DontResolveStartupStrings:      false,
758*333d2b36SAndroid Build Coastguard Worker		AlwaysSystemServerDebugInfo:    false,
759*333d2b36SAndroid Build Coastguard Worker		NeverSystemServerDebugInfo:     false,
760*333d2b36SAndroid Build Coastguard Worker		AlwaysOtherDebugInfo:           false,
761*333d2b36SAndroid Build Coastguard Worker		NeverOtherDebugInfo:            false,
762*333d2b36SAndroid Build Coastguard Worker		IsEng:                          false,
763*333d2b36SAndroid Build Coastguard Worker		SanitizeLite:                   false,
764*333d2b36SAndroid Build Coastguard Worker		DefaultAppImages:               false,
765*333d2b36SAndroid Build Coastguard Worker		Dex2oatXmx:                     "",
766*333d2b36SAndroid Build Coastguard Worker		Dex2oatXms:                     "",
767*333d2b36SAndroid Build Coastguard Worker		EmptyDirectory:                 "empty_dir",
768*333d2b36SAndroid Build Coastguard Worker		CpuVariant:                     nil,
769*333d2b36SAndroid Build Coastguard Worker		InstructionSetFeatures:         nil,
770*333d2b36SAndroid Build Coastguard Worker		BootImageProfiles:              nil,
771*333d2b36SAndroid Build Coastguard Worker		BootFlags:                      "",
772*333d2b36SAndroid Build Coastguard Worker		Dex2oatImageXmx:                "",
773*333d2b36SAndroid Build Coastguard Worker		Dex2oatImageXms:                "",
774*333d2b36SAndroid Build Coastguard Worker	}
775*333d2b36SAndroid Build Coastguard Worker}
776*333d2b36SAndroid Build Coastguard Worker
777*333d2b36SAndroid Build Coastguard Workerfunc globalSoongConfigForTests(ctx android.BuilderContext) *GlobalSoongConfig {
778*333d2b36SAndroid Build Coastguard Worker	return &GlobalSoongConfig{
779*333d2b36SAndroid Build Coastguard Worker		Profman:          android.PathForTesting("profman"),
780*333d2b36SAndroid Build Coastguard Worker		Dex2oat:          android.PathForTesting("dex2oat"),
781*333d2b36SAndroid Build Coastguard Worker		Aapt:             android.PathForTesting("aapt2"),
782*333d2b36SAndroid Build Coastguard Worker		SoongZip:         android.PathForTesting("soong_zip"),
783*333d2b36SAndroid Build Coastguard Worker		Zip2zip:          android.PathForTesting("zip2zip"),
784*333d2b36SAndroid Build Coastguard Worker		ManifestCheck:    android.PathForTesting("manifest_check"),
785*333d2b36SAndroid Build Coastguard Worker		ConstructContext: android.PathForTesting("construct_context"),
786*333d2b36SAndroid Build Coastguard Worker		UffdGcFlag:       android.PathForOutput(ctx, "dexpreopt_test", "uffd_gc_flag.txt"),
787*333d2b36SAndroid Build Coastguard Worker	}
788*333d2b36SAndroid Build Coastguard Worker}
789*333d2b36SAndroid Build Coastguard Worker
790*333d2b36SAndroid Build Coastguard Workerfunc GetDexpreoptDirName(ctx android.PathContext) string {
791*333d2b36SAndroid Build Coastguard Worker	prefix := "dexpreopt_"
792*333d2b36SAndroid Build Coastguard Worker	targets := ctx.Config().Targets[android.Android]
793*333d2b36SAndroid Build Coastguard Worker	if len(targets) > 0 {
794*333d2b36SAndroid Build Coastguard Worker		return prefix + targets[0].Arch.ArchType.String()
795*333d2b36SAndroid Build Coastguard Worker	}
796*333d2b36SAndroid Build Coastguard Worker	return prefix + "unknown_target"
797*333d2b36SAndroid Build Coastguard Worker}
798*333d2b36SAndroid Build Coastguard Worker
799*333d2b36SAndroid Build Coastguard Workerfunc getUffdGcFlagPath(ctx android.PathContext) android.WritablePath {
800*333d2b36SAndroid Build Coastguard Worker	return android.PathForOutput(ctx, "dexpreopt/uffd_gc_flag.txt")
801*333d2b36SAndroid Build Coastguard Worker}
802