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