| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 1 | // Copyright 2018 Google Inc. All rights reserved. | 
|  | 2 | // | 
|  | 3 | // Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 4 | // you may not use this file except in compliance with the License. | 
|  | 5 | // You may obtain a copy of the License at | 
|  | 6 | // | 
|  | 7 | //     http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 8 | // | 
|  | 9 | // Unless required by applicable law or agreed to in writing, software | 
|  | 10 | // distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 12 | // See the License for the specific language governing permissions and | 
|  | 13 | // limitations under the License. | 
|  | 14 |  | 
|  | 15 | package java | 
|  | 16 |  | 
|  | 17 | import ( | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 18 | "android/soong/android" | 
|  | 19 | "android/soong/dexpreopt" | 
|  | 20 | ) | 
|  | 21 |  | 
|  | 22 | type dexpreopter struct { | 
|  | 23 | dexpreoptProperties DexpreoptProperties | 
|  | 24 |  | 
| Colin Cross | 2fc72f6 | 2018-12-21 12:59:54 -0800 | [diff] [blame] | 25 | installPath     android.OutputPath | 
|  | 26 | uncompressedDex bool | 
|  | 27 | isSDKLibrary    bool | 
|  | 28 | isTest          bool | 
|  | 29 | isInstallable   bool | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 30 |  | 
| Colin Cross | deabb94 | 2019-02-11 14:11:09 -0800 | [diff] [blame] | 31 | builtInstalled string | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 32 | } | 
|  | 33 |  | 
|  | 34 | type DexpreoptProperties struct { | 
|  | 35 | Dex_preopt struct { | 
|  | 36 | // If false, prevent dexpreopting and stripping the dex file from the final jar.  Defaults to | 
|  | 37 | // true. | 
|  | 38 | Enabled *bool | 
|  | 39 |  | 
| Colin Cross | 8c6d250 | 2019-01-09 21:09:14 -0800 | [diff] [blame] | 40 | // If true, never strip the dex files from the final jar when dexpreopting.  Defaults to false. | 
|  | 41 | No_stripping *bool | 
|  | 42 |  | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 43 | // If true, generate an app image (.art file) for this module. | 
|  | 44 | App_image *bool | 
|  | 45 |  | 
|  | 46 | // If true, use a checked-in profile to guide optimization.  Defaults to false unless | 
|  | 47 | // a matching profile is set or a profile is found in PRODUCT_DEX_PREOPT_PROFILE_DIR | 
|  | 48 | // that matches the name of this module, in which case it is defaulted to true. | 
|  | 49 | Profile_guided *bool | 
|  | 50 |  | 
|  | 51 | // If set, provides the path to profile relative to the Android.bp file.  If not set, | 
|  | 52 | // defaults to searching for a file that matches the name of this module in the default | 
|  | 53 | // profile location set by PRODUCT_DEX_PREOPT_PROFILE_DIR, or empty if not found. | 
|  | 54 | Profile *string | 
|  | 55 | } | 
|  | 56 | } | 
|  | 57 |  | 
|  | 58 | func (d *dexpreopter) dexpreoptDisabled(ctx android.ModuleContext) bool { | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 59 | global := dexpreoptGlobalConfig(ctx) | 
|  | 60 |  | 
|  | 61 | if global.DisablePreopt { | 
| Colin Cross | 800fe13 | 2019-02-11 14:21:24 -0800 | [diff] [blame] | 62 | return true | 
|  | 63 | } | 
|  | 64 |  | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 65 | if inList(ctx.ModuleName(), global.DisablePreoptModules) { | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 66 | return true | 
|  | 67 | } | 
|  | 68 |  | 
|  | 69 | if ctx.Config().UnbundledBuild() { | 
|  | 70 | return true | 
|  | 71 | } | 
|  | 72 |  | 
|  | 73 | if d.isTest { | 
|  | 74 | return true | 
|  | 75 | } | 
|  | 76 |  | 
|  | 77 | if !BoolDefault(d.dexpreoptProperties.Dex_preopt.Enabled, true) { | 
|  | 78 | return true | 
|  | 79 | } | 
|  | 80 |  | 
| Colin Cross | dc2da91 | 2019-01-05 22:13:05 -0800 | [diff] [blame] | 81 | if !d.isInstallable { | 
|  | 82 | return true | 
|  | 83 | } | 
|  | 84 |  | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 85 | // TODO: contains no java code | 
|  | 86 |  | 
|  | 87 | return false | 
|  | 88 | } | 
|  | 89 |  | 
| Nicolas Geoffray | fa6e9ec | 2019-02-12 13:12:16 +0000 | [diff] [blame] | 90 | func odexOnSystemOther(ctx android.ModuleContext, installPath android.OutputPath) bool { | 
| Colin Cross | 800fe13 | 2019-02-11 14:21:24 -0800 | [diff] [blame] | 91 | return dexpreopt.OdexOnSystemOtherByName(ctx.ModuleName(), android.InstallPathToOnDevicePath(ctx, installPath), dexpreoptGlobalConfig(ctx)) | 
| Nicolas Geoffray | fa6e9ec | 2019-02-12 13:12:16 +0000 | [diff] [blame] | 92 | } | 
|  | 93 |  | 
|  | 94 | func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.ModuleOutPath) android.ModuleOutPath { | 
|  | 95 | if d.dexpreoptDisabled(ctx) { | 
|  | 96 | return dexJarFile | 
|  | 97 | } | 
|  | 98 |  | 
| Colin Cross | 44df581 | 2019-02-15 23:06:46 -0800 | [diff] [blame] | 99 | global := dexpreoptGlobalConfig(ctx) | 
|  | 100 | bootImage := defaultBootImageConfig(ctx) | 
| Nicolas Geoffray | cd6abd8 | 2019-04-08 17:19:15 +0100 | [diff] [blame] | 101 | defaultBootImage := bootImage | 
| Nicolas Geoffray | 0ebdd34 | 2019-04-04 18:45:20 +0100 | [diff] [blame] | 102 | if global.UseApexImage { | 
|  | 103 | bootImage = apexBootImageConfig(ctx) | 
|  | 104 | } | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 105 |  | 
| Colin Cross | 74ba962 | 2019-02-11 15:11:14 -0800 | [diff] [blame] | 106 | var archs []android.ArchType | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 107 | for _, a := range ctx.MultiTargets() { | 
| Colin Cross | 74ba962 | 2019-02-11 15:11:14 -0800 | [diff] [blame] | 108 | archs = append(archs, a.Arch.ArchType) | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 109 | } | 
|  | 110 | if len(archs) == 0 { | 
|  | 111 | // assume this is a java library, dexpreopt for all arches for now | 
|  | 112 | for _, target := range ctx.Config().Targets[android.Android] { | 
| Colin Cross | 74ba962 | 2019-02-11 15:11:14 -0800 | [diff] [blame] | 113 | archs = append(archs, target.Arch.ArchType) | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 114 | } | 
| Colin Cross | 44df581 | 2019-02-15 23:06:46 -0800 | [diff] [blame] | 115 | if inList(ctx.ModuleName(), global.SystemServerJars) && !d.isSDKLibrary { | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 116 | // If the module is not an SDK library and it's a system server jar, only preopt the primary arch. | 
|  | 117 | archs = archs[:1] | 
|  | 118 | } | 
|  | 119 | } | 
|  | 120 | if ctx.Config().SecondArchIsTranslated() { | 
|  | 121 | // Only preopt primary arch for translated arch since there is only an image there. | 
|  | 122 | archs = archs[:1] | 
|  | 123 | } | 
|  | 124 |  | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 125 | var images android.Paths | 
| Colin Cross | c7e40aa | 2019-02-08 21:37:00 -0800 | [diff] [blame] | 126 | for _, arch := range archs { | 
| Colin Cross | 44df581 | 2019-02-15 23:06:46 -0800 | [diff] [blame] | 127 | images = append(images, bootImage.images[arch]) | 
| Colin Cross | c7e40aa | 2019-02-08 21:37:00 -0800 | [diff] [blame] | 128 | } | 
|  | 129 |  | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 130 | dexLocation := android.InstallPathToOnDevicePath(ctx, d.installPath) | 
|  | 131 |  | 
|  | 132 | strippedDexJarFile := android.PathForModuleOut(ctx, "dexpreopt", dexJarFile.Base()) | 
|  | 133 |  | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 134 | var profileClassListing android.OptionalPath | 
|  | 135 | profileIsTextListing := false | 
|  | 136 | if BoolDefault(d.dexpreoptProperties.Dex_preopt.Profile_guided, true) { | 
|  | 137 | // If dex_preopt.profile_guided is not set, default it based on the existence of the | 
|  | 138 | // dexprepot.profile option or the profile class listing. | 
|  | 139 | if String(d.dexpreoptProperties.Dex_preopt.Profile) != "" { | 
|  | 140 | profileClassListing = android.OptionalPathForPath( | 
|  | 141 | android.PathForModuleSrc(ctx, String(d.dexpreoptProperties.Dex_preopt.Profile))) | 
|  | 142 | profileIsTextListing = true | 
|  | 143 | } else { | 
|  | 144 | profileClassListing = android.ExistentPathForSource(ctx, | 
| Colin Cross | 44df581 | 2019-02-15 23:06:46 -0800 | [diff] [blame] | 145 | global.ProfileDir, ctx.ModuleName()+".prof") | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 146 | } | 
|  | 147 | } | 
|  | 148 |  | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 149 | dexpreoptConfig := dexpreopt.ModuleConfig{ | 
| Victor Hsieh | d181c8b | 2019-01-29 13:00:33 -0800 | [diff] [blame] | 150 | Name:            ctx.ModuleName(), | 
|  | 151 | DexLocation:     dexLocation, | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 152 | BuildPath:       android.PathForModuleOut(ctx, "dexpreopt", ctx.ModuleName()+".jar").OutputPath, | 
|  | 153 | DexPath:         dexJarFile, | 
| Victor Hsieh | d181c8b | 2019-01-29 13:00:33 -0800 | [diff] [blame] | 154 | UncompressedDex: d.uncompressedDex, | 
|  | 155 | HasApkLibraries: false, | 
|  | 156 | PreoptFlags:     nil, | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 157 |  | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 158 | ProfileClassListing:  profileClassListing, | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 159 | ProfileIsTextListing: profileIsTextListing, | 
|  | 160 |  | 
|  | 161 | EnforceUsesLibraries:  false, | 
|  | 162 | OptionalUsesLibraries: nil, | 
|  | 163 | UsesLibraries:         nil, | 
|  | 164 | LibraryPaths:          nil, | 
|  | 165 |  | 
| Colin Cross | c7e40aa | 2019-02-08 21:37:00 -0800 | [diff] [blame] | 166 | Archs:           archs, | 
|  | 167 | DexPreoptImages: images, | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 168 |  | 
| Nicolas Geoffray | cd6abd8 | 2019-04-08 17:19:15 +0100 | [diff] [blame] | 169 | // We use the dex paths and dex locations of the default boot image, as it | 
|  | 170 | // contains the full dexpreopt boot classpath. Other images may just contain a subset of | 
|  | 171 | // the dexpreopt boot classpath. | 
|  | 172 | PreoptBootClassPathDexFiles:     defaultBootImage.dexPaths.Paths(), | 
|  | 173 | PreoptBootClassPathDexLocations: defaultBootImage.dexLocations, | 
| Colin Cross | 800fe13 | 2019-02-11 14:21:24 -0800 | [diff] [blame] | 174 |  | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 175 | PreoptExtractedApk: false, | 
|  | 176 |  | 
|  | 177 | NoCreateAppImage:    !BoolDefault(d.dexpreoptProperties.Dex_preopt.App_image, true), | 
|  | 178 | ForceCreateAppImage: BoolDefault(d.dexpreoptProperties.Dex_preopt.App_image, false), | 
|  | 179 |  | 
| Colin Cross | 8c6d250 | 2019-01-09 21:09:14 -0800 | [diff] [blame] | 180 | NoStripping:     Bool(d.dexpreoptProperties.Dex_preopt.No_stripping), | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 181 | StripInputPath:  dexJarFile, | 
|  | 182 | StripOutputPath: strippedDexJarFile.OutputPath, | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 183 | } | 
|  | 184 |  | 
| Colin Cross | 44df581 | 2019-02-15 23:06:46 -0800 | [diff] [blame] | 185 | dexpreoptRule, err := dexpreopt.GenerateDexpreoptRule(ctx, global, dexpreoptConfig) | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 186 | if err != nil { | 
|  | 187 | ctx.ModuleErrorf("error generating dexpreopt rule: %s", err.Error()) | 
|  | 188 | return dexJarFile | 
|  | 189 | } | 
|  | 190 |  | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 191 | dexpreoptRule.Build(pctx, ctx, "dexpreopt", "dexpreopt") | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 192 |  | 
| Colin Cross | deabb94 | 2019-02-11 14:11:09 -0800 | [diff] [blame] | 193 | d.builtInstalled = dexpreoptRule.Installs().String() | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 194 |  | 
| Colin Cross | 44df581 | 2019-02-15 23:06:46 -0800 | [diff] [blame] | 195 | stripRule, err := dexpreopt.GenerateStripRule(global, dexpreoptConfig) | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 196 | if err != nil { | 
|  | 197 | ctx.ModuleErrorf("error generating dexpreopt strip rule: %s", err.Error()) | 
|  | 198 | return dexJarFile | 
|  | 199 | } | 
|  | 200 |  | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 201 | stripRule.Build(pctx, ctx, "dexpreopt_strip", "dexpreopt strip") | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 202 |  | 
|  | 203 | return strippedDexJarFile | 
|  | 204 | } |