| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 1 | // Copyright (C) 2019 The Android Open Source Project | 
|  | 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 apex | 
|  | 16 |  | 
|  | 17 | import ( | 
|  | 18 | "fmt" | 
| Paul Duffin | c30aea2 | 2021-06-15 19:10:11 +0100 | [diff] [blame] | 19 | "io" | 
| Colin Cross | 6340ea5 | 2021-11-04 12:01:18 -0700 | [diff] [blame] | 20 | "path/filepath" | 
| Jaewoong Jung | fa00c06 | 2020-05-14 14:15:24 -0700 | [diff] [blame] | 21 | "strconv" | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 22 | "strings" | 
|  | 23 |  | 
|  | 24 | "android/soong/android" | 
| Spandan Das | 2069c3f | 2023-12-06 19:40:24 +0000 | [diff] [blame] | 25 | "android/soong/dexpreopt" | 
| Jaewoong Jung | fa00c06 | 2020-05-14 14:15:24 -0700 | [diff] [blame] | 26 | "android/soong/java" | 
| Wei Li | 340ee8e | 2022-03-18 17:33:24 -0700 | [diff] [blame] | 27 | "android/soong/provenance" | 
| Anton Hansson | 805e0a5 | 2022-11-25 14:06:46 +0000 | [diff] [blame] | 28 |  | 
| Jaewoong Jung | fa00c06 | 2020-05-14 14:15:24 -0700 | [diff] [blame] | 29 | "github.com/google/blueprint" | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 30 | "github.com/google/blueprint/proptools" | 
|  | 31 | ) | 
|  | 32 |  | 
| Jaewoong Jung | fa00c06 | 2020-05-14 14:15:24 -0700 | [diff] [blame] | 33 | var ( | 
|  | 34 | extractMatchingApex = pctx.StaticRule( | 
|  | 35 | "extractMatchingApex", | 
|  | 36 | blueprint.RuleParams{ | 
|  | 37 | Command: `rm -rf "$out" && ` + | 
|  | 38 | `${extract_apks} -o "${out}" -allow-prereleased=${allow-prereleased} ` + | 
| Pranav Gupta | 51645ff | 2023-03-20 16:19:53 -0700 | [diff] [blame] | 39 | `-sdk-version=${sdk-version} -skip-sdk-check=${skip-sdk-check} -abis=${abis} ` + | 
|  | 40 | `-screen-densities=all -extract-single ` + | 
| Jaewoong Jung | fa00c06 | 2020-05-14 14:15:24 -0700 | [diff] [blame] | 41 | `${in}`, | 
|  | 42 | CommandDeps: []string{"${extract_apks}"}, | 
|  | 43 | }, | 
| Pranav Gupta | 51645ff | 2023-03-20 16:19:53 -0700 | [diff] [blame] | 44 | "abis", "allow-prereleased", "sdk-version", "skip-sdk-check") | 
| Jaewoong Jung | fa00c06 | 2020-05-14 14:15:24 -0700 | [diff] [blame] | 45 | ) | 
|  | 46 |  | 
| Jiyong Park | 10e926b | 2020-07-16 21:38:56 +0900 | [diff] [blame] | 47 | type prebuilt interface { | 
|  | 48 | isForceDisabled() bool | 
|  | 49 | InstallFilename() string | 
|  | 50 | } | 
|  | 51 |  | 
|  | 52 | type prebuiltCommon struct { | 
| Paul Duffin | ef6b695 | 2021-06-15 11:34:01 +0100 | [diff] [blame] | 53 | android.ModuleBase | 
| Spandan Das | 2069c3f | 2023-12-06 19:40:24 +0000 | [diff] [blame] | 54 | java.Dexpreopter | 
| Paul Duffin | bb0dc13 | 2021-05-05 16:58:08 +0100 | [diff] [blame] | 55 | prebuilt android.Prebuilt | 
| Paul Duffin | dfd3326 | 2021-04-06 17:02:08 +0100 | [diff] [blame] | 56 |  | 
| Paul Duffin | bb0dc13 | 2021-05-05 16:58:08 +0100 | [diff] [blame] | 57 | // Properties common to both prebuilt_apex and apex_set. | 
| Paul Duffin | ef6b695 | 2021-06-15 11:34:01 +0100 | [diff] [blame] | 58 | prebuiltCommonProperties *PrebuiltCommonProperties | 
|  | 59 |  | 
|  | 60 | installDir      android.InstallPath | 
|  | 61 | installFilename string | 
| Colin Cross | 6340ea5 | 2021-11-04 12:01:18 -0700 | [diff] [blame] | 62 | installedFile   android.InstallPath | 
| Paul Duffin | ef6b695 | 2021-06-15 11:34:01 +0100 | [diff] [blame] | 63 | outputApex      android.WritablePath | 
|  | 64 |  | 
| Jooyung Han | 286957d | 2023-10-30 16:17:56 +0900 | [diff] [blame] | 65 | // fragment for this apex for apexkeys.txt | 
|  | 66 | apexKeysPath android.WritablePath | 
|  | 67 |  | 
| Paul Duffin | c30aea2 | 2021-06-15 19:10:11 +0100 | [diff] [blame] | 68 | // A list of apexFile objects created in prebuiltCommon.initApexFilesForAndroidMk which are used | 
|  | 69 | // to create make modules in prebuiltCommon.AndroidMkEntries. | 
|  | 70 | apexFilesForAndroidMk []apexFile | 
|  | 71 |  | 
| Colin Cross | 6340ea5 | 2021-11-04 12:01:18 -0700 | [diff] [blame] | 72 | // Installed locations of symlinks for backward compatibility. | 
|  | 73 | compatSymlinks android.InstallPaths | 
| Paul Duffin | ef6b695 | 2021-06-15 11:34:01 +0100 | [diff] [blame] | 74 |  | 
| Jiakai Zhang | e6e90db | 2022-01-28 14:58:56 +0000 | [diff] [blame] | 75 | hostRequired        []string | 
|  | 76 | requiredModuleNames []string | 
| Jiyong Park | 10e926b | 2020-07-16 21:38:56 +0900 | [diff] [blame] | 77 | } | 
|  | 78 |  | 
| Evgenii Stepanov | 2080bfe | 2020-07-24 15:35:40 -0700 | [diff] [blame] | 79 | type sanitizedPrebuilt interface { | 
|  | 80 | hasSanitizedSource(sanitizer string) bool | 
|  | 81 | } | 
|  | 82 |  | 
| Paul Duffin | ef6b695 | 2021-06-15 11:34:01 +0100 | [diff] [blame] | 83 | type PrebuiltCommonProperties struct { | 
| Paul Duffin | bb0dc13 | 2021-05-05 16:58:08 +0100 | [diff] [blame] | 84 | SelectedApexProperties | 
|  | 85 |  | 
| Martin Stjernholm | d8da28e | 2021-06-24 14:37:13 +0100 | [diff] [blame] | 86 | // Canonical name of this APEX. Used to determine the path to the activated APEX on | 
|  | 87 | // device (/apex/<apex_name>). If unspecified, follows the name property. | 
|  | 88 | Apex_name *string | 
|  | 89 |  | 
| Jiyong Park | 10e926b | 2020-07-16 21:38:56 +0900 | [diff] [blame] | 90 | ForceDisable bool `blueprint:"mutated"` | 
| Paul Duffin | 3bae068 | 2021-05-05 18:03:47 +0100 | [diff] [blame] | 91 |  | 
| Paul Duffin | ef6b695 | 2021-06-15 11:34:01 +0100 | [diff] [blame] | 92 | // whether the extracted apex file is installable. | 
|  | 93 | Installable *bool | 
|  | 94 |  | 
|  | 95 | // optional name for the installed apex. If unspecified, name of the | 
|  | 96 | // module is used as the file name | 
|  | 97 | Filename *string | 
|  | 98 |  | 
|  | 99 | // names of modules to be overridden. Listed modules can only be other binaries | 
|  | 100 | // (in Make or Soong). | 
|  | 101 | // This does not completely prevent installation of the overridden binaries, but if both | 
|  | 102 | // binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed | 
|  | 103 | // from PRODUCT_PACKAGES. | 
|  | 104 | Overrides []string | 
|  | 105 |  | 
| Paul Duffin | 3bae068 | 2021-05-05 18:03:47 +0100 | [diff] [blame] | 106 | // List of java libraries that are embedded inside this prebuilt APEX bundle and for which this | 
|  | 107 | // APEX bundle will create an APEX variant and provide dex implementation jars for use by | 
|  | 108 | // dexpreopt and boot jars package check. | 
|  | 109 | Exported_java_libs []string | 
|  | 110 |  | 
|  | 111 | // List of bootclasspath fragments inside this prebuilt APEX bundle and for which this APEX | 
|  | 112 | // bundle will create an APEX variant. | 
|  | 113 | Exported_bootclasspath_fragments []string | 
| Jiakai Zhang | 774dd30 | 2021-09-26 03:54:25 +0000 | [diff] [blame] | 114 |  | 
|  | 115 | // List of systemserverclasspath fragments inside this prebuilt APEX bundle and for which this | 
|  | 116 | // APEX bundle will create an APEX variant. | 
|  | 117 | Exported_systemserverclasspath_fragments []string | 
| Jiyong Park | 10e926b | 2020-07-16 21:38:56 +0900 | [diff] [blame] | 118 | } | 
|  | 119 |  | 
| Paul Duffin | ef6b695 | 2021-06-15 11:34:01 +0100 | [diff] [blame] | 120 | // initPrebuiltCommon initializes the prebuiltCommon structure and performs initialization of the | 
|  | 121 | // module that is common to Prebuilt and ApexSet. | 
|  | 122 | func (p *prebuiltCommon) initPrebuiltCommon(module android.Module, properties *PrebuiltCommonProperties) { | 
|  | 123 | p.prebuiltCommonProperties = properties | 
|  | 124 | android.InitSingleSourcePrebuiltModule(module.(android.PrebuiltInterface), properties, "Selected_apex") | 
|  | 125 | android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) | 
|  | 126 | } | 
|  | 127 |  | 
| Martin Stjernholm | d8da28e | 2021-06-24 14:37:13 +0100 | [diff] [blame] | 128 | func (p *prebuiltCommon) ApexVariationName() string { | 
|  | 129 | return proptools.StringDefault(p.prebuiltCommonProperties.Apex_name, p.ModuleBase.BaseModuleName()) | 
|  | 130 | } | 
|  | 131 |  | 
| Jiyong Park | 10e926b | 2020-07-16 21:38:56 +0900 | [diff] [blame] | 132 | func (p *prebuiltCommon) Prebuilt() *android.Prebuilt { | 
|  | 133 | return &p.prebuilt | 
|  | 134 | } | 
|  | 135 |  | 
|  | 136 | func (p *prebuiltCommon) isForceDisabled() bool { | 
| Paul Duffin | bb0dc13 | 2021-05-05 16:58:08 +0100 | [diff] [blame] | 137 | return p.prebuiltCommonProperties.ForceDisable | 
| Jiyong Park | 10e926b | 2020-07-16 21:38:56 +0900 | [diff] [blame] | 138 | } | 
|  | 139 |  | 
|  | 140 | func (p *prebuiltCommon) checkForceDisable(ctx android.ModuleContext) bool { | 
| Jooyung Han | eec1b3f | 2023-06-20 16:25:59 +0900 | [diff] [blame] | 141 | forceDisable := false | 
| Jiyong Park | 10e926b | 2020-07-16 21:38:56 +0900 | [diff] [blame] | 142 |  | 
|  | 143 | // Force disable the prebuilts when we are doing unbundled build. We do unbundled build | 
|  | 144 | // to build the prebuilts themselves. | 
|  | 145 | forceDisable = forceDisable || ctx.Config().UnbundledBuild() | 
|  | 146 |  | 
| Evgenii Stepanov | 2080bfe | 2020-07-24 15:35:40 -0700 | [diff] [blame] | 147 | // b/137216042 don't use prebuilts when address sanitizer is on, unless the prebuilt has a sanitized source | 
|  | 148 | sanitized := ctx.Module().(sanitizedPrebuilt) | 
|  | 149 | forceDisable = forceDisable || (android.InList("address", ctx.Config().SanitizeDevice()) && !sanitized.hasSanitizedSource("address")) | 
|  | 150 | forceDisable = forceDisable || (android.InList("hwaddress", ctx.Config().SanitizeDevice()) && !sanitized.hasSanitizedSource("hwaddress")) | 
| Jiyong Park | 10e926b | 2020-07-16 21:38:56 +0900 | [diff] [blame] | 151 |  | 
|  | 152 | if forceDisable && p.prebuilt.SourceExists() { | 
| Paul Duffin | bb0dc13 | 2021-05-05 16:58:08 +0100 | [diff] [blame] | 153 | p.prebuiltCommonProperties.ForceDisable = true | 
| Jiyong Park | 10e926b | 2020-07-16 21:38:56 +0900 | [diff] [blame] | 154 | return true | 
|  | 155 | } | 
|  | 156 | return false | 
|  | 157 | } | 
|  | 158 |  | 
| Paul Duffin | ef6b695 | 2021-06-15 11:34:01 +0100 | [diff] [blame] | 159 | func (p *prebuiltCommon) InstallFilename() string { | 
|  | 160 | return proptools.StringDefault(p.prebuiltCommonProperties.Filename, p.BaseModuleName()+imageApexSuffix) | 
|  | 161 | } | 
|  | 162 |  | 
|  | 163 | func (p *prebuiltCommon) Name() string { | 
|  | 164 | return p.prebuilt.Name(p.ModuleBase.Name()) | 
|  | 165 | } | 
|  | 166 |  | 
|  | 167 | func (p *prebuiltCommon) Overrides() []string { | 
|  | 168 | return p.prebuiltCommonProperties.Overrides | 
|  | 169 | } | 
|  | 170 |  | 
|  | 171 | func (p *prebuiltCommon) installable() bool { | 
|  | 172 | return proptools.BoolDefault(p.prebuiltCommonProperties.Installable, true) | 
|  | 173 | } | 
|  | 174 |  | 
| Spandan Das | 2069c3f | 2023-12-06 19:40:24 +0000 | [diff] [blame] | 175 | // To satisfy java.DexpreopterInterface | 
|  | 176 | func (p *prebuiltCommon) IsInstallable() bool { | 
|  | 177 | return p.installable() | 
|  | 178 | } | 
|  | 179 |  | 
|  | 180 | // initApexFilesForAndroidMk initializes the prebuiltCommon.requiredModuleNames field with the install only deps of the prebuilt apex | 
| Paul Duffin | c30aea2 | 2021-06-15 19:10:11 +0100 | [diff] [blame] | 181 | func (p *prebuiltCommon) initApexFilesForAndroidMk(ctx android.ModuleContext) { | 
| Spandan Das | 2069c3f | 2023-12-06 19:40:24 +0000 | [diff] [blame] | 182 | // If this apex contains a system server jar, then the dexpreopt artifacts should be added as required | 
|  | 183 | for _, install := range p.Dexpreopter.DexpreoptBuiltInstalledForApex() { | 
|  | 184 | p.requiredModuleNames = append(p.requiredModuleNames, install.FullModuleName()) | 
|  | 185 | } | 
|  | 186 | } | 
| Paul Duffin | c30aea2 | 2021-06-15 19:10:11 +0100 | [diff] [blame] | 187 |  | 
| Spandan Das | 2069c3f | 2023-12-06 19:40:24 +0000 | [diff] [blame] | 188 | // If this prebuilt has system server jar, create the rules to dexpreopt it and install it alongside the prebuilt apex | 
|  | 189 | func (p *prebuiltCommon) dexpreoptSystemServerJars(ctx android.ModuleContext) { | 
|  | 190 | // If this apex does not export anything, return | 
|  | 191 | if !p.hasExportedDeps() { | 
|  | 192 | return | 
|  | 193 | } | 
|  | 194 | // Use apex_name to determine the api domain of this prebuilt apex | 
|  | 195 | apexName := p.ApexVariationName() | 
| Spandan Das | fae468e | 2023-12-12 23:23:53 +0000 | [diff] [blame] | 196 | di, err := android.FindDeapexerProviderForModule(ctx) | 
|  | 197 | if err != nil { | 
|  | 198 | ctx.ModuleErrorf(err.Error()) | 
|  | 199 | } | 
| Spandan Das | 2069c3f | 2023-12-06 19:40:24 +0000 | [diff] [blame] | 200 | dc := dexpreopt.GetGlobalConfig(ctx) | 
|  | 201 | systemServerJarList := dc.AllApexSystemServerJars(ctx) | 
|  | 202 |  | 
|  | 203 | for i := 0; i < systemServerJarList.Len(); i++ { | 
|  | 204 | sscpApex := systemServerJarList.Apex(i) | 
|  | 205 | sscpJar := systemServerJarList.Jar(i) | 
|  | 206 | if apexName != sscpApex { | 
|  | 207 | continue | 
| Paul Duffin | c30aea2 | 2021-06-15 19:10:11 +0100 | [diff] [blame] | 208 | } | 
| Spandan Das | 2069c3f | 2023-12-06 19:40:24 +0000 | [diff] [blame] | 209 | p.Dexpreopter.DexpreoptPrebuiltApexSystemServerJars(ctx, sscpJar, di) | 
|  | 210 | } | 
| Paul Duffin | c30aea2 | 2021-06-15 19:10:11 +0100 | [diff] [blame] | 211 | } | 
|  | 212 |  | 
| Jiakai Zhang | 204356f | 2021-09-09 08:12:46 +0000 | [diff] [blame] | 213 | func (p *prebuiltCommon) addRequiredModules(entries *android.AndroidMkEntries) { | 
|  | 214 | for _, fi := range p.apexFilesForAndroidMk { | 
|  | 215 | entries.AddStrings("LOCAL_REQUIRED_MODULES", fi.requiredModuleNames...) | 
|  | 216 | entries.AddStrings("LOCAL_TARGET_REQUIRED_MODULES", fi.targetRequiredModuleNames...) | 
|  | 217 | entries.AddStrings("LOCAL_HOST_REQUIRED_MODULES", fi.hostRequiredModuleNames...) | 
|  | 218 | } | 
| Jiakai Zhang | e6e90db | 2022-01-28 14:58:56 +0000 | [diff] [blame] | 219 | entries.AddStrings("LOCAL_REQUIRED_MODULES", p.requiredModuleNames...) | 
| Jiakai Zhang | 204356f | 2021-09-09 08:12:46 +0000 | [diff] [blame] | 220 | } | 
|  | 221 |  | 
| Paul Duffin | ef6b695 | 2021-06-15 11:34:01 +0100 | [diff] [blame] | 222 | func (p *prebuiltCommon) AndroidMkEntries() []android.AndroidMkEntries { | 
| Paul Duffin | c30aea2 | 2021-06-15 19:10:11 +0100 | [diff] [blame] | 223 | entriesList := []android.AndroidMkEntries{ | 
| Paul Duffin | ef6b695 | 2021-06-15 11:34:01 +0100 | [diff] [blame] | 224 | { | 
|  | 225 | Class:         "ETC", | 
|  | 226 | OutputFile:    android.OptionalPathForPath(p.outputApex), | 
|  | 227 | Include:       "$(BUILD_PREBUILT)", | 
|  | 228 | Host_required: p.hostRequired, | 
|  | 229 | ExtraEntries: []android.AndroidMkExtraEntriesFunc{ | 
|  | 230 | func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { | 
| Colin Cross | c68db4b | 2021-11-11 18:59:15 -0800 | [diff] [blame] | 231 | entries.SetString("LOCAL_MODULE_PATH", p.installDir.String()) | 
| Paul Duffin | ef6b695 | 2021-06-15 11:34:01 +0100 | [diff] [blame] | 232 | entries.SetString("LOCAL_MODULE_STEM", p.installFilename) | 
| Colin Cross | 6340ea5 | 2021-11-04 12:01:18 -0700 | [diff] [blame] | 233 | entries.SetPath("LOCAL_SOONG_INSTALLED_MODULE", p.installedFile) | 
|  | 234 | entries.SetString("LOCAL_SOONG_INSTALL_PAIRS", p.outputApex.String()+":"+p.installedFile.String()) | 
| Cole Faust | d22afe9 | 2023-08-18 16:05:44 -0700 | [diff] [blame] | 235 | entries.AddStrings("LOCAL_SOONG_INSTALL_SYMLINKS", p.compatSymlinks.Strings()...) | 
| Paul Duffin | ef6b695 | 2021-06-15 11:34:01 +0100 | [diff] [blame] | 236 | entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", !p.installable()) | 
|  | 237 | entries.AddStrings("LOCAL_OVERRIDES_MODULES", p.prebuiltCommonProperties.Overrides...) | 
| Jooyung Han | 286957d | 2023-10-30 16:17:56 +0900 | [diff] [blame] | 238 | entries.SetString("LOCAL_APEX_KEY_PATH", p.apexKeysPath.String()) | 
| Jiakai Zhang | 204356f | 2021-09-09 08:12:46 +0000 | [diff] [blame] | 239 | p.addRequiredModules(entries) | 
| Paul Duffin | ef6b695 | 2021-06-15 11:34:01 +0100 | [diff] [blame] | 240 | }, | 
|  | 241 | }, | 
|  | 242 | }, | 
|  | 243 | } | 
| Paul Duffin | c30aea2 | 2021-06-15 19:10:11 +0100 | [diff] [blame] | 244 |  | 
| Spandan Das | 2069c3f | 2023-12-06 19:40:24 +0000 | [diff] [blame] | 245 | // Add the dexpreopt artifacts to androidmk | 
|  | 246 | for _, install := range p.Dexpreopter.DexpreoptBuiltInstalledForApex() { | 
|  | 247 | entriesList = append(entriesList, install.ToMakeEntries()) | 
|  | 248 | } | 
|  | 249 |  | 
| Paul Duffin | c30aea2 | 2021-06-15 19:10:11 +0100 | [diff] [blame] | 250 | // Iterate over the apexFilesForAndroidMk list and create an AndroidMkEntries struct for each | 
|  | 251 | // file. This provides similar behavior to that provided in apexBundle.AndroidMk() as it makes the | 
|  | 252 | // apex specific variants of the exported java modules available for use from within make. | 
|  | 253 | apexName := p.BaseModuleName() | 
|  | 254 | for _, fi := range p.apexFilesForAndroidMk { | 
| Paul Duffin | 9dc8c54 | 2021-06-17 13:33:09 +0100 | [diff] [blame] | 255 | entries := p.createEntriesForApexFile(fi, apexName) | 
| Paul Duffin | c30aea2 | 2021-06-15 19:10:11 +0100 | [diff] [blame] | 256 | entriesList = append(entriesList, entries) | 
|  | 257 | } | 
|  | 258 |  | 
|  | 259 | return entriesList | 
| Paul Duffin | ef6b695 | 2021-06-15 11:34:01 +0100 | [diff] [blame] | 260 | } | 
|  | 261 |  | 
| Paul Duffin | 9dc8c54 | 2021-06-17 13:33:09 +0100 | [diff] [blame] | 262 | // createEntriesForApexFile creates an AndroidMkEntries for the supplied apexFile | 
|  | 263 | func (p *prebuiltCommon) createEntriesForApexFile(fi apexFile, apexName string) android.AndroidMkEntries { | 
|  | 264 | moduleName := fi.androidMkModuleName + "." + apexName | 
|  | 265 | entries := android.AndroidMkEntries{ | 
|  | 266 | Class:        fi.class.nameInMake(), | 
|  | 267 | OverrideName: moduleName, | 
|  | 268 | OutputFile:   android.OptionalPathForPath(fi.builtFile), | 
|  | 269 | Include:      "$(BUILD_SYSTEM)/soong_java_prebuilt.mk", | 
|  | 270 | ExtraEntries: []android.AndroidMkExtraEntriesFunc{ | 
|  | 271 | func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { | 
| Colin Cross | c68db4b | 2021-11-11 18:59:15 -0800 | [diff] [blame] | 272 | entries.SetString("LOCAL_MODULE_PATH", p.installDir.String()) | 
| Martin Stjernholm | ae44fd8 | 2021-11-23 23:17:33 +0000 | [diff] [blame] | 273 | entries.SetString("LOCAL_SOONG_INSTALLED_MODULE", filepath.Join(p.installDir.String(), fi.stem())) | 
|  | 274 | entries.SetString("LOCAL_SOONG_INSTALL_PAIRS", | 
| Colin Cross | 6340ea5 | 2021-11-04 12:01:18 -0700 | [diff] [blame] | 275 | fi.builtFile.String()+":"+filepath.Join(p.installDir.String(), fi.stem())) | 
| Paul Duffin | 9dc8c54 | 2021-06-17 13:33:09 +0100 | [diff] [blame] | 276 |  | 
|  | 277 | // soong_java_prebuilt.mk sets LOCAL_MODULE_SUFFIX := .jar  Therefore | 
|  | 278 | // we need to remove the suffix from LOCAL_MODULE_STEM, otherwise | 
|  | 279 | // we will have foo.jar.jar | 
|  | 280 | entries.SetString("LOCAL_MODULE_STEM", strings.TrimSuffix(fi.stem(), ".jar")) | 
| Paul Duffin | 9dc8c54 | 2021-06-17 13:33:09 +0100 | [diff] [blame] | 281 | entries.SetString("LOCAL_SOONG_DEX_JAR", fi.builtFile.String()) | 
|  | 282 | entries.SetString("LOCAL_DEX_PREOPT", "false") | 
|  | 283 | }, | 
|  | 284 | }, | 
|  | 285 | ExtraFooters: []android.AndroidMkExtraFootersFunc{ | 
|  | 286 | func(w io.Writer, name, prefix, moduleDir string) { | 
|  | 287 | // m <module_name> will build <module_name>.<apex_name> as well. | 
|  | 288 | if fi.androidMkModuleName != moduleName { | 
|  | 289 | fmt.Fprintf(w, ".PHONY: %s\n", fi.androidMkModuleName) | 
|  | 290 | fmt.Fprintf(w, "%s: %s\n", fi.androidMkModuleName, moduleName) | 
|  | 291 | } | 
|  | 292 | }, | 
|  | 293 | }, | 
|  | 294 | } | 
|  | 295 | return entries | 
|  | 296 | } | 
|  | 297 |  | 
| Paul Duffin | 5dda3e3 | 2021-05-05 14:13:27 +0100 | [diff] [blame] | 298 | // prebuiltApexModuleCreator defines the methods that need to be implemented by prebuilt_apex and | 
|  | 299 | // apex_set in order to create the modules needed to provide access to the prebuilt .apex file. | 
|  | 300 | type prebuiltApexModuleCreator interface { | 
|  | 301 | createPrebuiltApexModules(ctx android.TopDownMutatorContext) | 
|  | 302 | } | 
|  | 303 |  | 
|  | 304 | // prebuiltApexModuleCreatorMutator is the mutator responsible for invoking the | 
|  | 305 | // prebuiltApexModuleCreator's createPrebuiltApexModules method. | 
|  | 306 | // | 
|  | 307 | // It is registered as a pre-arch mutator as it must run after the ComponentDepsMutator because it | 
|  | 308 | // will need to access dependencies added by that (exported modules) but must run before the | 
|  | 309 | // DepsMutator so that the deapexer module it creates can add dependencies onto itself from the | 
|  | 310 | // exported modules. | 
|  | 311 | func prebuiltApexModuleCreatorMutator(ctx android.TopDownMutatorContext) { | 
|  | 312 | module := ctx.Module() | 
|  | 313 | if creator, ok := module.(prebuiltApexModuleCreator); ok { | 
|  | 314 | creator.createPrebuiltApexModules(ctx) | 
|  | 315 | } | 
|  | 316 | } | 
|  | 317 |  | 
| Liz Kammer | 2dc7244 | 2023-04-20 10:10:48 -0400 | [diff] [blame] | 318 | func (p *prebuiltCommon) hasExportedDeps() bool { | 
|  | 319 | return len(p.prebuiltCommonProperties.Exported_java_libs) > 0 || | 
|  | 320 | len(p.prebuiltCommonProperties.Exported_bootclasspath_fragments) > 0 || | 
|  | 321 | len(p.prebuiltCommonProperties.Exported_systemserverclasspath_fragments) > 0 | 
| Jiakai Zhang | 774dd30 | 2021-09-26 03:54:25 +0000 | [diff] [blame] | 322 | } | 
|  | 323 |  | 
| Paul Duffin | 57f8359 | 2021-05-05 15:09:44 +0100 | [diff] [blame] | 324 | // prebuiltApexContentsDeps adds dependencies onto the prebuilt apex module's contents. | 
|  | 325 | func (p *prebuiltCommon) prebuiltApexContentsDeps(ctx android.BottomUpMutatorContext) { | 
|  | 326 | module := ctx.Module() | 
| Paul Duffin | 023dba0 | 2021-04-22 01:45:29 +0100 | [diff] [blame] | 327 |  | 
| Liz Kammer | 2dc7244 | 2023-04-20 10:10:48 -0400 | [diff] [blame] | 328 | for _, dep := range p.prebuiltCommonProperties.Exported_java_libs { | 
| Jiakai Zhang | 774dd30 | 2021-09-26 03:54:25 +0000 | [diff] [blame] | 329 | prebuiltDep := android.PrebuiltNameFromSource(dep) | 
| Liz Kammer | 2dc7244 | 2023-04-20 10:10:48 -0400 | [diff] [blame] | 330 | ctx.AddDependency(module, exportedJavaLibTag, prebuiltDep) | 
|  | 331 | } | 
|  | 332 |  | 
|  | 333 | for _, dep := range p.prebuiltCommonProperties.Exported_bootclasspath_fragments { | 
|  | 334 | prebuiltDep := android.PrebuiltNameFromSource(dep) | 
|  | 335 | ctx.AddDependency(module, exportedBootclasspathFragmentTag, prebuiltDep) | 
|  | 336 | } | 
|  | 337 |  | 
|  | 338 | for _, dep := range p.prebuiltCommonProperties.Exported_systemserverclasspath_fragments { | 
|  | 339 | prebuiltDep := android.PrebuiltNameFromSource(dep) | 
|  | 340 | ctx.AddDependency(module, exportedSystemserverclasspathFragmentTag, prebuiltDep) | 
| Paul Duffin | 023dba0 | 2021-04-22 01:45:29 +0100 | [diff] [blame] | 341 | } | 
| Paul Duffin | dfd3326 | 2021-04-06 17:02:08 +0100 | [diff] [blame] | 342 | } | 
|  | 343 |  | 
| Paul Duffin | b17d044 | 2021-05-05 12:07:00 +0100 | [diff] [blame] | 344 | // Implements android.DepInInSameApex | 
|  | 345 | func (p *prebuiltCommon) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool { | 
|  | 346 | tag := ctx.OtherModuleDependencyTag(dep) | 
|  | 347 | _, ok := tag.(exportedDependencyTag) | 
|  | 348 | return ok | 
|  | 349 | } | 
|  | 350 |  | 
| Paul Duffin | dfd3326 | 2021-04-06 17:02:08 +0100 | [diff] [blame] | 351 | // apexInfoMutator marks any modules for which this apex exports a file as requiring an apex | 
|  | 352 | // specific variant and checks that they are supported. | 
|  | 353 | // | 
|  | 354 | // The apexMutator will ensure that the ApexInfo objects passed to BuildForApex(ApexInfo) are | 
|  | 355 | // associated with the apex specific variant using the ApexInfoProvider for later retrieval. | 
|  | 356 | // | 
|  | 357 | // Unlike the source apex module type the prebuilt_apex module type cannot share compatible variants | 
|  | 358 | // across prebuilt_apex modules. That is because there is no way to determine whether two | 
|  | 359 | // prebuilt_apex modules that export files for the same module are compatible. e.g. they could have | 
|  | 360 | // been built from different source at different times or they could have been built with different | 
|  | 361 | // build options that affect the libraries. | 
|  | 362 | // | 
|  | 363 | // While it may be possible to provide sufficient information to determine whether two prebuilt_apex | 
|  | 364 | // modules were compatible it would be a lot of work and would not provide much benefit for a couple | 
|  | 365 | // of reasons: | 
| Colin Cross | d079e0b | 2022-08-16 10:27:33 -0700 | [diff] [blame] | 366 | //   - The number of prebuilt_apex modules that will be exporting files for the same module will be | 
|  | 367 | //     low as the prebuilt_apex only exports files for the direct dependencies that require it and | 
|  | 368 | //     very few modules are direct dependencies of multiple prebuilt_apex modules, e.g. there are a | 
|  | 369 | //     few com.android.art* apex files that contain the same contents and could export files for the | 
|  | 370 | //     same modules but only one of them needs to do so. Contrast that with source apex modules which | 
|  | 371 | //     need apex specific variants for every module that contributes code to the apex, whether direct | 
|  | 372 | //     or indirect. | 
|  | 373 | //   - The build cost of a prebuilt_apex variant is generally low as at worst it will involve some | 
|  | 374 | //     extra copying of files. Contrast that with source apex modules that has to build each variant | 
|  | 375 | //     from source. | 
| Paul Duffin | dfd3326 | 2021-04-06 17:02:08 +0100 | [diff] [blame] | 376 | func (p *prebuiltCommon) apexInfoMutator(mctx android.TopDownMutatorContext) { | 
|  | 377 |  | 
|  | 378 | // Collect direct dependencies into contents. | 
|  | 379 | contents := make(map[string]android.ApexMembership) | 
|  | 380 |  | 
|  | 381 | // Collect the list of dependencies. | 
|  | 382 | var dependencies []android.ApexModule | 
| Paul Duffin | b17d044 | 2021-05-05 12:07:00 +0100 | [diff] [blame] | 383 | mctx.WalkDeps(func(child, parent android.Module) bool { | 
|  | 384 | // If the child is not in the same apex as the parent then exit immediately and do not visit | 
|  | 385 | // any of the child's dependencies. | 
|  | 386 | if !android.IsDepInSameApex(mctx, parent, child) { | 
|  | 387 | return false | 
|  | 388 | } | 
|  | 389 |  | 
|  | 390 | tag := mctx.OtherModuleDependencyTag(child) | 
|  | 391 | depName := mctx.OtherModuleName(child) | 
| Paul Duffin | 023dba0 | 2021-04-22 01:45:29 +0100 | [diff] [blame] | 392 | if exportedTag, ok := tag.(exportedDependencyTag); ok { | 
|  | 393 | propertyName := exportedTag.name | 
| Paul Duffin | dfd3326 | 2021-04-06 17:02:08 +0100 | [diff] [blame] | 394 |  | 
|  | 395 | // It is an error if the other module is not a prebuilt. | 
| Paul Duffin | b17d044 | 2021-05-05 12:07:00 +0100 | [diff] [blame] | 396 | if !android.IsModulePrebuilt(child) { | 
| Paul Duffin | 023dba0 | 2021-04-22 01:45:29 +0100 | [diff] [blame] | 397 | mctx.PropertyErrorf(propertyName, "%q is not a prebuilt module", depName) | 
| Paul Duffin | b17d044 | 2021-05-05 12:07:00 +0100 | [diff] [blame] | 398 | return false | 
| Paul Duffin | dfd3326 | 2021-04-06 17:02:08 +0100 | [diff] [blame] | 399 | } | 
|  | 400 |  | 
|  | 401 | // It is an error if the other module is not an ApexModule. | 
| Paul Duffin | b17d044 | 2021-05-05 12:07:00 +0100 | [diff] [blame] | 402 | if _, ok := child.(android.ApexModule); !ok { | 
| Paul Duffin | 023dba0 | 2021-04-22 01:45:29 +0100 | [diff] [blame] | 403 | mctx.PropertyErrorf(propertyName, "%q is not usable within an apex", depName) | 
| Paul Duffin | b17d044 | 2021-05-05 12:07:00 +0100 | [diff] [blame] | 404 | return false | 
| Paul Duffin | dfd3326 | 2021-04-06 17:02:08 +0100 | [diff] [blame] | 405 | } | 
| Paul Duffin | dfd3326 | 2021-04-06 17:02:08 +0100 | [diff] [blame] | 406 | } | 
| Paul Duffin | b17d044 | 2021-05-05 12:07:00 +0100 | [diff] [blame] | 407 |  | 
| Paul Duffin | fee8cf3 | 2021-06-29 18:38:38 +0100 | [diff] [blame] | 408 | // Ignore any modules that do not implement ApexModule as they cannot have an APEX specific | 
|  | 409 | // variant. | 
|  | 410 | if _, ok := child.(android.ApexModule); !ok { | 
|  | 411 | return false | 
|  | 412 | } | 
|  | 413 |  | 
| Paul Duffin | b17d044 | 2021-05-05 12:07:00 +0100 | [diff] [blame] | 414 | // Strip off the prebuilt_ prefix if present before storing content to ensure consistent | 
|  | 415 | // behavior whether there is a corresponding source module present or not. | 
|  | 416 | depName = android.RemoveOptionalPrebuiltPrefix(depName) | 
|  | 417 |  | 
|  | 418 | // Remember if this module was added as a direct dependency. | 
|  | 419 | direct := parent == mctx.Module() | 
|  | 420 | contents[depName] = contents[depName].Add(direct) | 
|  | 421 |  | 
|  | 422 | // Add the module to the list of dependencies that need to have an APEX variant. | 
|  | 423 | dependencies = append(dependencies, child.(android.ApexModule)) | 
|  | 424 |  | 
|  | 425 | return true | 
| Paul Duffin | dfd3326 | 2021-04-06 17:02:08 +0100 | [diff] [blame] | 426 | }) | 
|  | 427 |  | 
|  | 428 | // Create contents for the prebuilt_apex and store it away for later use. | 
|  | 429 | apexContents := android.NewApexContents(contents) | 
| Colin Cross | 4021302 | 2023-12-13 15:19:49 -0800 | [diff] [blame] | 430 | android.SetProvider(mctx, ApexBundleInfoProvider, ApexBundleInfo{ | 
| Paul Duffin | dfd3326 | 2021-04-06 17:02:08 +0100 | [diff] [blame] | 431 | Contents: apexContents, | 
|  | 432 | }) | 
|  | 433 |  | 
|  | 434 | // Create an ApexInfo for the prebuilt_apex. | 
| Martin Stjernholm | d8da28e | 2021-06-24 14:37:13 +0100 | [diff] [blame] | 435 | apexVariationName := p.ApexVariationName() | 
| Paul Duffin | dfd3326 | 2021-04-06 17:02:08 +0100 | [diff] [blame] | 436 | apexInfo := android.ApexInfo{ | 
| Martin Stjernholm | c4f4ced | 2021-05-27 11:17:00 +0000 | [diff] [blame] | 437 | ApexVariationName: apexVariationName, | 
|  | 438 | InApexVariants:    []string{apexVariationName}, | 
| Martin Stjernholm | d8da28e | 2021-06-24 14:37:13 +0100 | [diff] [blame] | 439 | InApexModules:     []string{p.ModuleBase.BaseModuleName()}, // BaseModuleName() to avoid the prebuilt_ prefix. | 
| Paul Duffin | dfd3326 | 2021-04-06 17:02:08 +0100 | [diff] [blame] | 440 | ApexContents:      []*android.ApexContents{apexContents}, | 
|  | 441 | ForPrebuiltApex:   true, | 
|  | 442 | } | 
|  | 443 |  | 
|  | 444 | // Mark the dependencies of this module as requiring a variant for this module. | 
|  | 445 | for _, am := range dependencies { | 
|  | 446 | am.BuildForApex(apexInfo) | 
|  | 447 | } | 
|  | 448 | } | 
|  | 449 |  | 
| Paul Duffin | 11216db | 2021-03-01 14:14:52 +0000 | [diff] [blame] | 450 | // prebuiltApexSelectorModule is a private module type that is only created by the prebuilt_apex | 
|  | 451 | // module. It selects the apex to use and makes it available for use by prebuilt_apex and the | 
|  | 452 | // deapexer. | 
|  | 453 | type prebuiltApexSelectorModule struct { | 
|  | 454 | android.ModuleBase | 
|  | 455 |  | 
|  | 456 | apexFileProperties ApexFileProperties | 
|  | 457 |  | 
|  | 458 | inputApex android.Path | 
|  | 459 | } | 
|  | 460 |  | 
|  | 461 | func privateApexSelectorModuleFactory() android.Module { | 
|  | 462 | module := &prebuiltApexSelectorModule{} | 
|  | 463 | module.AddProperties( | 
|  | 464 | &module.apexFileProperties, | 
|  | 465 | ) | 
|  | 466 | android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) | 
|  | 467 | return module | 
|  | 468 | } | 
|  | 469 |  | 
|  | 470 | func (p *prebuiltApexSelectorModule) Srcs() android.Paths { | 
|  | 471 | return android.Paths{p.inputApex} | 
|  | 472 | } | 
|  | 473 |  | 
|  | 474 | func (p *prebuiltApexSelectorModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { | 
|  | 475 | p.inputApex = android.SingleSourcePathFromSupplier(ctx, p.apexFileProperties.prebuiltApexSelector, "src") | 
|  | 476 | } | 
|  | 477 |  | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 478 | type Prebuilt struct { | 
| Jiyong Park | 10e926b | 2020-07-16 21:38:56 +0900 | [diff] [blame] | 479 | prebuiltCommon | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 480 |  | 
| Paul Duffin | bb0dc13 | 2021-05-05 16:58:08 +0100 | [diff] [blame] | 481 | properties PrebuiltProperties | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 482 |  | 
| Paul Duffin | ef6b695 | 2021-06-15 11:34:01 +0100 | [diff] [blame] | 483 | inputApex android.Path | 
| Wei Li | 340ee8e | 2022-03-18 17:33:24 -0700 | [diff] [blame] | 484 |  | 
|  | 485 | provenanceMetaDataFile android.OutputPath | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 486 | } | 
|  | 487 |  | 
| Paul Duffin | 851f399 | 2021-01-13 17:03:51 +0000 | [diff] [blame] | 488 | type ApexFileProperties struct { | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 489 | // the path to the prebuilt .apex file to import. | 
| Paul Duffin | c04fb9e | 2021-03-01 12:25:10 +0000 | [diff] [blame] | 490 | // | 
|  | 491 | // This cannot be marked as `android:"arch_variant"` because the `prebuilt_apex` is only mutated | 
|  | 492 | // for android_common. That is so that it will have the same arch variant as, and so be compatible | 
|  | 493 | // with, the source `apex` module type that it replaces. | 
| Paul Duffin | 11216db | 2021-03-01 14:14:52 +0000 | [diff] [blame] | 494 | Src  *string `android:"path"` | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 495 | Arch struct { | 
|  | 496 | Arm struct { | 
| Paul Duffin | 11216db | 2021-03-01 14:14:52 +0000 | [diff] [blame] | 497 | Src *string `android:"path"` | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 498 | } | 
|  | 499 | Arm64 struct { | 
| Paul Duffin | 11216db | 2021-03-01 14:14:52 +0000 | [diff] [blame] | 500 | Src *string `android:"path"` | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 501 | } | 
| Chen Guoyin | 401f298 | 2022-10-12 19:28:48 +0800 | [diff] [blame] | 502 | Riscv64 struct { | 
|  | 503 | Src *string `android:"path"` | 
|  | 504 | } | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 505 | X86 struct { | 
| Paul Duffin | 11216db | 2021-03-01 14:14:52 +0000 | [diff] [blame] | 506 | Src *string `android:"path"` | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 507 | } | 
|  | 508 | X86_64 struct { | 
| Paul Duffin | 11216db | 2021-03-01 14:14:52 +0000 | [diff] [blame] | 509 | Src *string `android:"path"` | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 510 | } | 
|  | 511 | } | 
| Paul Duffin | 851f399 | 2021-01-13 17:03:51 +0000 | [diff] [blame] | 512 | } | 
|  | 513 |  | 
| Paul Duffin | c04fb9e | 2021-03-01 12:25:10 +0000 | [diff] [blame] | 514 | // prebuiltApexSelector selects the correct prebuilt APEX file for the build target. | 
|  | 515 | // | 
|  | 516 | // The ctx parameter can be for any module not just the prebuilt module so care must be taken not | 
|  | 517 | // to use methods on it that are specific to the current module. | 
|  | 518 | // | 
|  | 519 | // See the ApexFileProperties.Src property. | 
|  | 520 | func (p *ApexFileProperties) prebuiltApexSelector(ctx android.BaseModuleContext, prebuilt android.Module) []string { | 
|  | 521 | multiTargets := prebuilt.MultiTargets() | 
|  | 522 | if len(multiTargets) != 1 { | 
|  | 523 | ctx.OtherModuleErrorf(prebuilt, "compile_multilib shouldn't be \"both\" for prebuilt_apex") | 
|  | 524 | return nil | 
| Paul Duffin | 851f399 | 2021-01-13 17:03:51 +0000 | [diff] [blame] | 525 | } | 
|  | 526 | var src string | 
| Paul Duffin | c04fb9e | 2021-03-01 12:25:10 +0000 | [diff] [blame] | 527 | switch multiTargets[0].Arch.ArchType { | 
| Paul Duffin | 851f399 | 2021-01-13 17:03:51 +0000 | [diff] [blame] | 528 | case android.Arm: | 
|  | 529 | src = String(p.Arch.Arm.Src) | 
|  | 530 | case android.Arm64: | 
|  | 531 | src = String(p.Arch.Arm64.Src) | 
| Chen Guoyin | 401f298 | 2022-10-12 19:28:48 +0800 | [diff] [blame] | 532 | case android.Riscv64: | 
|  | 533 | src = String(p.Arch.Riscv64.Src) | 
| Colin Cross | abacbe8 | 2022-11-01 09:26:51 -0700 | [diff] [blame] | 534 | // HACK: fall back to arm64 prebuilts, the riscv64 ones don't exist yet. | 
|  | 535 | if src == "" { | 
|  | 536 | src = String(p.Arch.Arm64.Src) | 
|  | 537 | } | 
| Paul Duffin | 851f399 | 2021-01-13 17:03:51 +0000 | [diff] [blame] | 538 | case android.X86: | 
|  | 539 | src = String(p.Arch.X86.Src) | 
|  | 540 | case android.X86_64: | 
|  | 541 | src = String(p.Arch.X86_64.Src) | 
| Paul Duffin | 851f399 | 2021-01-13 17:03:51 +0000 | [diff] [blame] | 542 | } | 
|  | 543 | if src == "" { | 
|  | 544 | src = String(p.Src) | 
|  | 545 | } | 
| Paul Duffin | 851f399 | 2021-01-13 17:03:51 +0000 | [diff] [blame] | 546 |  | 
| Paul Duffin | c0609c6 | 2021-03-01 17:27:16 +0000 | [diff] [blame] | 547 | if src == "" { | 
| Colin Cross | 553a31b | 2022-10-03 22:02:09 -0700 | [diff] [blame] | 548 | if ctx.Config().AllowMissingDependencies() { | 
|  | 549 | ctx.AddMissingDependencies([]string{ctx.OtherModuleName(prebuilt)}) | 
|  | 550 | } else { | 
|  | 551 | ctx.OtherModuleErrorf(prebuilt, "prebuilt_apex does not support %q", multiTargets[0].Arch.String()) | 
|  | 552 | } | 
| Paul Duffin | c0609c6 | 2021-03-01 17:27:16 +0000 | [diff] [blame] | 553 | // Drop through to return an empty string as the src (instead of nil) to avoid the prebuilt | 
|  | 554 | // logic from reporting a more general, less useful message. | 
|  | 555 | } | 
|  | 556 |  | 
| Paul Duffin | c04fb9e | 2021-03-01 12:25:10 +0000 | [diff] [blame] | 557 | return []string{src} | 
| Paul Duffin | 851f399 | 2021-01-13 17:03:51 +0000 | [diff] [blame] | 558 | } | 
|  | 559 |  | 
|  | 560 | type PrebuiltProperties struct { | 
|  | 561 | ApexFileProperties | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 562 |  | 
| Paul Duffin | ef6b695 | 2021-06-15 11:34:01 +0100 | [diff] [blame] | 563 | PrebuiltCommonProperties | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 564 | } | 
|  | 565 |  | 
| Evgenii Stepanov | 2080bfe | 2020-07-24 15:35:40 -0700 | [diff] [blame] | 566 | func (a *Prebuilt) hasSanitizedSource(sanitizer string) bool { | 
|  | 567 | return false | 
|  | 568 | } | 
|  | 569 |  | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 570 | func (p *Prebuilt) OutputFiles(tag string) (android.Paths, error) { | 
|  | 571 | switch tag { | 
|  | 572 | case "": | 
|  | 573 | return android.Paths{p.outputApex}, nil | 
|  | 574 | default: | 
|  | 575 | return nil, fmt.Errorf("unsupported module reference tag %q", tag) | 
|  | 576 | } | 
|  | 577 | } | 
|  | 578 |  | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 579 | // prebuilt_apex imports an `.apex` file into the build graph as if it was built with apex. | 
|  | 580 | func PrebuiltFactory() android.Module { | 
|  | 581 | module := &Prebuilt{} | 
| Paul Duffin | ef6b695 | 2021-06-15 11:34:01 +0100 | [diff] [blame] | 582 | module.AddProperties(&module.properties) | 
|  | 583 | module.initPrebuiltCommon(module, &module.properties.PrebuiltCommonProperties) | 
| Paul Duffin | 064b70c | 2020-11-02 17:32:38 +0000 | [diff] [blame] | 584 |  | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 585 | return module | 
|  | 586 | } | 
|  | 587 |  | 
| Paul Duffin | 5dda3e3 | 2021-05-05 14:13:27 +0100 | [diff] [blame] | 588 | func createApexSelectorModule(ctx android.TopDownMutatorContext, name string, apexFileProperties *ApexFileProperties) { | 
| Paul Duffin | 11216db | 2021-03-01 14:14:52 +0000 | [diff] [blame] | 589 | props := struct { | 
|  | 590 | Name *string | 
|  | 591 | }{ | 
|  | 592 | Name: proptools.StringPtr(name), | 
|  | 593 | } | 
|  | 594 |  | 
|  | 595 | ctx.CreateModule(privateApexSelectorModuleFactory, | 
|  | 596 | &props, | 
|  | 597 | apexFileProperties, | 
|  | 598 | ) | 
|  | 599 | } | 
|  | 600 |  | 
| Paul Duffin | 5dda3e3 | 2021-05-05 14:13:27 +0100 | [diff] [blame] | 601 | // createDeapexerModuleIfNeeded will create a deapexer module if it is needed. | 
|  | 602 | // | 
| Paul Duffin | 57f8359 | 2021-05-05 15:09:44 +0100 | [diff] [blame] | 603 | // A deapexer module is only needed when the prebuilt apex specifies one or more modules in either | 
|  | 604 | // the `exported_java_libs` or `exported_bootclasspath_fragments` properties as that indicates that | 
|  | 605 | // the listed modules need access to files from within the prebuilt .apex file. | 
| Jiakai Zhang | 774dd30 | 2021-09-26 03:54:25 +0000 | [diff] [blame] | 606 | func (p *prebuiltCommon) createDeapexerModuleIfNeeded(ctx android.TopDownMutatorContext, deapexerName string, apexFileSource string) { | 
| Paul Duffin | 5dda3e3 | 2021-05-05 14:13:27 +0100 | [diff] [blame] | 607 | // Only create the deapexer module if it is needed. | 
| Liz Kammer | 2dc7244 | 2023-04-20 10:10:48 -0400 | [diff] [blame] | 608 | if !p.hasExportedDeps() { | 
| Paul Duffin | 5dda3e3 | 2021-05-05 14:13:27 +0100 | [diff] [blame] | 609 | return | 
|  | 610 | } | 
|  | 611 |  | 
| Paul Duffin | 57f8359 | 2021-05-05 15:09:44 +0100 | [diff] [blame] | 612 | // Compute the deapexer properties from the transitive dependencies of this module. | 
| Paul Duffin | b508405 | 2021-06-07 10:25:31 +0100 | [diff] [blame] | 613 | commonModules := []string{} | 
| Paul Duffin | 034196d | 2021-06-17 15:59:07 +0100 | [diff] [blame] | 614 | exportedFiles := []string{} | 
| Paul Duffin | 57f8359 | 2021-05-05 15:09:44 +0100 | [diff] [blame] | 615 | ctx.WalkDeps(func(child, parent android.Module) bool { | 
|  | 616 | tag := ctx.OtherModuleDependencyTag(child) | 
|  | 617 |  | 
| Paul Duffin | 7db57e0 | 2021-06-17 14:56:05 +0100 | [diff] [blame] | 618 | // If the child is not in the same apex as the parent then ignore it and all its children. | 
|  | 619 | if !android.IsDepInSameApex(ctx, parent, child) { | 
|  | 620 | return false | 
|  | 621 | } | 
|  | 622 |  | 
| Paul Duffin | 57f8359 | 2021-05-05 15:09:44 +0100 | [diff] [blame] | 623 | name := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(child)) | 
| Paul Duffin | 7db57e0 | 2021-06-17 14:56:05 +0100 | [diff] [blame] | 624 | if _, ok := tag.(android.RequiresFilesFromPrebuiltApexTag); ok { | 
| Paul Duffin | b508405 | 2021-06-07 10:25:31 +0100 | [diff] [blame] | 625 | commonModules = append(commonModules, name) | 
|  | 626 |  | 
|  | 627 | requiredFiles := child.(android.RequiredFilesFromPrebuiltApex).RequiredFilesFromPrebuiltApex(ctx) | 
| Paul Duffin | 034196d | 2021-06-17 15:59:07 +0100 | [diff] [blame] | 628 | exportedFiles = append(exportedFiles, requiredFiles...) | 
| Paul Duffin | b508405 | 2021-06-07 10:25:31 +0100 | [diff] [blame] | 629 |  | 
| Paul Duffin | 7db57e0 | 2021-06-17 14:56:05 +0100 | [diff] [blame] | 630 | // Visit the dependencies of this module just in case they also require files from the | 
|  | 631 | // prebuilt apex. | 
| Paul Duffin | 57f8359 | 2021-05-05 15:09:44 +0100 | [diff] [blame] | 632 | return true | 
|  | 633 | } | 
|  | 634 |  | 
|  | 635 | return false | 
|  | 636 | }) | 
|  | 637 |  | 
| Paul Duffin | 3bae068 | 2021-05-05 18:03:47 +0100 | [diff] [blame] | 638 | // Create properties for deapexer module. | 
|  | 639 | deapexerProperties := &DeapexerProperties{ | 
| Paul Duffin | b508405 | 2021-06-07 10:25:31 +0100 | [diff] [blame] | 640 | // Remove any duplicates from the common modules lists as a module may be included via a direct | 
| Paul Duffin | 3bae068 | 2021-05-05 18:03:47 +0100 | [diff] [blame] | 641 | // dependency as well as transitive ones. | 
| Paul Duffin | b508405 | 2021-06-07 10:25:31 +0100 | [diff] [blame] | 642 | CommonModules: android.SortedUniqueStrings(commonModules), | 
| Paul Duffin | 3bae068 | 2021-05-05 18:03:47 +0100 | [diff] [blame] | 643 | } | 
|  | 644 |  | 
|  | 645 | // Populate the exported files property in a fixed order. | 
| Paul Duffin | 034196d | 2021-06-17 15:59:07 +0100 | [diff] [blame] | 646 | deapexerProperties.ExportedFiles = android.SortedUniqueStrings(exportedFiles) | 
| Paul Duffin | 57f8359 | 2021-05-05 15:09:44 +0100 | [diff] [blame] | 647 |  | 
| Paul Duffin | 11216db | 2021-03-01 14:14:52 +0000 | [diff] [blame] | 648 | props := struct { | 
|  | 649 | Name          *string | 
|  | 650 | Selected_apex *string | 
|  | 651 | }{ | 
|  | 652 | Name:          proptools.StringPtr(deapexerName), | 
|  | 653 | Selected_apex: proptools.StringPtr(apexFileSource), | 
|  | 654 | } | 
|  | 655 | ctx.CreateModule(privateDeapexerFactory, | 
|  | 656 | &props, | 
|  | 657 | deapexerProperties, | 
|  | 658 | ) | 
|  | 659 | } | 
|  | 660 |  | 
| Paul Duffin | 11216db | 2021-03-01 14:14:52 +0000 | [diff] [blame] | 661 | func apexSelectorModuleName(baseModuleName string) string { | 
|  | 662 | return baseModuleName + ".apex.selector" | 
|  | 663 | } | 
|  | 664 |  | 
| Paul Duffin | 064b70c | 2020-11-02 17:32:38 +0000 | [diff] [blame] | 665 | func prebuiltApexExportedModuleName(ctx android.BottomUpMutatorContext, name string) string { | 
|  | 666 | // The prebuilt_apex should be depending on prebuilt modules but as this runs after | 
|  | 667 | // prebuilt_rename the prebuilt module may or may not be using the prebuilt_ prefixed named. So, | 
|  | 668 | // check to see if the prefixed name is in use first, if it is then use that, otherwise assume | 
|  | 669 | // the unprefixed name is the one to use. If the unprefixed one turns out to be a source module | 
|  | 670 | // and not a renamed prebuilt module then that will be detected and reported as an error when | 
|  | 671 | // processing the dependency in ApexInfoMutator(). | 
| Paul Duffin | 864116c | 2021-04-02 10:24:13 +0100 | [diff] [blame] | 672 | prebuiltName := android.PrebuiltNameFromSource(name) | 
| Paul Duffin | 064b70c | 2020-11-02 17:32:38 +0000 | [diff] [blame] | 673 | if ctx.OtherModuleExists(prebuiltName) { | 
|  | 674 | name = prebuiltName | 
|  | 675 | } | 
|  | 676 | return name | 
|  | 677 | } | 
|  | 678 |  | 
| Paul Duffin | a713942 | 2021-02-08 11:01:58 +0000 | [diff] [blame] | 679 | type exportedDependencyTag struct { | 
|  | 680 | blueprint.BaseDependencyTag | 
|  | 681 | name string | 
|  | 682 | } | 
|  | 683 |  | 
|  | 684 | // Mark this tag so dependencies that use it are excluded from visibility enforcement. | 
|  | 685 | // | 
|  | 686 | // This does allow any prebuilt_apex to reference any module which does open up a small window for | 
|  | 687 | // restricted visibility modules to be referenced from the wrong prebuilt_apex. However, doing so | 
|  | 688 | // avoids opening up a much bigger window by widening the visibility of modules that need files | 
|  | 689 | // provided by the prebuilt_apex to include all the possible locations they may be defined, which | 
|  | 690 | // could include everything below vendor/. | 
|  | 691 | // | 
|  | 692 | // A prebuilt_apex that references a module via this tag will have to contain the appropriate files | 
|  | 693 | // corresponding to that module, otherwise it will fail when attempting to retrieve the files from | 
|  | 694 | // the .apex file. It will also have to be included in the module's apex_available property too. | 
|  | 695 | // That makes it highly unlikely that a prebuilt_apex would reference a restricted module | 
|  | 696 | // incorrectly. | 
|  | 697 | func (t exportedDependencyTag) ExcludeFromVisibilityEnforcement() {} | 
|  | 698 |  | 
| Paul Duffin | 7db57e0 | 2021-06-17 14:56:05 +0100 | [diff] [blame] | 699 | func (t exportedDependencyTag) RequiresFilesFromPrebuiltApex() {} | 
|  | 700 |  | 
|  | 701 | var _ android.RequiresFilesFromPrebuiltApexTag = exportedDependencyTag{} | 
|  | 702 |  | 
| Paul Duffin | a713942 | 2021-02-08 11:01:58 +0000 | [diff] [blame] | 703 | var ( | 
| Jiakai Zhang | 774dd30 | 2021-09-26 03:54:25 +0000 | [diff] [blame] | 704 | exportedJavaLibTag                       = exportedDependencyTag{name: "exported_java_libs"} | 
|  | 705 | exportedBootclasspathFragmentTag         = exportedDependencyTag{name: "exported_bootclasspath_fragments"} | 
|  | 706 | exportedSystemserverclasspathFragmentTag = exportedDependencyTag{name: "exported_systemserverclasspath_fragments"} | 
| Paul Duffin | a713942 | 2021-02-08 11:01:58 +0000 | [diff] [blame] | 707 | ) | 
|  | 708 |  | 
| Paul Duffin | 5dda3e3 | 2021-05-05 14:13:27 +0100 | [diff] [blame] | 709 | var _ prebuiltApexModuleCreator = (*Prebuilt)(nil) | 
|  | 710 |  | 
|  | 711 | // createPrebuiltApexModules creates modules necessary to export files from the prebuilt apex to the | 
|  | 712 | // build. | 
|  | 713 | // | 
|  | 714 | // If this needs to make files from within a `.apex` file available for use by other Soong modules, | 
|  | 715 | // e.g. make dex implementation jars available for java_import modules listed in exported_java_libs, | 
|  | 716 | // it does so as follows: | 
|  | 717 | // | 
| Colin Cross | d079e0b | 2022-08-16 10:27:33 -0700 | [diff] [blame] | 718 | //  1. It creates a `deapexer` module that actually extracts the files from the `.apex` file and | 
|  | 719 | //     makes them available for use by other modules, at both Soong and ninja levels. | 
| Paul Duffin | 5dda3e3 | 2021-05-05 14:13:27 +0100 | [diff] [blame] | 720 | // | 
| Colin Cross | d079e0b | 2022-08-16 10:27:33 -0700 | [diff] [blame] | 721 | //  2. It adds a dependency onto those modules and creates an apex specific variant similar to what | 
|  | 722 | //     an `apex` module does. That ensures that code which looks for specific apex variant, e.g. | 
|  | 723 | //     dexpreopt, will work the same way from source and prebuilt. | 
| Paul Duffin | 5dda3e3 | 2021-05-05 14:13:27 +0100 | [diff] [blame] | 724 | // | 
| Colin Cross | d079e0b | 2022-08-16 10:27:33 -0700 | [diff] [blame] | 725 | //  3. The `deapexer` module adds a dependency from the modules that require the exported files onto | 
|  | 726 | //     itself so that they can retrieve the file paths to those files. | 
| Paul Duffin | 5dda3e3 | 2021-05-05 14:13:27 +0100 | [diff] [blame] | 727 | // | 
|  | 728 | // It also creates a child module `selector` that is responsible for selecting the appropriate | 
|  | 729 | // input apex for both the prebuilt_apex and the deapexer. That is needed for a couple of reasons: | 
| Paul Duffin | 5dda3e3 | 2021-05-05 14:13:27 +0100 | [diff] [blame] | 730 | // | 
| Colin Cross | d079e0b | 2022-08-16 10:27:33 -0700 | [diff] [blame] | 731 | //  1. To dedup the selection logic so it only runs in one module. | 
| Paul Duffin | 5dda3e3 | 2021-05-05 14:13:27 +0100 | [diff] [blame] | 732 | // | 
| Colin Cross | d079e0b | 2022-08-16 10:27:33 -0700 | [diff] [blame] | 733 | //  2. To allow the deapexer to be wired up to a different source for the input apex, e.g. an | 
|  | 734 | //     `apex_set`. | 
|  | 735 | // | 
|  | 736 | //     prebuilt_apex | 
|  | 737 | //     /      |      \ | 
|  | 738 | //     /         |         \ | 
|  | 739 | //     V            V            V | 
|  | 740 | //     selector  <---  deapexer  <---  exported java lib | 
| Paul Duffin | 5dda3e3 | 2021-05-05 14:13:27 +0100 | [diff] [blame] | 741 | func (p *Prebuilt) createPrebuiltApexModules(ctx android.TopDownMutatorContext) { | 
|  | 742 | baseModuleName := p.BaseModuleName() | 
|  | 743 |  | 
|  | 744 | apexSelectorModuleName := apexSelectorModuleName(baseModuleName) | 
|  | 745 | createApexSelectorModule(ctx, apexSelectorModuleName, &p.properties.ApexFileProperties) | 
|  | 746 |  | 
|  | 747 | apexFileSource := ":" + apexSelectorModuleName | 
| Jiakai Zhang | 774dd30 | 2021-09-26 03:54:25 +0000 | [diff] [blame] | 748 | p.createDeapexerModuleIfNeeded(ctx, deapexerModuleName(baseModuleName), apexFileSource) | 
| Paul Duffin | 5dda3e3 | 2021-05-05 14:13:27 +0100 | [diff] [blame] | 749 |  | 
|  | 750 | // Add a source reference to retrieve the selected apex from the selector module. | 
| Paul Duffin | bb0dc13 | 2021-05-05 16:58:08 +0100 | [diff] [blame] | 751 | p.prebuiltCommonProperties.Selected_apex = proptools.StringPtr(apexFileSource) | 
| Paul Duffin | 5dda3e3 | 2021-05-05 14:13:27 +0100 | [diff] [blame] | 752 | } | 
|  | 753 |  | 
| Paul Duffin | 57f8359 | 2021-05-05 15:09:44 +0100 | [diff] [blame] | 754 | func (p *Prebuilt) ComponentDepsMutator(ctx android.BottomUpMutatorContext) { | 
|  | 755 | p.prebuiltApexContentsDeps(ctx) | 
| Paul Duffin | 064b70c | 2020-11-02 17:32:38 +0000 | [diff] [blame] | 756 | } | 
|  | 757 |  | 
| Spandan Das | 2069c3f | 2023-12-06 19:40:24 +0000 | [diff] [blame] | 758 | func (p *prebuiltCommon) DepsMutator(ctx android.BottomUpMutatorContext) { | 
|  | 759 | if p.hasExportedDeps() { | 
|  | 760 | // Create a dependency from the prebuilt apex (prebuilt_apex/apex_set) to the internal deapexer module | 
|  | 761 | // The deapexer will return a provider that will be bubbled up to the rdeps of apexes (e.g. dex_bootjars) | 
|  | 762 | ctx.AddDependency(ctx.Module(), android.DeapexerTag, deapexerModuleName(p.BaseModuleName())) | 
|  | 763 | } | 
|  | 764 | } | 
|  | 765 |  | 
| Paul Duffin | 064b70c | 2020-11-02 17:32:38 +0000 | [diff] [blame] | 766 | var _ ApexInfoMutator = (*Prebuilt)(nil) | 
|  | 767 |  | 
| Paul Duffin | 064b70c | 2020-11-02 17:32:38 +0000 | [diff] [blame] | 768 | func (p *Prebuilt) ApexInfoMutator(mctx android.TopDownMutatorContext) { | 
| Paul Duffin | dfd3326 | 2021-04-06 17:02:08 +0100 | [diff] [blame] | 769 | p.apexInfoMutator(mctx) | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 770 | } | 
|  | 771 |  | 
| Spandan Das | da739a3 | 2023-12-13 00:06:32 +0000 | [diff] [blame] | 772 | // Set a provider containing information about the jars and .prof provided by the apex | 
|  | 773 | // Apexes built from prebuilts retrieve this information by visiting its internal deapexer module | 
|  | 774 | // Used by dex_bootjars to generate the boot image | 
|  | 775 | func (p *prebuiltCommon) provideApexExportsInfo(ctx android.ModuleContext) { | 
|  | 776 | if !p.hasExportedDeps() { | 
|  | 777 | // nothing to do | 
|  | 778 | return | 
|  | 779 | } | 
|  | 780 | if di, err := android.FindDeapexerProviderForModule(ctx); err == nil { | 
| Spandan Das | 5be6333 | 2023-12-13 00:06:32 +0000 | [diff] [blame] | 781 | javaModuleToDexPath := map[string]android.Path{} | 
|  | 782 | for _, commonModule := range di.GetExportedModuleNames() { | 
|  | 783 | if dex := di.PrebuiltExportPath(java.ApexRootRelativePathToJavaLib(commonModule)); dex != nil { | 
|  | 784 | javaModuleToDexPath[commonModule] = dex | 
|  | 785 | } | 
|  | 786 | } | 
|  | 787 |  | 
| Spandan Das | da739a3 | 2023-12-13 00:06:32 +0000 | [diff] [blame] | 788 | exports := android.ApexExportsInfo{ | 
| Spandan Das | 5be6333 | 2023-12-13 00:06:32 +0000 | [diff] [blame] | 789 | ApexName:                      p.ApexVariationName(), | 
|  | 790 | ProfilePathOnHost:             di.PrebuiltExportPath(java.ProfileInstallPathInApex), | 
|  | 791 | LibraryNameToDexJarPathOnHost: javaModuleToDexPath, | 
| Spandan Das | da739a3 | 2023-12-13 00:06:32 +0000 | [diff] [blame] | 792 | } | 
|  | 793 | ctx.SetProvider(android.ApexExportsInfoProvider, exports) | 
|  | 794 | } else { | 
|  | 795 | ctx.ModuleErrorf(err.Error()) | 
|  | 796 | } | 
|  | 797 | } | 
|  | 798 |  | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 799 | func (p *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) { | 
| Jooyung Han | 286957d | 2023-10-30 16:17:56 +0900 | [diff] [blame] | 800 | p.apexKeysPath = writeApexKeys(ctx, p) | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 801 | // TODO(jungjw): Check the key validity. | 
| Paul Duffin | bb0dc13 | 2021-05-05 16:58:08 +0100 | [diff] [blame] | 802 | p.inputApex = android.OptionalPathForModuleSrc(ctx, p.prebuiltCommonProperties.Selected_apex).Path() | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 803 | p.installDir = android.PathForModuleInstall(ctx, "apex") | 
|  | 804 | p.installFilename = p.InstallFilename() | 
|  | 805 | if !strings.HasSuffix(p.installFilename, imageApexSuffix) { | 
|  | 806 | ctx.ModuleErrorf("filename should end in %s for prebuilt_apex", imageApexSuffix) | 
|  | 807 | } | 
|  | 808 | p.outputApex = android.PathForModuleOut(ctx, p.installFilename) | 
|  | 809 | ctx.Build(pctx, android.BuildParams{ | 
|  | 810 | Rule:   android.Cp, | 
|  | 811 | Input:  p.inputApex, | 
|  | 812 | Output: p.outputApex, | 
|  | 813 | }) | 
| Jiyong Park | 10e926b | 2020-07-16 21:38:56 +0900 | [diff] [blame] | 814 |  | 
|  | 815 | if p.prebuiltCommon.checkForceDisable(ctx) { | 
| Colin Cross | a9c8c9f | 2020-12-16 10:20:23 -0800 | [diff] [blame] | 816 | p.HideFromMake() | 
| Jiyong Park | 10e926b | 2020-07-16 21:38:56 +0900 | [diff] [blame] | 817 | return | 
|  | 818 | } | 
|  | 819 |  | 
| Spandan Das | 2069c3f | 2023-12-06 19:40:24 +0000 | [diff] [blame] | 820 | // dexpreopt any system server jars if present | 
|  | 821 | p.dexpreoptSystemServerJars(ctx) | 
|  | 822 |  | 
| Spandan Das | da739a3 | 2023-12-13 00:06:32 +0000 | [diff] [blame] | 823 | // provide info used for generating the boot image | 
|  | 824 | p.provideApexExportsInfo(ctx) | 
|  | 825 |  | 
| Paul Duffin | c30aea2 | 2021-06-15 19:10:11 +0100 | [diff] [blame] | 826 | // Save the files that need to be made available to Make. | 
|  | 827 | p.initApexFilesForAndroidMk(ctx) | 
|  | 828 |  | 
| Colin Cross | ccba23d | 2021-11-12 19:01:29 +0000 | [diff] [blame] | 829 | // in case that prebuilt_apex replaces source apex (using prefer: prop) | 
| Jooyung Han | 06a8a1c | 2023-08-23 11:11:43 +0900 | [diff] [blame] | 830 | p.compatSymlinks = makeCompatSymlinks(p.BaseModuleName(), ctx) | 
| Colin Cross | ccba23d | 2021-11-12 19:01:29 +0000 | [diff] [blame] | 831 | // or that prebuilt_apex overrides other apexes (using overrides: prop) | 
|  | 832 | for _, overridden := range p.prebuiltCommonProperties.Overrides { | 
| Jooyung Han | 06a8a1c | 2023-08-23 11:11:43 +0900 | [diff] [blame] | 833 | p.compatSymlinks = append(p.compatSymlinks, makeCompatSymlinks(overridden, ctx)...) | 
| Colin Cross | 6340ea5 | 2021-11-04 12:01:18 -0700 | [diff] [blame] | 834 | } | 
|  | 835 |  | 
|  | 836 | if p.installable() { | 
| Colin Cross | 09ad3a6 | 2023-11-15 12:29:33 -0800 | [diff] [blame] | 837 | p.installedFile = ctx.InstallFile(p.installDir, p.installFilename, p.inputApex, p.compatSymlinks...) | 
| Wei Li | 340ee8e | 2022-03-18 17:33:24 -0700 | [diff] [blame] | 838 | p.provenanceMetaDataFile = provenance.GenerateArtifactProvenanceMetaData(ctx, p.inputApex, p.installedFile) | 
| Jooyung Han | 002ab68 | 2020-01-08 01:57:58 +0900 | [diff] [blame] | 839 | } | 
| Jiyong Park | 09d7752 | 2019-11-18 11:16:27 +0900 | [diff] [blame] | 840 | } | 
|  | 841 |  | 
| Wei Li | 340ee8e | 2022-03-18 17:33:24 -0700 | [diff] [blame] | 842 | func (p *Prebuilt) ProvenanceMetaDataFile() android.OutputPath { | 
|  | 843 | return p.provenanceMetaDataFile | 
|  | 844 | } | 
|  | 845 |  | 
| Paul Duffin | 2470467 | 2021-04-06 16:09:30 +0100 | [diff] [blame] | 846 | // prebuiltApexExtractorModule is a private module type that is only created by the prebuilt_apex | 
|  | 847 | // module. It extracts the correct apex to use and makes it available for use by apex_set. | 
|  | 848 | type prebuiltApexExtractorModule struct { | 
|  | 849 | android.ModuleBase | 
|  | 850 |  | 
|  | 851 | properties ApexExtractorProperties | 
|  | 852 |  | 
|  | 853 | extractedApex android.WritablePath | 
|  | 854 | } | 
|  | 855 |  | 
|  | 856 | func privateApexExtractorModuleFactory() android.Module { | 
|  | 857 | module := &prebuiltApexExtractorModule{} | 
|  | 858 | module.AddProperties( | 
|  | 859 | &module.properties, | 
|  | 860 | ) | 
|  | 861 | android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) | 
|  | 862 | return module | 
|  | 863 | } | 
|  | 864 |  | 
|  | 865 | func (p *prebuiltApexExtractorModule) Srcs() android.Paths { | 
|  | 866 | return android.Paths{p.extractedApex} | 
|  | 867 | } | 
|  | 868 |  | 
|  | 869 | func (p *prebuiltApexExtractorModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { | 
|  | 870 | srcsSupplier := func(ctx android.BaseModuleContext, prebuilt android.Module) []string { | 
|  | 871 | return p.properties.prebuiltSrcs(ctx) | 
|  | 872 | } | 
| Paul Duffin | 76fdd67 | 2022-12-12 18:00:47 +0000 | [diff] [blame] | 873 | defaultAllowPrerelease := ctx.Config().IsEnvTrue("SOONG_ALLOW_PRERELEASE_APEXES") | 
| Paul Duffin | 2470467 | 2021-04-06 16:09:30 +0100 | [diff] [blame] | 874 | apexSet := android.SingleSourcePathFromSupplier(ctx, srcsSupplier, "set") | 
|  | 875 | p.extractedApex = android.PathForModuleOut(ctx, "extracted", apexSet.Base()) | 
| Anton Hansson | 805e0a5 | 2022-11-25 14:06:46 +0000 | [diff] [blame] | 876 | // Filter out NativeBridge archs (b/260115309) | 
|  | 877 | abis := java.SupportedAbis(ctx, true) | 
| Paul Duffin | 2470467 | 2021-04-06 16:09:30 +0100 | [diff] [blame] | 878 | ctx.Build(pctx, | 
|  | 879 | android.BuildParams{ | 
|  | 880 | Rule:        extractMatchingApex, | 
|  | 881 | Description: "Extract an apex from an apex set", | 
|  | 882 | Inputs:      android.Paths{apexSet}, | 
|  | 883 | Output:      p.extractedApex, | 
|  | 884 | Args: map[string]string{ | 
| Anton Hansson | 805e0a5 | 2022-11-25 14:06:46 +0000 | [diff] [blame] | 885 | "abis":              strings.Join(abis, ","), | 
| Paul Duffin | 76fdd67 | 2022-12-12 18:00:47 +0000 | [diff] [blame] | 886 | "allow-prereleased": strconv.FormatBool(proptools.BoolDefault(p.properties.Prerelease, defaultAllowPrerelease)), | 
| Paul Duffin | 2470467 | 2021-04-06 16:09:30 +0100 | [diff] [blame] | 887 | "sdk-version":       ctx.Config().PlatformSdkVersion().String(), | 
| Pranav Gupta | 51645ff | 2023-03-20 16:19:53 -0700 | [diff] [blame] | 888 | "skip-sdk-check":    strconv.FormatBool(ctx.Config().IsEnvTrue("SOONG_SKIP_APPSET_SDK_CHECK")), | 
| Paul Duffin | 2470467 | 2021-04-06 16:09:30 +0100 | [diff] [blame] | 889 | }, | 
|  | 890 | }) | 
|  | 891 | } | 
|  | 892 |  | 
| Jaewoong Jung | fa00c06 | 2020-05-14 14:15:24 -0700 | [diff] [blame] | 893 | type ApexSet struct { | 
| Jiyong Park | 10e926b | 2020-07-16 21:38:56 +0900 | [diff] [blame] | 894 | prebuiltCommon | 
| Jaewoong Jung | fa00c06 | 2020-05-14 14:15:24 -0700 | [diff] [blame] | 895 |  | 
|  | 896 | properties ApexSetProperties | 
| Jaewoong Jung | fa00c06 | 2020-05-14 14:15:24 -0700 | [diff] [blame] | 897 | } | 
|  | 898 |  | 
| Paul Duffin | 2470467 | 2021-04-06 16:09:30 +0100 | [diff] [blame] | 899 | type ApexExtractorProperties struct { | 
| Jaewoong Jung | fa00c06 | 2020-05-14 14:15:24 -0700 | [diff] [blame] | 900 | // the .apks file path that contains prebuilt apex files to be extracted. | 
| Pranav Gupta | eba03b0 | 2022-09-27 00:27:08 +0000 | [diff] [blame] | 901 | Set *string `android:"path"` | 
| Jaewoong Jung | fa00c06 | 2020-05-14 14:15:24 -0700 | [diff] [blame] | 902 |  | 
| Evgenii Stepanov | 2080bfe | 2020-07-24 15:35:40 -0700 | [diff] [blame] | 903 | Sanitized struct { | 
|  | 904 | None struct { | 
| Pranav Gupta | eba03b0 | 2022-09-27 00:27:08 +0000 | [diff] [blame] | 905 | Set *string `android:"path"` | 
| Evgenii Stepanov | 2080bfe | 2020-07-24 15:35:40 -0700 | [diff] [blame] | 906 | } | 
|  | 907 | Address struct { | 
| Pranav Gupta | eba03b0 | 2022-09-27 00:27:08 +0000 | [diff] [blame] | 908 | Set *string `android:"path"` | 
| Evgenii Stepanov | 2080bfe | 2020-07-24 15:35:40 -0700 | [diff] [blame] | 909 | } | 
|  | 910 | Hwaddress struct { | 
| Pranav Gupta | eba03b0 | 2022-09-27 00:27:08 +0000 | [diff] [blame] | 911 | Set *string `android:"path"` | 
| Evgenii Stepanov | 2080bfe | 2020-07-24 15:35:40 -0700 | [diff] [blame] | 912 | } | 
|  | 913 | } | 
|  | 914 |  | 
| Paul Duffin | 2470467 | 2021-04-06 16:09:30 +0100 | [diff] [blame] | 915 | // apexes in this set use prerelease SDK version | 
|  | 916 | Prerelease *bool | 
|  | 917 | } | 
|  | 918 |  | 
|  | 919 | func (e *ApexExtractorProperties) prebuiltSrcs(ctx android.BaseModuleContext) []string { | 
|  | 920 | var srcs []string | 
|  | 921 | if e.Set != nil { | 
|  | 922 | srcs = append(srcs, *e.Set) | 
|  | 923 | } | 
|  | 924 |  | 
| Jooyung Han | 8d4a1f0 | 2023-08-23 13:54:08 +0900 | [diff] [blame] | 925 | sanitizers := ctx.Config().SanitizeDevice() | 
| Paul Duffin | 2470467 | 2021-04-06 16:09:30 +0100 | [diff] [blame] | 926 |  | 
|  | 927 | if android.InList("address", sanitizers) && e.Sanitized.Address.Set != nil { | 
|  | 928 | srcs = append(srcs, *e.Sanitized.Address.Set) | 
|  | 929 | } else if android.InList("hwaddress", sanitizers) && e.Sanitized.Hwaddress.Set != nil { | 
|  | 930 | srcs = append(srcs, *e.Sanitized.Hwaddress.Set) | 
|  | 931 | } else if e.Sanitized.None.Set != nil { | 
|  | 932 | srcs = append(srcs, *e.Sanitized.None.Set) | 
|  | 933 | } | 
|  | 934 |  | 
|  | 935 | return srcs | 
|  | 936 | } | 
|  | 937 |  | 
|  | 938 | type ApexSetProperties struct { | 
|  | 939 | ApexExtractorProperties | 
|  | 940 |  | 
| Paul Duffin | ef6b695 | 2021-06-15 11:34:01 +0100 | [diff] [blame] | 941 | PrebuiltCommonProperties | 
| Evgenii Stepanov | 2080bfe | 2020-07-24 15:35:40 -0700 | [diff] [blame] | 942 | } | 
|  | 943 |  | 
|  | 944 | func (a *ApexSet) hasSanitizedSource(sanitizer string) bool { | 
|  | 945 | if sanitizer == "address" { | 
|  | 946 | return a.properties.Sanitized.Address.Set != nil | 
|  | 947 | } | 
|  | 948 | if sanitizer == "hwaddress" { | 
|  | 949 | return a.properties.Sanitized.Hwaddress.Set != nil | 
|  | 950 | } | 
|  | 951 |  | 
|  | 952 | return false | 
|  | 953 | } | 
|  | 954 |  | 
| Paul Duffin | 4f2282c | 2022-12-12 17:44:33 +0000 | [diff] [blame] | 955 | func (a *ApexSet) OutputFiles(tag string) (android.Paths, error) { | 
|  | 956 | switch tag { | 
|  | 957 | case "": | 
|  | 958 | return android.Paths{a.outputApex}, nil | 
|  | 959 | default: | 
|  | 960 | return nil, fmt.Errorf("unsupported module reference tag %q", tag) | 
|  | 961 | } | 
|  | 962 | } | 
|  | 963 |  | 
| Jaewoong Jung | fa00c06 | 2020-05-14 14:15:24 -0700 | [diff] [blame] | 964 | // prebuilt_apex imports an `.apex` file into the build graph as if it was built with apex. | 
|  | 965 | func apexSetFactory() android.Module { | 
|  | 966 | module := &ApexSet{} | 
| Paul Duffin | ef6b695 | 2021-06-15 11:34:01 +0100 | [diff] [blame] | 967 | module.AddProperties(&module.properties) | 
|  | 968 | module.initPrebuiltCommon(module, &module.properties.PrebuiltCommonProperties) | 
| Paul Duffin | 2470467 | 2021-04-06 16:09:30 +0100 | [diff] [blame] | 969 |  | 
| Paul Duffin | 2470467 | 2021-04-06 16:09:30 +0100 | [diff] [blame] | 970 | return module | 
|  | 971 | } | 
|  | 972 |  | 
| Paul Duffin | 5dda3e3 | 2021-05-05 14:13:27 +0100 | [diff] [blame] | 973 | func createApexExtractorModule(ctx android.TopDownMutatorContext, name string, apexExtractorProperties *ApexExtractorProperties) { | 
| Paul Duffin | 2470467 | 2021-04-06 16:09:30 +0100 | [diff] [blame] | 974 | props := struct { | 
|  | 975 | Name *string | 
|  | 976 | }{ | 
|  | 977 | Name: proptools.StringPtr(name), | 
| Evgenii Stepanov | 2080bfe | 2020-07-24 15:35:40 -0700 | [diff] [blame] | 978 | } | 
|  | 979 |  | 
| Paul Duffin | 2470467 | 2021-04-06 16:09:30 +0100 | [diff] [blame] | 980 | ctx.CreateModule(privateApexExtractorModuleFactory, | 
|  | 981 | &props, | 
|  | 982 | apexExtractorProperties, | 
|  | 983 | ) | 
|  | 984 | } | 
|  | 985 |  | 
|  | 986 | func apexExtractorModuleName(baseModuleName string) string { | 
|  | 987 | return baseModuleName + ".apex.extractor" | 
| Jaewoong Jung | fa00c06 | 2020-05-14 14:15:24 -0700 | [diff] [blame] | 988 | } | 
|  | 989 |  | 
| Paul Duffin | 5dda3e3 | 2021-05-05 14:13:27 +0100 | [diff] [blame] | 990 | var _ prebuiltApexModuleCreator = (*ApexSet)(nil) | 
|  | 991 |  | 
|  | 992 | // createPrebuiltApexModules creates modules necessary to export files from the apex set to other | 
|  | 993 | // modules. | 
|  | 994 | // | 
|  | 995 | // This effectively does for apex_set what Prebuilt.createPrebuiltApexModules does for a | 
|  | 996 | // prebuilt_apex except that instead of creating a selector module which selects one .apex file | 
|  | 997 | // from those provided this creates an extractor module which extracts the appropriate .apex file | 
|  | 998 | // from the zip file containing them. | 
|  | 999 | func (a *ApexSet) createPrebuiltApexModules(ctx android.TopDownMutatorContext) { | 
|  | 1000 | baseModuleName := a.BaseModuleName() | 
|  | 1001 |  | 
|  | 1002 | apexExtractorModuleName := apexExtractorModuleName(baseModuleName) | 
|  | 1003 | createApexExtractorModule(ctx, apexExtractorModuleName, &a.properties.ApexExtractorProperties) | 
|  | 1004 |  | 
|  | 1005 | apexFileSource := ":" + apexExtractorModuleName | 
| Jiakai Zhang | 774dd30 | 2021-09-26 03:54:25 +0000 | [diff] [blame] | 1006 | a.createDeapexerModuleIfNeeded(ctx, deapexerModuleName(baseModuleName), apexFileSource) | 
| Paul Duffin | 5dda3e3 | 2021-05-05 14:13:27 +0100 | [diff] [blame] | 1007 |  | 
|  | 1008 | // After passing the arch specific src properties to the creating the apex selector module | 
| Paul Duffin | bb0dc13 | 2021-05-05 16:58:08 +0100 | [diff] [blame] | 1009 | a.prebuiltCommonProperties.Selected_apex = proptools.StringPtr(apexFileSource) | 
| Paul Duffin | 5dda3e3 | 2021-05-05 14:13:27 +0100 | [diff] [blame] | 1010 | } | 
|  | 1011 |  | 
| Paul Duffin | 57f8359 | 2021-05-05 15:09:44 +0100 | [diff] [blame] | 1012 | func (a *ApexSet) ComponentDepsMutator(ctx android.BottomUpMutatorContext) { | 
|  | 1013 | a.prebuiltApexContentsDeps(ctx) | 
| Paul Duffin | f58fd9a | 2021-04-06 16:00:22 +0100 | [diff] [blame] | 1014 | } | 
|  | 1015 |  | 
|  | 1016 | var _ ApexInfoMutator = (*ApexSet)(nil) | 
|  | 1017 |  | 
|  | 1018 | func (a *ApexSet) ApexInfoMutator(mctx android.TopDownMutatorContext) { | 
|  | 1019 | a.apexInfoMutator(mctx) | 
|  | 1020 | } | 
|  | 1021 |  | 
| Jaewoong Jung | fa00c06 | 2020-05-14 14:15:24 -0700 | [diff] [blame] | 1022 | func (a *ApexSet) GenerateAndroidBuildActions(ctx android.ModuleContext) { | 
| Jooyung Han | 286957d | 2023-10-30 16:17:56 +0900 | [diff] [blame] | 1023 | a.apexKeysPath = writeApexKeys(ctx, a) | 
| Jaewoong Jung | fa00c06 | 2020-05-14 14:15:24 -0700 | [diff] [blame] | 1024 | a.installFilename = a.InstallFilename() | 
| Samiul Islam | 7c02e26 | 2021-09-08 17:48:28 +0100 | [diff] [blame] | 1025 | if !strings.HasSuffix(a.installFilename, imageApexSuffix) && !strings.HasSuffix(a.installFilename, imageCapexSuffix) { | 
|  | 1026 | ctx.ModuleErrorf("filename should end in %s or %s for apex_set", imageApexSuffix, imageCapexSuffix) | 
| Jaewoong Jung | fa00c06 | 2020-05-14 14:15:24 -0700 | [diff] [blame] | 1027 | } | 
|  | 1028 |  | 
| Paul Duffin | bb0dc13 | 2021-05-05 16:58:08 +0100 | [diff] [blame] | 1029 | inputApex := android.OptionalPathForModuleSrc(ctx, a.prebuiltCommonProperties.Selected_apex).Path() | 
| Jaewoong Jung | fa00c06 | 2020-05-14 14:15:24 -0700 | [diff] [blame] | 1030 | a.outputApex = android.PathForModuleOut(ctx, a.installFilename) | 
| Paul Duffin | 2470467 | 2021-04-06 16:09:30 +0100 | [diff] [blame] | 1031 | ctx.Build(pctx, android.BuildParams{ | 
|  | 1032 | Rule:   android.Cp, | 
|  | 1033 | Input:  inputApex, | 
|  | 1034 | Output: a.outputApex, | 
|  | 1035 | }) | 
| Jiyong Park | 10e926b | 2020-07-16 21:38:56 +0900 | [diff] [blame] | 1036 |  | 
|  | 1037 | if a.prebuiltCommon.checkForceDisable(ctx) { | 
| Colin Cross | a9c8c9f | 2020-12-16 10:20:23 -0800 | [diff] [blame] | 1038 | a.HideFromMake() | 
| Jiyong Park | 10e926b | 2020-07-16 21:38:56 +0900 | [diff] [blame] | 1039 | return | 
|  | 1040 | } | 
|  | 1041 |  | 
| Spandan Das | 2069c3f | 2023-12-06 19:40:24 +0000 | [diff] [blame] | 1042 | // dexpreopt any system server jars if present | 
|  | 1043 | a.dexpreoptSystemServerJars(ctx) | 
|  | 1044 |  | 
| Spandan Das | da739a3 | 2023-12-13 00:06:32 +0000 | [diff] [blame] | 1045 | // provide info used for generating the boot image | 
|  | 1046 | a.provideApexExportsInfo(ctx) | 
|  | 1047 |  | 
| Paul Duffin | c30aea2 | 2021-06-15 19:10:11 +0100 | [diff] [blame] | 1048 | // Save the files that need to be made available to Make. | 
|  | 1049 | a.initApexFilesForAndroidMk(ctx) | 
|  | 1050 |  | 
| Jaewoong Jung | fa00c06 | 2020-05-14 14:15:24 -0700 | [diff] [blame] | 1051 | a.installDir = android.PathForModuleInstall(ctx, "apex") | 
|  | 1052 | if a.installable() { | 
| Colin Cross | 730e3f6 | 2021-12-08 21:09:04 -0800 | [diff] [blame] | 1053 | a.installedFile = ctx.InstallFile(a.installDir, a.installFilename, a.outputApex) | 
| Jaewoong Jung | fa00c06 | 2020-05-14 14:15:24 -0700 | [diff] [blame] | 1054 | } | 
|  | 1055 |  | 
|  | 1056 | // in case that apex_set replaces source apex (using prefer: prop) | 
| Jooyung Han | 06a8a1c | 2023-08-23 11:11:43 +0900 | [diff] [blame] | 1057 | a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx) | 
| Jaewoong Jung | fa00c06 | 2020-05-14 14:15:24 -0700 | [diff] [blame] | 1058 | // or that apex_set overrides other apexes (using overrides: prop) | 
| Paul Duffin | ef6b695 | 2021-06-15 11:34:01 +0100 | [diff] [blame] | 1059 | for _, overridden := range a.prebuiltCommonProperties.Overrides { | 
| Jooyung Han | 06a8a1c | 2023-08-23 11:11:43 +0900 | [diff] [blame] | 1060 | a.compatSymlinks = append(a.compatSymlinks, makeCompatSymlinks(overridden, ctx)...) | 
| Jaewoong Jung | fa00c06 | 2020-05-14 14:15:24 -0700 | [diff] [blame] | 1061 | } | 
|  | 1062 | } | 
|  | 1063 |  | 
| Paul Duffin | ef6b695 | 2021-06-15 11:34:01 +0100 | [diff] [blame] | 1064 | type systemExtContext struct { | 
|  | 1065 | android.ModuleContext | 
|  | 1066 | } | 
|  | 1067 |  | 
|  | 1068 | func (*systemExtContext) SystemExtSpecific() bool { | 
|  | 1069 | return true | 
| Jaewoong Jung | fa00c06 | 2020-05-14 14:15:24 -0700 | [diff] [blame] | 1070 | } |