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 java 16*333d2b36SAndroid Build Coastguard Worker 17*333d2b36SAndroid Build Coastguard Workerimport ( 18*333d2b36SAndroid Build Coastguard Worker "path/filepath" 19*333d2b36SAndroid Build Coastguard Worker "sort" 20*333d2b36SAndroid Build Coastguard Worker "strings" 21*333d2b36SAndroid Build Coastguard Worker 22*333d2b36SAndroid Build Coastguard Worker "github.com/google/blueprint/proptools" 23*333d2b36SAndroid Build Coastguard Worker 24*333d2b36SAndroid Build Coastguard Worker "android/soong/android" 25*333d2b36SAndroid Build Coastguard Worker "android/soong/dexpreopt" 26*333d2b36SAndroid Build Coastguard Worker) 27*333d2b36SAndroid Build Coastguard Worker 28*333d2b36SAndroid Build Coastguard Workertype DexpreopterInterface interface { 29*333d2b36SAndroid Build Coastguard Worker // True if the java module is to be dexed and installed on devices. 30*333d2b36SAndroid Build Coastguard Worker // Structs that embed dexpreopter must implement this. 31*333d2b36SAndroid Build Coastguard Worker IsInstallable() bool 32*333d2b36SAndroid Build Coastguard Worker 33*333d2b36SAndroid Build Coastguard Worker // True if dexpreopt is disabled for the java module. 34*333d2b36SAndroid Build Coastguard Worker dexpreoptDisabled(ctx android.BaseModuleContext, libraryName string) bool 35*333d2b36SAndroid Build Coastguard Worker 36*333d2b36SAndroid Build Coastguard Worker // If the java module is to be installed into an APEX, this list contains information about the 37*333d2b36SAndroid Build Coastguard Worker // dexpreopt outputs to be installed on devices. Note that these dexpreopt outputs are installed 38*333d2b36SAndroid Build Coastguard Worker // outside of the APEX. 39*333d2b36SAndroid Build Coastguard Worker DexpreoptBuiltInstalledForApex() []dexpreopterInstall 40*333d2b36SAndroid Build Coastguard Worker 41*333d2b36SAndroid Build Coastguard Worker // The Make entries to install the dexpreopt outputs. Derived from 42*333d2b36SAndroid Build Coastguard Worker // `DexpreoptBuiltInstalledForApex`. 43*333d2b36SAndroid Build Coastguard Worker AndroidMkEntriesForApex() []android.AndroidMkEntries 44*333d2b36SAndroid Build Coastguard Worker 45*333d2b36SAndroid Build Coastguard Worker // See `dexpreopter.outputProfilePathOnHost`. 46*333d2b36SAndroid Build Coastguard Worker OutputProfilePathOnHost() android.Path 47*333d2b36SAndroid Build Coastguard Worker} 48*333d2b36SAndroid Build Coastguard Worker 49*333d2b36SAndroid Build Coastguard Workertype dexpreopterInstall struct { 50*333d2b36SAndroid Build Coastguard Worker // A unique name to distinguish an output from others for the same java library module. Usually in 51*333d2b36SAndroid Build Coastguard Worker // the form of `<arch>-<encoded-path>.odex/vdex/art`. 52*333d2b36SAndroid Build Coastguard Worker name string 53*333d2b36SAndroid Build Coastguard Worker 54*333d2b36SAndroid Build Coastguard Worker // The name of the input java module. 55*333d2b36SAndroid Build Coastguard Worker moduleName string 56*333d2b36SAndroid Build Coastguard Worker 57*333d2b36SAndroid Build Coastguard Worker // The path to the dexpreopt output on host. 58*333d2b36SAndroid Build Coastguard Worker outputPathOnHost android.Path 59*333d2b36SAndroid Build Coastguard Worker 60*333d2b36SAndroid Build Coastguard Worker // The directory on the device for the output to install to. 61*333d2b36SAndroid Build Coastguard Worker installDirOnDevice android.InstallPath 62*333d2b36SAndroid Build Coastguard Worker 63*333d2b36SAndroid Build Coastguard Worker // The basename (the last segment of the path) for the output to install as. 64*333d2b36SAndroid Build Coastguard Worker installFileOnDevice string 65*333d2b36SAndroid Build Coastguard Worker} 66*333d2b36SAndroid Build Coastguard Worker 67*333d2b36SAndroid Build Coastguard Worker// The full module name of the output in the makefile. 68*333d2b36SAndroid Build Coastguard Workerfunc (install *dexpreopterInstall) FullModuleName() string { 69*333d2b36SAndroid Build Coastguard Worker return install.moduleName + install.SubModuleName() 70*333d2b36SAndroid Build Coastguard Worker} 71*333d2b36SAndroid Build Coastguard Worker 72*333d2b36SAndroid Build Coastguard Worker// The sub-module name of the output in the makefile (the name excluding the java module name). 73*333d2b36SAndroid Build Coastguard Workerfunc (install *dexpreopterInstall) SubModuleName() string { 74*333d2b36SAndroid Build Coastguard Worker return "-dexpreopt-" + install.name 75*333d2b36SAndroid Build Coastguard Worker} 76*333d2b36SAndroid Build Coastguard Worker 77*333d2b36SAndroid Build Coastguard Worker// Returns Make entries for installing the file. 78*333d2b36SAndroid Build Coastguard Worker// 79*333d2b36SAndroid Build Coastguard Worker// This function uses a value receiver rather than a pointer receiver to ensure that the object is 80*333d2b36SAndroid Build Coastguard Worker// safe to use in `android.AndroidMkExtraEntriesFunc`. 81*333d2b36SAndroid Build Coastguard Workerfunc (install dexpreopterInstall) ToMakeEntries() android.AndroidMkEntries { 82*333d2b36SAndroid Build Coastguard Worker return android.AndroidMkEntries{ 83*333d2b36SAndroid Build Coastguard Worker Class: "ETC", 84*333d2b36SAndroid Build Coastguard Worker OutputFile: android.OptionalPathForPath(install.outputPathOnHost), 85*333d2b36SAndroid Build Coastguard Worker ExtraEntries: []android.AndroidMkExtraEntriesFunc{ 86*333d2b36SAndroid Build Coastguard Worker func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { 87*333d2b36SAndroid Build Coastguard Worker entries.SetString("LOCAL_MODULE", install.FullModuleName()) 88*333d2b36SAndroid Build Coastguard Worker entries.SetString("LOCAL_MODULE_PATH", install.installDirOnDevice.String()) 89*333d2b36SAndroid Build Coastguard Worker entries.SetString("LOCAL_INSTALLED_MODULE_STEM", install.installFileOnDevice) 90*333d2b36SAndroid Build Coastguard Worker entries.SetString("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", "false") 91*333d2b36SAndroid Build Coastguard Worker }, 92*333d2b36SAndroid Build Coastguard Worker }, 93*333d2b36SAndroid Build Coastguard Worker } 94*333d2b36SAndroid Build Coastguard Worker} 95*333d2b36SAndroid Build Coastguard Worker 96*333d2b36SAndroid Build Coastguard Workertype Dexpreopter struct { 97*333d2b36SAndroid Build Coastguard Worker dexpreopter 98*333d2b36SAndroid Build Coastguard Worker} 99*333d2b36SAndroid Build Coastguard Worker 100*333d2b36SAndroid Build Coastguard Workertype dexpreopter struct { 101*333d2b36SAndroid Build Coastguard Worker dexpreoptProperties DexpreoptProperties 102*333d2b36SAndroid Build Coastguard Worker importDexpreoptProperties ImportDexpreoptProperties 103*333d2b36SAndroid Build Coastguard Worker 104*333d2b36SAndroid Build Coastguard Worker // If true, the dexpreopt rules will not be generated 105*333d2b36SAndroid Build Coastguard Worker // Unlike Dex_preopt.Enabled which is user-facing, 106*333d2b36SAndroid Build Coastguard Worker // shouldDisableDexpreopt is a mutated propery. 107*333d2b36SAndroid Build Coastguard Worker shouldDisableDexpreopt bool 108*333d2b36SAndroid Build Coastguard Worker 109*333d2b36SAndroid Build Coastguard Worker installPath android.InstallPath 110*333d2b36SAndroid Build Coastguard Worker uncompressedDex bool 111*333d2b36SAndroid Build Coastguard Worker isSDKLibrary bool 112*333d2b36SAndroid Build Coastguard Worker isApp bool 113*333d2b36SAndroid Build Coastguard Worker isTest bool 114*333d2b36SAndroid Build Coastguard Worker isPresignedPrebuilt bool 115*333d2b36SAndroid Build Coastguard Worker preventInstall bool 116*333d2b36SAndroid Build Coastguard Worker 117*333d2b36SAndroid Build Coastguard Worker manifestFile android.Path 118*333d2b36SAndroid Build Coastguard Worker statusFile android.WritablePath 119*333d2b36SAndroid Build Coastguard Worker enforceUsesLibs bool 120*333d2b36SAndroid Build Coastguard Worker classLoaderContexts dexpreopt.ClassLoaderContextMap 121*333d2b36SAndroid Build Coastguard Worker 122*333d2b36SAndroid Build Coastguard Worker // See the `dexpreopt` function for details. 123*333d2b36SAndroid Build Coastguard Worker builtInstalled string 124*333d2b36SAndroid Build Coastguard Worker builtInstalledForApex []dexpreopterInstall 125*333d2b36SAndroid Build Coastguard Worker 126*333d2b36SAndroid Build Coastguard Worker // The config is used for two purposes: 127*333d2b36SAndroid Build Coastguard Worker // - Passing dexpreopt information about libraries from Soong to Make. This is needed when 128*333d2b36SAndroid Build Coastguard Worker // a <uses-library> is defined in Android.bp, but used in Android.mk (see dex_preopt_config_merger.py). 129*333d2b36SAndroid Build Coastguard Worker // Note that dexpreopt.config might be needed even if dexpreopt is disabled for the library itself. 130*333d2b36SAndroid Build Coastguard Worker // - Dexpreopt post-processing (using dexpreopt artifacts from a prebuilt system image to incrementally 131*333d2b36SAndroid Build Coastguard Worker // dexpreopt another partition). 132*333d2b36SAndroid Build Coastguard Worker configPath android.WritablePath 133*333d2b36SAndroid Build Coastguard Worker 134*333d2b36SAndroid Build Coastguard Worker // The path to the profile on host that dexpreopter generates. This is used as the input for 135*333d2b36SAndroid Build Coastguard Worker // dex2oat. 136*333d2b36SAndroid Build Coastguard Worker outputProfilePathOnHost android.Path 137*333d2b36SAndroid Build Coastguard Worker 138*333d2b36SAndroid Build Coastguard Worker // The path to the profile that dexpreopter accepts. It must be in the binary format. If this is 139*333d2b36SAndroid Build Coastguard Worker // set, it overrides the profile settings in `dexpreoptProperties`. 140*333d2b36SAndroid Build Coastguard Worker inputProfilePathOnHost android.Path 141*333d2b36SAndroid Build Coastguard Worker 142*333d2b36SAndroid Build Coastguard Worker // The path to the profile that matches the dex optimized by r8/d8. It is in text format. If this is 143*333d2b36SAndroid Build Coastguard Worker // set, it will be converted to a binary profile which will be subsequently used for dexpreopt. 144*333d2b36SAndroid Build Coastguard Worker rewrittenProfile android.Path 145*333d2b36SAndroid Build Coastguard Worker} 146*333d2b36SAndroid Build Coastguard Worker 147*333d2b36SAndroid Build Coastguard Workertype DexpreoptProperties struct { 148*333d2b36SAndroid Build Coastguard Worker Dex_preopt struct { 149*333d2b36SAndroid Build Coastguard Worker // If false, prevent dexpreopting. Defaults to true. 150*333d2b36SAndroid Build Coastguard Worker Enabled proptools.Configurable[bool] `android:"replace_instead_of_append"` 151*333d2b36SAndroid Build Coastguard Worker 152*333d2b36SAndroid Build Coastguard Worker // If true, generate an app image (.art file) for this module. 153*333d2b36SAndroid Build Coastguard Worker App_image proptools.Configurable[bool] `android:"replace_instead_of_append"` 154*333d2b36SAndroid Build Coastguard Worker 155*333d2b36SAndroid Build Coastguard Worker // If true, use a checked-in profile to guide optimization. Defaults to false unless 156*333d2b36SAndroid Build Coastguard Worker // a matching profile is set or a profile is found in PRODUCT_DEX_PREOPT_PROFILE_DIR 157*333d2b36SAndroid Build Coastguard Worker // that matches the name of this module, in which case it is defaulted to true. 158*333d2b36SAndroid Build Coastguard Worker Profile_guided proptools.Configurable[bool] `android:"replace_instead_of_append"` 159*333d2b36SAndroid Build Coastguard Worker 160*333d2b36SAndroid Build Coastguard Worker // If set, provides the path to profile relative to the Android.bp file. If not set, 161*333d2b36SAndroid Build Coastguard Worker // defaults to searching for a file that matches the name of this module in the default 162*333d2b36SAndroid Build Coastguard Worker // profile location set by PRODUCT_DEX_PREOPT_PROFILE_DIR, or empty if not found. 163*333d2b36SAndroid Build Coastguard Worker Profile proptools.Configurable[string] `android:"path,replace_instead_of_append"` 164*333d2b36SAndroid Build Coastguard Worker 165*333d2b36SAndroid Build Coastguard Worker // If set to true, r8/d8 will use `profile` as input to generate a new profile that matches 166*333d2b36SAndroid Build Coastguard Worker // the optimized dex. 167*333d2b36SAndroid Build Coastguard Worker // The new profile will be subsequently used as the profile to dexpreopt the dex file. 168*333d2b36SAndroid Build Coastguard Worker Enable_profile_rewriting proptools.Configurable[bool] `android:"replace_instead_of_append"` 169*333d2b36SAndroid Build Coastguard Worker } 170*333d2b36SAndroid Build Coastguard Worker 171*333d2b36SAndroid Build Coastguard Worker Dex_preopt_result struct { 172*333d2b36SAndroid Build Coastguard Worker // True if profile-guided optimization is actually enabled. 173*333d2b36SAndroid Build Coastguard Worker Profile_guided bool 174*333d2b36SAndroid Build Coastguard Worker } `blueprint:"mutated"` 175*333d2b36SAndroid Build Coastguard Worker} 176*333d2b36SAndroid Build Coastguard Worker 177*333d2b36SAndroid Build Coastguard Workertype ImportDexpreoptProperties struct { 178*333d2b36SAndroid Build Coastguard Worker Dex_preopt struct { 179*333d2b36SAndroid Build Coastguard Worker // If true, use the profile in the prebuilt APEX to guide optimization. Defaults to false. 180*333d2b36SAndroid Build Coastguard Worker Profile_guided *bool 181*333d2b36SAndroid Build Coastguard Worker } 182*333d2b36SAndroid Build Coastguard Worker} 183*333d2b36SAndroid Build Coastguard Worker 184*333d2b36SAndroid Build Coastguard Workerfunc init() { 185*333d2b36SAndroid Build Coastguard Worker dexpreopt.DexpreoptRunningInSoong = true 186*333d2b36SAndroid Build Coastguard Worker} 187*333d2b36SAndroid Build Coastguard Worker 188*333d2b36SAndroid Build Coastguard Workerfunc isApexVariant(ctx android.BaseModuleContext) bool { 189*333d2b36SAndroid Build Coastguard Worker apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) 190*333d2b36SAndroid Build Coastguard Worker return !apexInfo.IsForPlatform() 191*333d2b36SAndroid Build Coastguard Worker} 192*333d2b36SAndroid Build Coastguard Worker 193*333d2b36SAndroid Build Coastguard Workerfunc forPrebuiltApex(ctx android.BaseModuleContext) bool { 194*333d2b36SAndroid Build Coastguard Worker apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) 195*333d2b36SAndroid Build Coastguard Worker return apexInfo.ForPrebuiltApex 196*333d2b36SAndroid Build Coastguard Worker} 197*333d2b36SAndroid Build Coastguard Worker 198*333d2b36SAndroid Build Coastguard Worker// For apex variant of modules, this returns true on the source variant if the prebuilt apex 199*333d2b36SAndroid Build Coastguard Worker// has been selected using apex_contributions. 200*333d2b36SAndroid Build Coastguard Worker// The prebuilt apex will be responsible for generating the dexpreopt rules of the deapexed java lib. 201*333d2b36SAndroid Build Coastguard Workerfunc disableSourceApexVariant(ctx android.BaseModuleContext) bool { 202*333d2b36SAndroid Build Coastguard Worker if !isApexVariant(ctx) { 203*333d2b36SAndroid Build Coastguard Worker return false // platform variant 204*333d2b36SAndroid Build Coastguard Worker } 205*333d2b36SAndroid Build Coastguard Worker apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) 206*333d2b36SAndroid Build Coastguard Worker psi := android.PrebuiltSelectionInfoMap{} 207*333d2b36SAndroid Build Coastguard Worker ctx.VisitDirectDeps(func(am android.Module) { 208*333d2b36SAndroid Build Coastguard Worker if prebuiltSelectionInfo, ok := android.OtherModuleProvider(ctx, am, android.PrebuiltSelectionInfoProvider); ok { 209*333d2b36SAndroid Build Coastguard Worker psi = prebuiltSelectionInfo 210*333d2b36SAndroid Build Coastguard Worker } 211*333d2b36SAndroid Build Coastguard Worker }) 212*333d2b36SAndroid Build Coastguard Worker 213*333d2b36SAndroid Build Coastguard Worker // Find the apex variant for this module 214*333d2b36SAndroid Build Coastguard Worker apexVariantsWithoutTestApexes := []string{} 215*333d2b36SAndroid Build Coastguard Worker if apexInfo.BaseApexName != "" { 216*333d2b36SAndroid Build Coastguard Worker // This is a transitive dependency of an override_apex 217*333d2b36SAndroid Build Coastguard Worker apexVariantsWithoutTestApexes = append(apexVariantsWithoutTestApexes, apexInfo.BaseApexName) 218*333d2b36SAndroid Build Coastguard Worker } else { 219*333d2b36SAndroid Build Coastguard Worker _, variants, _ := android.ListSetDifference(apexInfo.InApexVariants, apexInfo.TestApexes) 220*333d2b36SAndroid Build Coastguard Worker apexVariantsWithoutTestApexes = append(apexVariantsWithoutTestApexes, variants...) 221*333d2b36SAndroid Build Coastguard Worker } 222*333d2b36SAndroid Build Coastguard Worker if apexInfo.ApexAvailableName != "" { 223*333d2b36SAndroid Build Coastguard Worker apexVariantsWithoutTestApexes = append(apexVariantsWithoutTestApexes, apexInfo.ApexAvailableName) 224*333d2b36SAndroid Build Coastguard Worker } 225*333d2b36SAndroid Build Coastguard Worker disableSource := false 226*333d2b36SAndroid Build Coastguard Worker // find the selected apexes 227*333d2b36SAndroid Build Coastguard Worker for _, apexVariant := range apexVariantsWithoutTestApexes { 228*333d2b36SAndroid Build Coastguard Worker if len(psi.GetSelectedModulesForApiDomain(apexVariant)) > 0 { 229*333d2b36SAndroid Build Coastguard Worker // If the apex_contribution for this api domain is non-empty, disable the source variant 230*333d2b36SAndroid Build Coastguard Worker disableSource = true 231*333d2b36SAndroid Build Coastguard Worker } 232*333d2b36SAndroid Build Coastguard Worker } 233*333d2b36SAndroid Build Coastguard Worker return disableSource 234*333d2b36SAndroid Build Coastguard Worker} 235*333d2b36SAndroid Build Coastguard Worker 236*333d2b36SAndroid Build Coastguard Worker// Returns whether dexpreopt is applicable to the module. 237*333d2b36SAndroid Build Coastguard Worker// When it returns true, neither profile nor dexpreopt artifacts will be generated. 238*333d2b36SAndroid Build Coastguard Workerfunc (d *dexpreopter) dexpreoptDisabled(ctx android.BaseModuleContext, libName string) bool { 239*333d2b36SAndroid Build Coastguard Worker if !ctx.Device() { 240*333d2b36SAndroid Build Coastguard Worker return true 241*333d2b36SAndroid Build Coastguard Worker } 242*333d2b36SAndroid Build Coastguard Worker 243*333d2b36SAndroid Build Coastguard Worker if d.isTest { 244*333d2b36SAndroid Build Coastguard Worker return true 245*333d2b36SAndroid Build Coastguard Worker } 246*333d2b36SAndroid Build Coastguard Worker 247*333d2b36SAndroid Build Coastguard Worker if !d.dexpreoptProperties.Dex_preopt.Enabled.GetOrDefault(ctx, true) { 248*333d2b36SAndroid Build Coastguard Worker return true 249*333d2b36SAndroid Build Coastguard Worker } 250*333d2b36SAndroid Build Coastguard Worker 251*333d2b36SAndroid Build Coastguard Worker if d.shouldDisableDexpreopt { 252*333d2b36SAndroid Build Coastguard Worker return true 253*333d2b36SAndroid Build Coastguard Worker } 254*333d2b36SAndroid Build Coastguard Worker 255*333d2b36SAndroid Build Coastguard Worker // If the module is from a prebuilt APEX, it shouldn't be installable, but it can still be 256*333d2b36SAndroid Build Coastguard Worker // dexpreopted. 257*333d2b36SAndroid Build Coastguard Worker if !ctx.Module().(DexpreopterInterface).IsInstallable() && !forPrebuiltApex(ctx) { 258*333d2b36SAndroid Build Coastguard Worker return true 259*333d2b36SAndroid Build Coastguard Worker } 260*333d2b36SAndroid Build Coastguard Worker 261*333d2b36SAndroid Build Coastguard Worker if !android.IsModulePreferred(ctx.Module()) { 262*333d2b36SAndroid Build Coastguard Worker return true 263*333d2b36SAndroid Build Coastguard Worker } 264*333d2b36SAndroid Build Coastguard Worker 265*333d2b36SAndroid Build Coastguard Worker if _, isApex := android.ModuleProvider(ctx, android.ApexBundleInfoProvider); isApex { 266*333d2b36SAndroid Build Coastguard Worker // dexpreopt rules for system server jars can be generated in the ModuleCtx of prebuilt apexes 267*333d2b36SAndroid Build Coastguard Worker return false 268*333d2b36SAndroid Build Coastguard Worker } 269*333d2b36SAndroid Build Coastguard Worker 270*333d2b36SAndroid Build Coastguard Worker global := dexpreopt.GetGlobalConfig(ctx) 271*333d2b36SAndroid Build Coastguard Worker 272*333d2b36SAndroid Build Coastguard Worker // Use the libName argument to determine if the library being dexpreopt'd is a system server jar 273*333d2b36SAndroid Build Coastguard Worker // ctx.ModuleName() is not safe. In case of prebuilt apexes, the dexpreopt rules of system server jars 274*333d2b36SAndroid Build Coastguard Worker // are created in the ctx object of the top-level prebuilt apex. 275*333d2b36SAndroid Build Coastguard Worker isApexSystemServerJar := global.AllApexSystemServerJars(ctx).ContainsJar(libName) 276*333d2b36SAndroid Build Coastguard Worker 277*333d2b36SAndroid Build Coastguard Worker if _, isApex := android.ModuleProvider(ctx, android.ApexBundleInfoProvider); isApex || isApexVariant(ctx) { 278*333d2b36SAndroid Build Coastguard Worker // dexpreopt rules for system server jars can be generated in the ModuleCtx of prebuilt apexes 279*333d2b36SAndroid Build Coastguard Worker if !isApexSystemServerJar { 280*333d2b36SAndroid Build Coastguard Worker return true 281*333d2b36SAndroid Build Coastguard Worker } 282*333d2b36SAndroid Build Coastguard Worker ai, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) 283*333d2b36SAndroid Build Coastguard Worker allApexInfos := []android.ApexInfo{} 284*333d2b36SAndroid Build Coastguard Worker if allApexInfosProvider, ok := android.ModuleProvider(ctx, android.AllApexInfoProvider); ok { 285*333d2b36SAndroid Build Coastguard Worker allApexInfos = allApexInfosProvider.ApexInfos 286*333d2b36SAndroid Build Coastguard Worker } 287*333d2b36SAndroid Build Coastguard Worker if len(allApexInfos) > 0 && !ai.MinSdkVersion.EqualTo(allApexInfos[0].MinSdkVersion) { 288*333d2b36SAndroid Build Coastguard Worker // Apex system server jars are dexpreopted and installed on to the system image. 289*333d2b36SAndroid Build Coastguard Worker // Since we can have BigAndroid and Go variants of system server jar providing apexes, 290*333d2b36SAndroid Build Coastguard Worker // and these two variants can have different min_sdk_versions, hide one of the apex variants 291*333d2b36SAndroid Build Coastguard Worker // from make to prevent collisions. 292*333d2b36SAndroid Build Coastguard Worker // 293*333d2b36SAndroid Build Coastguard Worker // Unlike cc, min_sdk_version does not have an effect on the build actions of java libraries. 294*333d2b36SAndroid Build Coastguard Worker ctx.Module().MakeUninstallable() 295*333d2b36SAndroid Build Coastguard Worker } 296*333d2b36SAndroid Build Coastguard Worker } else { 297*333d2b36SAndroid Build Coastguard Worker // Don't preopt the platform variant of an APEX system server jar to avoid conflicts. 298*333d2b36SAndroid Build Coastguard Worker if isApexSystemServerJar { 299*333d2b36SAndroid Build Coastguard Worker return true 300*333d2b36SAndroid Build Coastguard Worker } 301*333d2b36SAndroid Build Coastguard Worker } 302*333d2b36SAndroid Build Coastguard Worker 303*333d2b36SAndroid Build Coastguard Worker // TODO: contains no java code 304*333d2b36SAndroid Build Coastguard Worker 305*333d2b36SAndroid Build Coastguard Worker return false 306*333d2b36SAndroid Build Coastguard Worker} 307*333d2b36SAndroid Build Coastguard Worker 308*333d2b36SAndroid Build Coastguard Workerfunc dexpreoptToolDepsMutator(ctx android.BottomUpMutatorContext) { 309*333d2b36SAndroid Build Coastguard Worker if _, isApex := android.ModuleProvider(ctx, android.ApexBundleInfoProvider); isApex && dexpreopt.IsDex2oatNeeded(ctx) { 310*333d2b36SAndroid Build Coastguard Worker // prebuilt apexes can genererate rules to dexpreopt deapexed jars 311*333d2b36SAndroid Build Coastguard Worker // Add a dex2oat dep aggressively on _every_ apex module 312*333d2b36SAndroid Build Coastguard Worker dexpreopt.RegisterToolDeps(ctx) 313*333d2b36SAndroid Build Coastguard Worker return 314*333d2b36SAndroid Build Coastguard Worker } 315*333d2b36SAndroid Build Coastguard Worker if d, ok := ctx.Module().(DexpreopterInterface); !ok || d.dexpreoptDisabled(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName())) || !dexpreopt.IsDex2oatNeeded(ctx) { 316*333d2b36SAndroid Build Coastguard Worker return 317*333d2b36SAndroid Build Coastguard Worker } 318*333d2b36SAndroid Build Coastguard Worker dexpreopt.RegisterToolDeps(ctx) 319*333d2b36SAndroid Build Coastguard Worker} 320*333d2b36SAndroid Build Coastguard Worker 321*333d2b36SAndroid Build Coastguard Worker// Returns the install path of the dex jar of a module. 322*333d2b36SAndroid Build Coastguard Worker// 323*333d2b36SAndroid Build Coastguard Worker// Do not rely on `ApexInfo.ApexVariationName` because it can be something like "apex1000", rather 324*333d2b36SAndroid Build Coastguard Worker// than the `name` in the path `/apex/<name>` as suggested in its comment. 325*333d2b36SAndroid Build Coastguard Worker// 326*333d2b36SAndroid Build Coastguard Worker// This function is on a best-effort basis. It cannot handle the case where an APEX jar is not a 327*333d2b36SAndroid Build Coastguard Worker// system server jar, which is fine because we currently only preopt system server jars for APEXes. 328*333d2b36SAndroid Build Coastguard Workerfunc (d *dexpreopter) getInstallPath( 329*333d2b36SAndroid Build Coastguard Worker ctx android.ModuleContext, libName string, defaultInstallPath android.InstallPath) android.InstallPath { 330*333d2b36SAndroid Build Coastguard Worker global := dexpreopt.GetGlobalConfig(ctx) 331*333d2b36SAndroid Build Coastguard Worker if global.AllApexSystemServerJars(ctx).ContainsJar(libName) { 332*333d2b36SAndroid Build Coastguard Worker dexLocation := dexpreopt.GetSystemServerDexLocation(ctx, global, libName) 333*333d2b36SAndroid Build Coastguard Worker return android.PathForModuleInPartitionInstall(ctx, "", strings.TrimPrefix(dexLocation, "/")) 334*333d2b36SAndroid Build Coastguard Worker } 335*333d2b36SAndroid Build Coastguard Worker if !d.dexpreoptDisabled(ctx, libName) && isApexVariant(ctx) && 336*333d2b36SAndroid Build Coastguard Worker filepath.Base(defaultInstallPath.PartitionDir()) != "apex" { 337*333d2b36SAndroid Build Coastguard Worker ctx.ModuleErrorf("unable to get the install path of the dex jar for dexpreopt") 338*333d2b36SAndroid Build Coastguard Worker } 339*333d2b36SAndroid Build Coastguard Worker return defaultInstallPath 340*333d2b36SAndroid Build Coastguard Worker} 341*333d2b36SAndroid Build Coastguard Worker 342*333d2b36SAndroid Build Coastguard Worker// DexpreoptPrebuiltApexSystemServerJars generates the dexpreopt artifacts from a jar file that has been deapexed from a prebuilt apex 343*333d2b36SAndroid Build Coastguard Workerfunc (d *Dexpreopter) DexpreoptPrebuiltApexSystemServerJars(ctx android.ModuleContext, libraryName string, di *android.DeapexerInfo) { 344*333d2b36SAndroid Build Coastguard Worker // A single prebuilt apex can have multiple apex system jars 345*333d2b36SAndroid Build Coastguard Worker // initialize the output path for this dex jar 346*333d2b36SAndroid Build Coastguard Worker dc := dexpreopt.GetGlobalConfig(ctx) 347*333d2b36SAndroid Build Coastguard Worker d.installPath = android.PathForModuleInPartitionInstall(ctx, "", strings.TrimPrefix(dexpreopt.GetSystemServerDexLocation(ctx, dc, libraryName), "/")) 348*333d2b36SAndroid Build Coastguard Worker // generate the rules for creating the .odex and .vdex files for this system server jar 349*333d2b36SAndroid Build Coastguard Worker dexJarFile := di.PrebuiltExportPath(ApexRootRelativePathToJavaLib(libraryName)) 350*333d2b36SAndroid Build Coastguard Worker 351*333d2b36SAndroid Build Coastguard Worker d.inputProfilePathOnHost = nil // reset: TODO(spandandas): Make dexpreopter stateless 352*333d2b36SAndroid Build Coastguard Worker if android.InList(libraryName, di.GetDexpreoptProfileGuidedExportedModuleNames()) { 353*333d2b36SAndroid Build Coastguard Worker // Set the profile path to guide optimization 354*333d2b36SAndroid Build Coastguard Worker prof := di.PrebuiltExportPath(ApexRootRelativePathToJavaLib(libraryName) + ".prof") 355*333d2b36SAndroid Build Coastguard Worker if prof == nil { 356*333d2b36SAndroid Build Coastguard Worker ctx.ModuleErrorf("Could not find a .prof file in this prebuilt apex") 357*333d2b36SAndroid Build Coastguard Worker } 358*333d2b36SAndroid Build Coastguard Worker d.inputProfilePathOnHost = prof 359*333d2b36SAndroid Build Coastguard Worker } 360*333d2b36SAndroid Build Coastguard Worker 361*333d2b36SAndroid Build Coastguard Worker d.dexpreopt(ctx, libraryName, dexJarFile) 362*333d2b36SAndroid Build Coastguard Worker} 363*333d2b36SAndroid Build Coastguard Worker 364*333d2b36SAndroid Build Coastguard Workerfunc (d *dexpreopter) dexpreopt(ctx android.ModuleContext, libName string, dexJarFile android.Path) { 365*333d2b36SAndroid Build Coastguard Worker global := dexpreopt.GetGlobalConfig(ctx) 366*333d2b36SAndroid Build Coastguard Worker 367*333d2b36SAndroid Build Coastguard Worker // TODO(b/148690468): The check on d.installPath is to bail out in cases where 368*333d2b36SAndroid Build Coastguard Worker // the dexpreopter struct hasn't been fully initialized before we're called, 369*333d2b36SAndroid Build Coastguard Worker // e.g. in aar.go. This keeps the behaviour that dexpreopting is effectively 370*333d2b36SAndroid Build Coastguard Worker // disabled, even if installable is true. 371*333d2b36SAndroid Build Coastguard Worker if d.installPath.Base() == "." { 372*333d2b36SAndroid Build Coastguard Worker return 373*333d2b36SAndroid Build Coastguard Worker } 374*333d2b36SAndroid Build Coastguard Worker 375*333d2b36SAndroid Build Coastguard Worker dexLocation := android.InstallPathToOnDevicePath(ctx, d.installPath) 376*333d2b36SAndroid Build Coastguard Worker 377*333d2b36SAndroid Build Coastguard Worker providesUsesLib := libName 378*333d2b36SAndroid Build Coastguard Worker if ulib, ok := ctx.Module().(ProvidesUsesLib); ok { 379*333d2b36SAndroid Build Coastguard Worker name := ulib.ProvidesUsesLib() 380*333d2b36SAndroid Build Coastguard Worker if name != nil { 381*333d2b36SAndroid Build Coastguard Worker providesUsesLib = *name 382*333d2b36SAndroid Build Coastguard Worker } 383*333d2b36SAndroid Build Coastguard Worker } 384*333d2b36SAndroid Build Coastguard Worker 385*333d2b36SAndroid Build Coastguard Worker // If it is test, make config files regardless of its dexpreopt setting. 386*333d2b36SAndroid Build Coastguard Worker // The config files are required for apps defined in make which depend on the lib. 387*333d2b36SAndroid Build Coastguard Worker if d.isTest && d.dexpreoptDisabled(ctx, libName) { 388*333d2b36SAndroid Build Coastguard Worker return 389*333d2b36SAndroid Build Coastguard Worker } 390*333d2b36SAndroid Build Coastguard Worker 391*333d2b36SAndroid Build Coastguard Worker isSystemServerJar := global.AllSystemServerJars(ctx).ContainsJar(libName) 392*333d2b36SAndroid Build Coastguard Worker 393*333d2b36SAndroid Build Coastguard Worker bootImage := defaultBootImageConfig(ctx) 394*333d2b36SAndroid Build Coastguard Worker // When `global.PreoptWithUpdatableBcp` is true, `bcpForDexpreopt` below includes the mainline 395*333d2b36SAndroid Build Coastguard Worker // boot jars into bootclasspath, so we should include the mainline boot image as well because it's 396*333d2b36SAndroid Build Coastguard Worker // generated from those jars. 397*333d2b36SAndroid Build Coastguard Worker if global.PreoptWithUpdatableBcp { 398*333d2b36SAndroid Build Coastguard Worker bootImage = mainlineBootImageConfig(ctx) 399*333d2b36SAndroid Build Coastguard Worker } 400*333d2b36SAndroid Build Coastguard Worker dexFiles, dexLocations := bcpForDexpreopt(ctx, global.PreoptWithUpdatableBcp) 401*333d2b36SAndroid Build Coastguard Worker 402*333d2b36SAndroid Build Coastguard Worker targets := ctx.MultiTargets() 403*333d2b36SAndroid Build Coastguard Worker if len(targets) == 0 { 404*333d2b36SAndroid Build Coastguard Worker // assume this is a java library, dexpreopt for all arches for now 405*333d2b36SAndroid Build Coastguard Worker for _, target := range ctx.Config().Targets[android.Android] { 406*333d2b36SAndroid Build Coastguard Worker if target.NativeBridge == android.NativeBridgeDisabled { 407*333d2b36SAndroid Build Coastguard Worker targets = append(targets, target) 408*333d2b36SAndroid Build Coastguard Worker } 409*333d2b36SAndroid Build Coastguard Worker } 410*333d2b36SAndroid Build Coastguard Worker if isSystemServerJar && libName != "com.android.location.provider" { 411*333d2b36SAndroid Build Coastguard Worker // If the module is a system server jar, only preopt for the primary arch because the jar can 412*333d2b36SAndroid Build Coastguard Worker // only be loaded by system server. "com.android.location.provider" is a special case because 413*333d2b36SAndroid Build Coastguard Worker // it's also used by apps as a shared library. 414*333d2b36SAndroid Build Coastguard Worker targets = targets[:1] 415*333d2b36SAndroid Build Coastguard Worker } 416*333d2b36SAndroid Build Coastguard Worker } 417*333d2b36SAndroid Build Coastguard Worker 418*333d2b36SAndroid Build Coastguard Worker var archs []android.ArchType 419*333d2b36SAndroid Build Coastguard Worker var images android.Paths 420*333d2b36SAndroid Build Coastguard Worker var imagesDeps []android.OutputPaths 421*333d2b36SAndroid Build Coastguard Worker for _, target := range targets { 422*333d2b36SAndroid Build Coastguard Worker archs = append(archs, target.Arch.ArchType) 423*333d2b36SAndroid Build Coastguard Worker variant := bootImage.getVariant(target) 424*333d2b36SAndroid Build Coastguard Worker images = append(images, variant.imagePathOnHost) 425*333d2b36SAndroid Build Coastguard Worker imagesDeps = append(imagesDeps, variant.imagesDeps) 426*333d2b36SAndroid Build Coastguard Worker } 427*333d2b36SAndroid Build Coastguard Worker // The image locations for all Android variants are identical. 428*333d2b36SAndroid Build Coastguard Worker hostImageLocations, deviceImageLocations := bootImage.getAnyAndroidVariant().imageLocations() 429*333d2b36SAndroid Build Coastguard Worker 430*333d2b36SAndroid Build Coastguard Worker var profileClassListing android.OptionalPath 431*333d2b36SAndroid Build Coastguard Worker var profileBootListing android.OptionalPath 432*333d2b36SAndroid Build Coastguard Worker profileIsTextListing := false 433*333d2b36SAndroid Build Coastguard Worker 434*333d2b36SAndroid Build Coastguard Worker if d.inputProfilePathOnHost != nil { 435*333d2b36SAndroid Build Coastguard Worker profileClassListing = android.OptionalPathForPath(d.inputProfilePathOnHost) 436*333d2b36SAndroid Build Coastguard Worker } else if d.dexpreoptProperties.Dex_preopt.Profile_guided.GetOrDefault(ctx, true) && !forPrebuiltApex(ctx) { 437*333d2b36SAndroid Build Coastguard Worker // If enable_profile_rewriting is set, use the rewritten profile instead of the checked-in profile 438*333d2b36SAndroid Build Coastguard Worker if d.EnableProfileRewriting(ctx) { 439*333d2b36SAndroid Build Coastguard Worker profileClassListing = android.OptionalPathForPath(d.GetRewrittenProfile()) 440*333d2b36SAndroid Build Coastguard Worker profileIsTextListing = true 441*333d2b36SAndroid Build Coastguard Worker } else if profile := d.GetProfile(ctx); profile != "" { 442*333d2b36SAndroid Build Coastguard Worker // If dex_preopt.profile_guided is not set, default it based on the existence of the 443*333d2b36SAndroid Build Coastguard Worker // dexprepot.profile option or the profile class listing. 444*333d2b36SAndroid Build Coastguard Worker profileClassListing = android.OptionalPathForPath( 445*333d2b36SAndroid Build Coastguard Worker android.PathForModuleSrc(ctx, profile)) 446*333d2b36SAndroid Build Coastguard Worker profileBootListing = android.ExistentPathForSource(ctx, 447*333d2b36SAndroid Build Coastguard Worker ctx.ModuleDir(), profile+"-boot") 448*333d2b36SAndroid Build Coastguard Worker profileIsTextListing = true 449*333d2b36SAndroid Build Coastguard Worker } else if global.ProfileDir != "" { 450*333d2b36SAndroid Build Coastguard Worker profileClassListing = android.ExistentPathForSource(ctx, 451*333d2b36SAndroid Build Coastguard Worker global.ProfileDir, libName+".prof") 452*333d2b36SAndroid Build Coastguard Worker } 453*333d2b36SAndroid Build Coastguard Worker } 454*333d2b36SAndroid Build Coastguard Worker 455*333d2b36SAndroid Build Coastguard Worker d.dexpreoptProperties.Dex_preopt_result.Profile_guided = profileClassListing.Valid() 456*333d2b36SAndroid Build Coastguard Worker 457*333d2b36SAndroid Build Coastguard Worker // A single apex can have multiple system server jars 458*333d2b36SAndroid Build Coastguard Worker // Use the dexJar to create a unique scope for each 459*333d2b36SAndroid Build Coastguard Worker dexJarStem := strings.TrimSuffix(dexJarFile.Base(), dexJarFile.Ext()) 460*333d2b36SAndroid Build Coastguard Worker 461*333d2b36SAndroid Build Coastguard Worker appImage := d.dexpreoptProperties.Dex_preopt.App_image.Get(ctx) 462*333d2b36SAndroid Build Coastguard Worker 463*333d2b36SAndroid Build Coastguard Worker // Full dexpreopt config, used to create dexpreopt build rules. 464*333d2b36SAndroid Build Coastguard Worker dexpreoptConfig := &dexpreopt.ModuleConfig{ 465*333d2b36SAndroid Build Coastguard Worker Name: libName, 466*333d2b36SAndroid Build Coastguard Worker DexLocation: dexLocation, 467*333d2b36SAndroid Build Coastguard Worker BuildPath: android.PathForModuleOut(ctx, "dexpreopt", dexJarStem, libName+".jar").OutputPath, 468*333d2b36SAndroid Build Coastguard Worker DexPath: dexJarFile, 469*333d2b36SAndroid Build Coastguard Worker ManifestPath: android.OptionalPathForPath(d.manifestFile), 470*333d2b36SAndroid Build Coastguard Worker UncompressedDex: d.uncompressedDex, 471*333d2b36SAndroid Build Coastguard Worker HasApkLibraries: false, 472*333d2b36SAndroid Build Coastguard Worker PreoptFlags: nil, 473*333d2b36SAndroid Build Coastguard Worker 474*333d2b36SAndroid Build Coastguard Worker ProfileClassListing: profileClassListing, 475*333d2b36SAndroid Build Coastguard Worker ProfileIsTextListing: profileIsTextListing, 476*333d2b36SAndroid Build Coastguard Worker ProfileBootListing: profileBootListing, 477*333d2b36SAndroid Build Coastguard Worker 478*333d2b36SAndroid Build Coastguard Worker EnforceUsesLibrariesStatusFile: dexpreopt.UsesLibrariesStatusFile(ctx), 479*333d2b36SAndroid Build Coastguard Worker EnforceUsesLibraries: d.enforceUsesLibs, 480*333d2b36SAndroid Build Coastguard Worker ProvidesUsesLibrary: providesUsesLib, 481*333d2b36SAndroid Build Coastguard Worker ClassLoaderContexts: d.classLoaderContexts, 482*333d2b36SAndroid Build Coastguard Worker 483*333d2b36SAndroid Build Coastguard Worker Archs: archs, 484*333d2b36SAndroid Build Coastguard Worker DexPreoptImagesDeps: imagesDeps, 485*333d2b36SAndroid Build Coastguard Worker DexPreoptImageLocationsOnHost: hostImageLocations, 486*333d2b36SAndroid Build Coastguard Worker DexPreoptImageLocationsOnDevice: deviceImageLocations, 487*333d2b36SAndroid Build Coastguard Worker 488*333d2b36SAndroid Build Coastguard Worker PreoptBootClassPathDexFiles: dexFiles.Paths(), 489*333d2b36SAndroid Build Coastguard Worker PreoptBootClassPathDexLocations: dexLocations, 490*333d2b36SAndroid Build Coastguard Worker 491*333d2b36SAndroid Build Coastguard Worker NoCreateAppImage: !appImage.GetOrDefault(true), 492*333d2b36SAndroid Build Coastguard Worker ForceCreateAppImage: appImage.GetOrDefault(false), 493*333d2b36SAndroid Build Coastguard Worker 494*333d2b36SAndroid Build Coastguard Worker PresignedPrebuilt: d.isPresignedPrebuilt, 495*333d2b36SAndroid Build Coastguard Worker } 496*333d2b36SAndroid Build Coastguard Worker 497*333d2b36SAndroid Build Coastguard Worker if ctx.Config().InstallApexSystemServerDexpreoptSamePartition() { 498*333d2b36SAndroid Build Coastguard Worker dexpreoptConfig.ApexPartition = android.PathForModuleInstall(ctx).Partition() 499*333d2b36SAndroid Build Coastguard Worker } else { 500*333d2b36SAndroid Build Coastguard Worker dexpreoptConfig.ApexPartition = "system" 501*333d2b36SAndroid Build Coastguard Worker } 502*333d2b36SAndroid Build Coastguard Worker 503*333d2b36SAndroid Build Coastguard Worker d.configPath = android.PathForModuleOut(ctx, "dexpreopt", dexJarStem, "dexpreopt.config") 504*333d2b36SAndroid Build Coastguard Worker dexpreopt.WriteModuleConfig(ctx, dexpreoptConfig, d.configPath) 505*333d2b36SAndroid Build Coastguard Worker ctx.CheckbuildFile(d.configPath) 506*333d2b36SAndroid Build Coastguard Worker 507*333d2b36SAndroid Build Coastguard Worker if d.dexpreoptDisabled(ctx, libName) { 508*333d2b36SAndroid Build Coastguard Worker return 509*333d2b36SAndroid Build Coastguard Worker } 510*333d2b36SAndroid Build Coastguard Worker 511*333d2b36SAndroid Build Coastguard Worker globalSoong := dexpreopt.GetGlobalSoongConfig(ctx) 512*333d2b36SAndroid Build Coastguard Worker 513*333d2b36SAndroid Build Coastguard Worker // The root "product_packages.txt" is generated by `build/make/core/Makefile`. It contains a list 514*333d2b36SAndroid Build Coastguard Worker // of all packages that are installed on the device. We use `grep` to filter the list by the app's 515*333d2b36SAndroid Build Coastguard Worker // dependencies to create a per-app list, and use `rsync --checksum` to prevent the file's mtime 516*333d2b36SAndroid Build Coastguard Worker // from being changed if the contents don't change. This avoids unnecessary dexpreopt reruns. 517*333d2b36SAndroid Build Coastguard Worker productPackages := android.PathForModuleInPartitionInstall(ctx, "", "product_packages.txt") 518*333d2b36SAndroid Build Coastguard Worker appProductPackages := android.PathForModuleOut(ctx, "dexpreopt", dexJarStem, "product_packages.txt") 519*333d2b36SAndroid Build Coastguard Worker appProductPackagesStaging := appProductPackages.ReplaceExtension(ctx, "txt.tmp") 520*333d2b36SAndroid Build Coastguard Worker clcNames, _ := dexpreopt.ComputeClassLoaderContextDependencies(dexpreoptConfig.ClassLoaderContexts) 521*333d2b36SAndroid Build Coastguard Worker sort.Strings(clcNames) // The order needs to be deterministic. 522*333d2b36SAndroid Build Coastguard Worker productPackagesRule := android.NewRuleBuilder(pctx, ctx) 523*333d2b36SAndroid Build Coastguard Worker if len(clcNames) > 0 { 524*333d2b36SAndroid Build Coastguard Worker productPackagesRule.Command(). 525*333d2b36SAndroid Build Coastguard Worker Text("grep -F -x"). 526*333d2b36SAndroid Build Coastguard Worker FlagForEachArg("-e ", clcNames). 527*333d2b36SAndroid Build Coastguard Worker Input(productPackages). 528*333d2b36SAndroid Build Coastguard Worker FlagWithOutput("> ", appProductPackagesStaging). 529*333d2b36SAndroid Build Coastguard Worker Text("|| true") 530*333d2b36SAndroid Build Coastguard Worker } else { 531*333d2b36SAndroid Build Coastguard Worker productPackagesRule.Command(). 532*333d2b36SAndroid Build Coastguard Worker Text("rm -f").Output(appProductPackagesStaging). 533*333d2b36SAndroid Build Coastguard Worker Text("&&"). 534*333d2b36SAndroid Build Coastguard Worker Text("touch").Output(appProductPackagesStaging) 535*333d2b36SAndroid Build Coastguard Worker } 536*333d2b36SAndroid Build Coastguard Worker productPackagesRule.Command(). 537*333d2b36SAndroid Build Coastguard Worker Text("rsync --checksum"). 538*333d2b36SAndroid Build Coastguard Worker Input(appProductPackagesStaging). 539*333d2b36SAndroid Build Coastguard Worker Output(appProductPackages) 540*333d2b36SAndroid Build Coastguard Worker productPackagesRule.Restat().Build("product_packages."+dexJarStem, "dexpreopt product_packages") 541*333d2b36SAndroid Build Coastguard Worker 542*333d2b36SAndroid Build Coastguard Worker // Prebuilts are active, do not copy the dexpreopt'd source javalib to out/soong/system_server_dexjars 543*333d2b36SAndroid Build Coastguard Worker // The javalib from the deapexed prebuilt will be copied to this location. 544*333d2b36SAndroid Build Coastguard Worker // TODO (b/331665856): Implement a principled solution for this. 545*333d2b36SAndroid Build Coastguard Worker copyApexSystemServerJarDex := !disableSourceApexVariant(ctx) && !ctx.Module().IsHideFromMake() 546*333d2b36SAndroid Build Coastguard Worker dexpreoptRule, err := dexpreopt.GenerateDexpreoptRule( 547*333d2b36SAndroid Build Coastguard Worker ctx, globalSoong, global, dexpreoptConfig, appProductPackages, copyApexSystemServerJarDex) 548*333d2b36SAndroid Build Coastguard Worker if err != nil { 549*333d2b36SAndroid Build Coastguard Worker ctx.ModuleErrorf("error generating dexpreopt rule: %s", err.Error()) 550*333d2b36SAndroid Build Coastguard Worker return 551*333d2b36SAndroid Build Coastguard Worker } 552*333d2b36SAndroid Build Coastguard Worker 553*333d2b36SAndroid Build Coastguard Worker dexpreoptRule.Build("dexpreopt"+"."+dexJarStem, "dexpreopt") 554*333d2b36SAndroid Build Coastguard Worker 555*333d2b36SAndroid Build Coastguard Worker // The current ctx might be of a deapexer module created by a prebuilt apex 556*333d2b36SAndroid Build Coastguard Worker // Use the path of the dex file to determine the library name 557*333d2b36SAndroid Build Coastguard Worker isApexSystemServerJar := global.AllApexSystemServerJars(ctx).ContainsJar(dexJarStem) 558*333d2b36SAndroid Build Coastguard Worker 559*333d2b36SAndroid Build Coastguard Worker dexpreoptPartition := d.installPath.Partition() 560*333d2b36SAndroid Build Coastguard Worker // dexpreoptPartition is set to empty for dexpreopts of system APEX and system_other. 561*333d2b36SAndroid Build Coastguard Worker // In case of system APEX, however, we can set it to "system" manually. 562*333d2b36SAndroid Build Coastguard Worker // TODO(b/346662300): Let dexpreopter generate the installPath for dexpreopt files instead of 563*333d2b36SAndroid Build Coastguard Worker // using the dex location to generate the installPath. 564*333d2b36SAndroid Build Coastguard Worker if isApexSystemServerJar { 565*333d2b36SAndroid Build Coastguard Worker dexpreoptPartition = dexpreoptConfig.ApexPartition 566*333d2b36SAndroid Build Coastguard Worker } 567*333d2b36SAndroid Build Coastguard Worker for _, install := range dexpreoptRule.Installs() { 568*333d2b36SAndroid Build Coastguard Worker // Remove the "/" prefix because the path should be relative to $ANDROID_PRODUCT_OUT. 569*333d2b36SAndroid Build Coastguard Worker installDir := strings.TrimPrefix(filepath.Dir(install.To), "/") 570*333d2b36SAndroid Build Coastguard Worker partition := dexpreoptPartition 571*333d2b36SAndroid Build Coastguard Worker if strings.HasPrefix(installDir, partition+"/") { 572*333d2b36SAndroid Build Coastguard Worker installDir = strings.TrimPrefix(installDir, partition+"/") 573*333d2b36SAndroid Build Coastguard Worker } else { 574*333d2b36SAndroid Build Coastguard Worker // If the partition for the installDir is different from the install partition, set the 575*333d2b36SAndroid Build Coastguard Worker // partition empty to install the dexpreopt files to the desired partition. 576*333d2b36SAndroid Build Coastguard Worker // TODO(b/346439786): Define and use the dexpreopt module type to avoid this mismatch. 577*333d2b36SAndroid Build Coastguard Worker partition = "" 578*333d2b36SAndroid Build Coastguard Worker } 579*333d2b36SAndroid Build Coastguard Worker installBase := filepath.Base(install.To) 580*333d2b36SAndroid Build Coastguard Worker arch := filepath.Base(installDir) 581*333d2b36SAndroid Build Coastguard Worker installPath := android.PathForModuleInPartitionInstall(ctx, partition, installDir) 582*333d2b36SAndroid Build Coastguard Worker isProfile := strings.HasSuffix(installBase, ".prof") 583*333d2b36SAndroid Build Coastguard Worker 584*333d2b36SAndroid Build Coastguard Worker if isProfile { 585*333d2b36SAndroid Build Coastguard Worker d.outputProfilePathOnHost = install.From 586*333d2b36SAndroid Build Coastguard Worker } 587*333d2b36SAndroid Build Coastguard Worker 588*333d2b36SAndroid Build Coastguard Worker if isApexSystemServerJar { 589*333d2b36SAndroid Build Coastguard Worker // Profiles are handled separately because they are installed into the APEX. 590*333d2b36SAndroid Build Coastguard Worker if !isProfile { 591*333d2b36SAndroid Build Coastguard Worker // APEX variants of java libraries are hidden from Make, so their dexpreopt 592*333d2b36SAndroid Build Coastguard Worker // outputs need special handling. Currently, for APEX variants of java 593*333d2b36SAndroid Build Coastguard Worker // libraries, only those in the system server classpath are handled here. 594*333d2b36SAndroid Build Coastguard Worker // Preopting of boot classpath jars in the ART APEX are handled in 595*333d2b36SAndroid Build Coastguard Worker // java/dexpreopt_bootjars.go, and other APEX jars are not preopted. 596*333d2b36SAndroid Build Coastguard Worker // The installs will be handled by Make as sub-modules of the java library. 597*333d2b36SAndroid Build Coastguard Worker di := dexpreopterInstall{ 598*333d2b36SAndroid Build Coastguard Worker name: arch + "-" + installBase, 599*333d2b36SAndroid Build Coastguard Worker moduleName: libName, 600*333d2b36SAndroid Build Coastguard Worker outputPathOnHost: install.From, 601*333d2b36SAndroid Build Coastguard Worker installDirOnDevice: installPath, 602*333d2b36SAndroid Build Coastguard Worker installFileOnDevice: installBase, 603*333d2b36SAndroid Build Coastguard Worker } 604*333d2b36SAndroid Build Coastguard Worker ctx.InstallFile(di.installDirOnDevice, di.installFileOnDevice, di.outputPathOnHost) 605*333d2b36SAndroid Build Coastguard Worker d.builtInstalledForApex = append(d.builtInstalledForApex, di) 606*333d2b36SAndroid Build Coastguard Worker 607*333d2b36SAndroid Build Coastguard Worker } 608*333d2b36SAndroid Build Coastguard Worker } else if !d.preventInstall { 609*333d2b36SAndroid Build Coastguard Worker // Install without adding to checkbuild to match behavior of previous Make-based checkbuild rules 610*333d2b36SAndroid Build Coastguard Worker ctx.InstallFileWithoutCheckbuild(installPath, installBase, install.From) 611*333d2b36SAndroid Build Coastguard Worker } 612*333d2b36SAndroid Build Coastguard Worker } 613*333d2b36SAndroid Build Coastguard Worker 614*333d2b36SAndroid Build Coastguard Worker if !isApexSystemServerJar { 615*333d2b36SAndroid Build Coastguard Worker d.builtInstalled = dexpreoptRule.Installs().String() 616*333d2b36SAndroid Build Coastguard Worker } 617*333d2b36SAndroid Build Coastguard Worker} 618*333d2b36SAndroid Build Coastguard Worker 619*333d2b36SAndroid Build Coastguard Workerfunc getModuleInstallPathInfo(ctx android.ModuleContext, fullInstallPath string) (android.InstallPath, string, string) { 620*333d2b36SAndroid Build Coastguard Worker installPath := android.PathForModuleInstall(ctx) 621*333d2b36SAndroid Build Coastguard Worker installDir, installBase := filepath.Split(strings.TrimPrefix(fullInstallPath, "/")) 622*333d2b36SAndroid Build Coastguard Worker 623*333d2b36SAndroid Build Coastguard Worker if !strings.HasPrefix(installDir, installPath.Partition()+"/") { 624*333d2b36SAndroid Build Coastguard Worker // Return empty filename if the install partition is not for the target image. 625*333d2b36SAndroid Build Coastguard Worker return installPath, "", "" 626*333d2b36SAndroid Build Coastguard Worker } 627*333d2b36SAndroid Build Coastguard Worker relDir, err := filepath.Rel(installPath.Partition(), installDir) 628*333d2b36SAndroid Build Coastguard Worker if err != nil { 629*333d2b36SAndroid Build Coastguard Worker panic(err) 630*333d2b36SAndroid Build Coastguard Worker } 631*333d2b36SAndroid Build Coastguard Worker return installPath, relDir, installBase 632*333d2b36SAndroid Build Coastguard Worker} 633*333d2b36SAndroid Build Coastguard Worker 634*333d2b36SAndroid Build Coastguard Worker// installFile will install the file if `install` path and the target install partition are the same. 635*333d2b36SAndroid Build Coastguard Workerfunc installFile(ctx android.ModuleContext, install android.RuleBuilderInstall) { 636*333d2b36SAndroid Build Coastguard Worker installPath, relDir, name := getModuleInstallPathInfo(ctx, install.To) 637*333d2b36SAndroid Build Coastguard Worker // Empty name means the install partition is not for the target image. 638*333d2b36SAndroid Build Coastguard Worker // For the system image, files for "apex" and "system_other" are skipped here. 639*333d2b36SAndroid Build Coastguard Worker // The skipped "apex" files are for testing only, for example, 640*333d2b36SAndroid Build Coastguard Worker // "/apex/art_boot_images/javalib/x86/boot.vdex". 641*333d2b36SAndroid Build Coastguard Worker // TODO(b/320196894): Files for "system_other" are skipped because soong creates the system 642*333d2b36SAndroid Build Coastguard Worker // image only for now. 643*333d2b36SAndroid Build Coastguard Worker if name != "" { 644*333d2b36SAndroid Build Coastguard Worker ctx.InstallFile(installPath.Join(ctx, relDir), name, install.From) 645*333d2b36SAndroid Build Coastguard Worker } 646*333d2b36SAndroid Build Coastguard Worker} 647*333d2b36SAndroid Build Coastguard Worker 648*333d2b36SAndroid Build Coastguard Workerfunc (d *dexpreopter) DexpreoptBuiltInstalledForApex() []dexpreopterInstall { 649*333d2b36SAndroid Build Coastguard Worker return d.builtInstalledForApex 650*333d2b36SAndroid Build Coastguard Worker} 651*333d2b36SAndroid Build Coastguard Worker 652*333d2b36SAndroid Build Coastguard Workerfunc (d *dexpreopter) AndroidMkEntriesForApex() []android.AndroidMkEntries { 653*333d2b36SAndroid Build Coastguard Worker var entries []android.AndroidMkEntries 654*333d2b36SAndroid Build Coastguard Worker for _, install := range d.builtInstalledForApex { 655*333d2b36SAndroid Build Coastguard Worker entries = append(entries, install.ToMakeEntries()) 656*333d2b36SAndroid Build Coastguard Worker } 657*333d2b36SAndroid Build Coastguard Worker return entries 658*333d2b36SAndroid Build Coastguard Worker} 659*333d2b36SAndroid Build Coastguard Worker 660*333d2b36SAndroid Build Coastguard Workerfunc (d *dexpreopter) OutputProfilePathOnHost() android.Path { 661*333d2b36SAndroid Build Coastguard Worker return d.outputProfilePathOnHost 662*333d2b36SAndroid Build Coastguard Worker} 663*333d2b36SAndroid Build Coastguard Worker 664*333d2b36SAndroid Build Coastguard Workerfunc (d *dexpreopter) disableDexpreopt() { 665*333d2b36SAndroid Build Coastguard Worker d.shouldDisableDexpreopt = true 666*333d2b36SAndroid Build Coastguard Worker} 667*333d2b36SAndroid Build Coastguard Worker 668*333d2b36SAndroid Build Coastguard Workerfunc (d *dexpreopter) EnableProfileRewriting(ctx android.BaseModuleContext) bool { 669*333d2b36SAndroid Build Coastguard Worker return d.dexpreoptProperties.Dex_preopt.Enable_profile_rewriting.GetOrDefault(ctx, false) 670*333d2b36SAndroid Build Coastguard Worker} 671*333d2b36SAndroid Build Coastguard Worker 672*333d2b36SAndroid Build Coastguard Workerfunc (d *dexpreopter) GetProfile(ctx android.BaseModuleContext) string { 673*333d2b36SAndroid Build Coastguard Worker return d.dexpreoptProperties.Dex_preopt.Profile.GetOrDefault(ctx, "") 674*333d2b36SAndroid Build Coastguard Worker} 675*333d2b36SAndroid Build Coastguard Worker 676*333d2b36SAndroid Build Coastguard Workerfunc (d *dexpreopter) GetProfileGuided(ctx android.BaseModuleContext) bool { 677*333d2b36SAndroid Build Coastguard Worker return d.dexpreoptProperties.Dex_preopt.Profile_guided.GetOrDefault(ctx, false) 678*333d2b36SAndroid Build Coastguard Worker} 679*333d2b36SAndroid Build Coastguard Worker 680*333d2b36SAndroid Build Coastguard Workerfunc (d *dexpreopter) GetRewrittenProfile() android.Path { 681*333d2b36SAndroid Build Coastguard Worker return d.rewrittenProfile 682*333d2b36SAndroid Build Coastguard Worker} 683*333d2b36SAndroid Build Coastguard Worker 684*333d2b36SAndroid Build Coastguard Workerfunc (d *dexpreopter) SetRewrittenProfile(p android.Path) { 685*333d2b36SAndroid Build Coastguard Worker d.rewrittenProfile = p 686*333d2b36SAndroid Build Coastguard Worker} 687