1*9e965d6fSRomain Jobredeaux# Copyright 2020 The Bazel Authors. All rights reserved. 2*9e965d6fSRomain Jobredeaux# 3*9e965d6fSRomain Jobredeaux# Licensed under the Apache License, Version 2.0 (the "License"); 4*9e965d6fSRomain Jobredeaux# you may not use this file except in compliance with the License. 5*9e965d6fSRomain Jobredeaux# You may obtain a copy of the License at 6*9e965d6fSRomain Jobredeaux# 7*9e965d6fSRomain Jobredeaux# http://www.apache.org/licenses/LICENSE-2.0 8*9e965d6fSRomain Jobredeaux# 9*9e965d6fSRomain Jobredeaux# Unless required by applicable law or agreed to in writing, software 10*9e965d6fSRomain Jobredeaux# distributed under the License is distributed on an "AS IS" BASIS, 11*9e965d6fSRomain Jobredeaux# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*9e965d6fSRomain Jobredeaux# See the License for the specific language governing permissions and 13*9e965d6fSRomain Jobredeaux# limitations under the License. 14*9e965d6fSRomain Jobredeaux 15*9e965d6fSRomain Jobredeaux"""Bazel Android Proguard library for the Android rules.""" 16*9e965d6fSRomain Jobredeaux 17*9e965d6fSRomain Jobredeauxload(":android_neverlink_aspect.bzl", "StarlarkAndroidNeverlinkInfo") 18*9e965d6fSRomain Jobredeauxload(":baseline_profiles.bzl", _baseline_profiles = "baseline_profiles") 19*9e965d6fSRomain Jobredeauxload(":common.bzl", "common") 20*9e965d6fSRomain Jobredeauxload(":java.bzl", "java") 21*9e965d6fSRomain Jobredeauxload(":utils.bzl", "ANDROID_TOOLCHAIN_TYPE", "get_android_sdk", "utils") 22*9e965d6fSRomain Jobredeaux 23*9e965d6fSRomain Jobredeaux_ProguardSpecContextInfo = provider( 24*9e965d6fSRomain Jobredeaux doc = "Contains data from processing Proguard specs.", 25*9e965d6fSRomain Jobredeaux fields = dict( 26*9e965d6fSRomain Jobredeaux proguard_configs = "The direct proguard configs", 27*9e965d6fSRomain Jobredeaux transitive_proguard_configs = 28*9e965d6fSRomain Jobredeaux "The proguard configs within the transitive closure of the target", 29*9e965d6fSRomain Jobredeaux providers = "The list of all providers to propagate.", 30*9e965d6fSRomain Jobredeaux ), 31*9e965d6fSRomain Jobredeaux) 32*9e965d6fSRomain Jobredeaux 33*9e965d6fSRomain Jobredeauxdef _validate_proguard_spec( 34*9e965d6fSRomain Jobredeaux ctx, 35*9e965d6fSRomain Jobredeaux out_validated_proguard_spec, 36*9e965d6fSRomain Jobredeaux proguard_spec, 37*9e965d6fSRomain Jobredeaux proguard_allowlister): 38*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 39*9e965d6fSRomain Jobredeaux args.add("--path", proguard_spec) 40*9e965d6fSRomain Jobredeaux args.add("--output", out_validated_proguard_spec) 41*9e965d6fSRomain Jobredeaux 42*9e965d6fSRomain Jobredeaux ctx.actions.run( 43*9e965d6fSRomain Jobredeaux executable = proguard_allowlister, 44*9e965d6fSRomain Jobredeaux arguments = [args], 45*9e965d6fSRomain Jobredeaux inputs = [proguard_spec], 46*9e965d6fSRomain Jobredeaux outputs = [out_validated_proguard_spec], 47*9e965d6fSRomain Jobredeaux mnemonic = "ValidateProguard", 48*9e965d6fSRomain Jobredeaux progress_message = ( 49*9e965d6fSRomain Jobredeaux "Validating proguard configuration %s" % proguard_spec.short_path 50*9e965d6fSRomain Jobredeaux ), 51*9e965d6fSRomain Jobredeaux toolchain = ANDROID_TOOLCHAIN_TYPE, 52*9e965d6fSRomain Jobredeaux ) 53*9e965d6fSRomain Jobredeaux 54*9e965d6fSRomain Jobredeauxdef _process_specs( 55*9e965d6fSRomain Jobredeaux ctx, 56*9e965d6fSRomain Jobredeaux proguard_configs = [], 57*9e965d6fSRomain Jobredeaux proguard_spec_providers = [], 58*9e965d6fSRomain Jobredeaux proguard_allowlister = None): 59*9e965d6fSRomain Jobredeaux """Processes Proguard Specs 60*9e965d6fSRomain Jobredeaux 61*9e965d6fSRomain Jobredeaux Args: 62*9e965d6fSRomain Jobredeaux ctx: The context. 63*9e965d6fSRomain Jobredeaux proguard_configs: sequence of Files. A list of proguard config files to be 64*9e965d6fSRomain Jobredeaux processed. Optional. 65*9e965d6fSRomain Jobredeaux proguard_spec_providers: sequence of ProguardSpecProvider providers. A 66*9e965d6fSRomain Jobredeaux list of providers from the dependencies, exports, plugins, 67*9e965d6fSRomain Jobredeaux exported_plugins, etc. Optional. 68*9e965d6fSRomain Jobredeaux proguard_allowlister: The proguard_allowlister exeutable provider. 69*9e965d6fSRomain Jobredeaux 70*9e965d6fSRomain Jobredeaux Returns: 71*9e965d6fSRomain Jobredeaux A _ProguardSpecContextInfo provider. 72*9e965d6fSRomain Jobredeaux """ 73*9e965d6fSRomain Jobredeaux 74*9e965d6fSRomain Jobredeaux # TODO(djwhang): Look to see if this can be just a validation action and the 75*9e965d6fSRomain Jobredeaux # proguard_spec provided by the rule can be propagated. 76*9e965d6fSRomain Jobredeaux validated_proguard_configs = [] 77*9e965d6fSRomain Jobredeaux for proguard_spec in proguard_configs: 78*9e965d6fSRomain Jobredeaux validated_proguard_spec = ctx.actions.declare_file( 79*9e965d6fSRomain Jobredeaux "validated_proguard/%s/%s_valid" % 80*9e965d6fSRomain Jobredeaux (ctx.label.name, proguard_spec.path), 81*9e965d6fSRomain Jobredeaux ) 82*9e965d6fSRomain Jobredeaux _validate_proguard_spec( 83*9e965d6fSRomain Jobredeaux ctx, 84*9e965d6fSRomain Jobredeaux validated_proguard_spec, 85*9e965d6fSRomain Jobredeaux proguard_spec, 86*9e965d6fSRomain Jobredeaux proguard_allowlister, 87*9e965d6fSRomain Jobredeaux ) 88*9e965d6fSRomain Jobredeaux validated_proguard_configs.append(validated_proguard_spec) 89*9e965d6fSRomain Jobredeaux 90*9e965d6fSRomain Jobredeaux transitive_validated_proguard_configs = [] 91*9e965d6fSRomain Jobredeaux for info in proguard_spec_providers: 92*9e965d6fSRomain Jobredeaux transitive_validated_proguard_configs.append(info.specs) 93*9e965d6fSRomain Jobredeaux 94*9e965d6fSRomain Jobredeaux transitive_proguard_configs = depset( 95*9e965d6fSRomain Jobredeaux validated_proguard_configs, 96*9e965d6fSRomain Jobredeaux transitive = transitive_validated_proguard_configs, 97*9e965d6fSRomain Jobredeaux order = "preorder", 98*9e965d6fSRomain Jobredeaux ) 99*9e965d6fSRomain Jobredeaux return _ProguardSpecContextInfo( 100*9e965d6fSRomain Jobredeaux proguard_configs = proguard_configs, 101*9e965d6fSRomain Jobredeaux transitive_proguard_configs = transitive_proguard_configs, 102*9e965d6fSRomain Jobredeaux providers = [ 103*9e965d6fSRomain Jobredeaux ProguardSpecProvider(transitive_proguard_configs), 104*9e965d6fSRomain Jobredeaux # TODO(b/152659272): Remove this once the android_archive rule is 105*9e965d6fSRomain Jobredeaux # able to process a transitive closure of deps to produce an aar. 106*9e965d6fSRomain Jobredeaux AndroidProguardInfo(proguard_configs), 107*9e965d6fSRomain Jobredeaux ], 108*9e965d6fSRomain Jobredeaux ) 109*9e965d6fSRomain Jobredeaux 110*9e965d6fSRomain Jobredeauxdef _collect_transitive_proguard_specs( 111*9e965d6fSRomain Jobredeaux specs_to_include, 112*9e965d6fSRomain Jobredeaux local_proguard_specs, 113*9e965d6fSRomain Jobredeaux proguard_deps): 114*9e965d6fSRomain Jobredeaux if len(local_proguard_specs) == 0: 115*9e965d6fSRomain Jobredeaux return [] 116*9e965d6fSRomain Jobredeaux 117*9e965d6fSRomain Jobredeaux proguard_specs = depset( 118*9e965d6fSRomain Jobredeaux local_proguard_specs + specs_to_include, 119*9e965d6fSRomain Jobredeaux transitive = [dep.specs for dep in proguard_deps], 120*9e965d6fSRomain Jobredeaux ) 121*9e965d6fSRomain Jobredeaux return sorted(proguard_specs.to_list()) 122*9e965d6fSRomain Jobredeaux 123*9e965d6fSRomain Jobredeauxdef _get_proguard_specs( 124*9e965d6fSRomain Jobredeaux ctx, 125*9e965d6fSRomain Jobredeaux resource_proguard_config, 126*9e965d6fSRomain Jobredeaux proguard_specs_for_manifest = []): 127*9e965d6fSRomain Jobredeaux proguard_deps = utils.collect_providers(ProguardSpecProvider, utils.dedupe_split_attr(ctx.split_attr.deps)) 128*9e965d6fSRomain Jobredeaux if ctx.configuration.coverage_enabled and hasattr(ctx.attr, "_jacoco_runtime"): 129*9e965d6fSRomain Jobredeaux proguard_deps.append(ctx.attr._jacoco_runtime[ProguardSpecProvider]) 130*9e965d6fSRomain Jobredeaux 131*9e965d6fSRomain Jobredeaux local_proguard_specs = [] 132*9e965d6fSRomain Jobredeaux if ctx.files.proguard_specs: 133*9e965d6fSRomain Jobredeaux local_proguard_specs = ctx.files.proguard_specs 134*9e965d6fSRomain Jobredeaux proguard_specs = _collect_transitive_proguard_specs( 135*9e965d6fSRomain Jobredeaux [resource_proguard_config], 136*9e965d6fSRomain Jobredeaux local_proguard_specs, 137*9e965d6fSRomain Jobredeaux proguard_deps, 138*9e965d6fSRomain Jobredeaux ) 139*9e965d6fSRomain Jobredeaux 140*9e965d6fSRomain Jobredeaux if len(proguard_specs) > 0 and ctx.fragments.android.assume_min_sdk_version: 141*9e965d6fSRomain Jobredeaux # NB: Order here is important. We're including generated Proguard specs before the user's 142*9e965d6fSRomain Jobredeaux # specs so that they can override values. 143*9e965d6fSRomain Jobredeaux proguard_specs = proguard_specs_for_manifest + proguard_specs 144*9e965d6fSRomain Jobredeaux 145*9e965d6fSRomain Jobredeaux return proguard_specs 146*9e965d6fSRomain Jobredeaux 147*9e965d6fSRomain Jobredeauxdef _generate_min_sdk_version_assumevalues( 148*9e965d6fSRomain Jobredeaux ctx, 149*9e965d6fSRomain Jobredeaux output = None, 150*9e965d6fSRomain Jobredeaux manifest = None, 151*9e965d6fSRomain Jobredeaux generate_exec = None): 152*9e965d6fSRomain Jobredeaux """Reads the minSdkVersion from an AndroidManifest to generate Proguard specs.""" 153*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 154*9e965d6fSRomain Jobredeaux inputs = [] 155*9e965d6fSRomain Jobredeaux outputs = [] 156*9e965d6fSRomain Jobredeaux 157*9e965d6fSRomain Jobredeaux args.add("--manifest", manifest) 158*9e965d6fSRomain Jobredeaux inputs.append(manifest) 159*9e965d6fSRomain Jobredeaux 160*9e965d6fSRomain Jobredeaux args.add("--output", output) 161*9e965d6fSRomain Jobredeaux outputs.append(output) 162*9e965d6fSRomain Jobredeaux 163*9e965d6fSRomain Jobredeaux ctx.actions.run( 164*9e965d6fSRomain Jobredeaux inputs = inputs, 165*9e965d6fSRomain Jobredeaux outputs = outputs, 166*9e965d6fSRomain Jobredeaux executable = generate_exec, 167*9e965d6fSRomain Jobredeaux arguments = [args], 168*9e965d6fSRomain Jobredeaux mnemonic = "MinSdkVersionAssumeValuesProguardSpecGenerator", 169*9e965d6fSRomain Jobredeaux progress_message = "Adding -assumevalues spec for minSdkVersion", 170*9e965d6fSRomain Jobredeaux ) 171*9e965d6fSRomain Jobredeaux 172*9e965d6fSRomain Jobredeauxdef _optimization_action( 173*9e965d6fSRomain Jobredeaux ctx, 174*9e965d6fSRomain Jobredeaux output_jar, 175*9e965d6fSRomain Jobredeaux program_jar, 176*9e965d6fSRomain Jobredeaux library_jar, 177*9e965d6fSRomain Jobredeaux proguard_specs, 178*9e965d6fSRomain Jobredeaux proguard_mapping = None, 179*9e965d6fSRomain Jobredeaux proguard_output_map = None, 180*9e965d6fSRomain Jobredeaux proguard_seeds = None, 181*9e965d6fSRomain Jobredeaux proguard_usage = None, 182*9e965d6fSRomain Jobredeaux proguard_config_output = None, 183*9e965d6fSRomain Jobredeaux startup_profile = None, 184*9e965d6fSRomain Jobredeaux startup_profile_rewritten = None, 185*9e965d6fSRomain Jobredeaux baseline_profile = None, 186*9e965d6fSRomain Jobredeaux baseline_profile_rewritten = None, 187*9e965d6fSRomain Jobredeaux runtype = None, 188*9e965d6fSRomain Jobredeaux last_stage_output = None, 189*9e965d6fSRomain Jobredeaux next_stage_output = None, 190*9e965d6fSRomain Jobredeaux final = False, 191*9e965d6fSRomain Jobredeaux mnemonic = None, 192*9e965d6fSRomain Jobredeaux progress_message = None, 193*9e965d6fSRomain Jobredeaux proguard_tool = None): 194*9e965d6fSRomain Jobredeaux """Creates a Proguard optimization action. 195*9e965d6fSRomain Jobredeaux 196*9e965d6fSRomain Jobredeaux This method is expected to be called one or more times to create Proguard optimization actions. 197*9e965d6fSRomain Jobredeaux Most outputs will only be generated by the final optimization action, and should otherwise be 198*9e965d6fSRomain Jobredeaux set to None. For the final action set `final = True` which will register the output_jar as an 199*9e965d6fSRomain Jobredeaux output of the action. 200*9e965d6fSRomain Jobredeaux 201*9e965d6fSRomain Jobredeaux TODO(b/286955442): Support baseline profiles. 202*9e965d6fSRomain Jobredeaux 203*9e965d6fSRomain Jobredeaux Args: 204*9e965d6fSRomain Jobredeaux ctx: The context. 205*9e965d6fSRomain Jobredeaux output_jar: File. The final output jar. 206*9e965d6fSRomain Jobredeaux program_jar: File. The jar to be optimized. 207*9e965d6fSRomain Jobredeaux library_jar: File. The merged library jar. While the underlying tooling supports multiple 208*9e965d6fSRomain Jobredeaux library jars, we merge these into a single jar before processing. 209*9e965d6fSRomain Jobredeaux proguard_specs: Sequence of files. A list of proguard specs to use for the optimization. 210*9e965d6fSRomain Jobredeaux proguard_mapping: File. Optional file to be used as a mapping for proguard. A mapping file 211*9e965d6fSRomain Jobredeaux generated by proguard_generate_mapping to be re-used to apply the same map to a new build. 212*9e965d6fSRomain Jobredeaux proguard_output_map: File. Optional file to be used to write the output map of obfuscated 213*9e965d6fSRomain Jobredeaux class and member names. 214*9e965d6fSRomain Jobredeaux proguard_seeds: File. Optional file used to write the "seeds", which is a list of all 215*9e965d6fSRomain Jobredeaux classes and members which match a keep rule. 216*9e965d6fSRomain Jobredeaux proguard_usage: File. Optional file used to write all classes and members that are removed 217*9e965d6fSRomain Jobredeaux during shrinking (i.e. unused code). 218*9e965d6fSRomain Jobredeaux proguard_config_output: File. Optional file used to write the entire configuration that has 219*9e965d6fSRomain Jobredeaux been parsed, included files and replaced variables. Useful for debugging. 220*9e965d6fSRomain Jobredeaux startup_profile: File. Optional. The merged startup profile to be optimized. 221*9e965d6fSRomain Jobredeaux startup_profile_rewritten: File. Optional file used to write the optimized startup profile. 222*9e965d6fSRomain Jobredeaux baseline_profile: File. Optional. The merged baseline profile to be optimized. 223*9e965d6fSRomain Jobredeaux baseline_profile_rewritten: File. Optional file used to write the optimized profile rules. 224*9e965d6fSRomain Jobredeaux runtype: String. Optional string identifying this run. One of [INITIAL, OPTIMIZATION, FINAL] 225*9e965d6fSRomain Jobredeaux last_stage_output: File. Optional input file to this optimization stage, which was output by 226*9e965d6fSRomain Jobredeaux the previous optimization stage. 227*9e965d6fSRomain Jobredeaux next_stage_output: File. Optional output file from this optimization stage, which will be 228*9e965d6fSRomain Jobredeaux consunmed by the next optimization stage. 229*9e965d6fSRomain Jobredeaux final: Boolean. Whether this is the final optimization stage, which will register output_jar 230*9e965d6fSRomain Jobredeaux as an output of this action. 231*9e965d6fSRomain Jobredeaux mnemonic: String. Action mnemonic. 232*9e965d6fSRomain Jobredeaux progress_message: String. Action progress message. 233*9e965d6fSRomain Jobredeaux proguard_tool: FilesToRunProvider. The proguard tool to execute. 234*9e965d6fSRomain Jobredeaux 235*9e965d6fSRomain Jobredeaux Returns: 236*9e965d6fSRomain Jobredeaux None 237*9e965d6fSRomain Jobredeaux """ 238*9e965d6fSRomain Jobredeaux 239*9e965d6fSRomain Jobredeaux inputs = [] 240*9e965d6fSRomain Jobredeaux outputs = [] 241*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 242*9e965d6fSRomain Jobredeaux 243*9e965d6fSRomain Jobredeaux args.add("-forceprocessing") 244*9e965d6fSRomain Jobredeaux 245*9e965d6fSRomain Jobredeaux args.add("-injars", program_jar) 246*9e965d6fSRomain Jobredeaux inputs.append(program_jar) 247*9e965d6fSRomain Jobredeaux 248*9e965d6fSRomain Jobredeaux args.add("-outjars", output_jar) 249*9e965d6fSRomain Jobredeaux if final: 250*9e965d6fSRomain Jobredeaux outputs.append(output_jar) 251*9e965d6fSRomain Jobredeaux 252*9e965d6fSRomain Jobredeaux args.add("-libraryjars", library_jar) 253*9e965d6fSRomain Jobredeaux inputs.append(library_jar) 254*9e965d6fSRomain Jobredeaux 255*9e965d6fSRomain Jobredeaux if proguard_mapping: 256*9e965d6fSRomain Jobredeaux args.add("-applymapping", proguard_mapping) 257*9e965d6fSRomain Jobredeaux inputs.append(proguard_mapping) 258*9e965d6fSRomain Jobredeaux 259*9e965d6fSRomain Jobredeaux args.add_all(proguard_specs, format_each = "@%s") 260*9e965d6fSRomain Jobredeaux inputs.extend(proguard_specs) 261*9e965d6fSRomain Jobredeaux 262*9e965d6fSRomain Jobredeaux if proguard_output_map: 263*9e965d6fSRomain Jobredeaux args.add("-printmapping", proguard_output_map) 264*9e965d6fSRomain Jobredeaux outputs.append(proguard_output_map) 265*9e965d6fSRomain Jobredeaux 266*9e965d6fSRomain Jobredeaux if proguard_seeds: 267*9e965d6fSRomain Jobredeaux args.add("-printseeds", proguard_seeds) 268*9e965d6fSRomain Jobredeaux outputs.append(proguard_seeds) 269*9e965d6fSRomain Jobredeaux 270*9e965d6fSRomain Jobredeaux if proguard_usage: 271*9e965d6fSRomain Jobredeaux args.add("-printusage", proguard_usage) 272*9e965d6fSRomain Jobredeaux outputs.append(proguard_usage) 273*9e965d6fSRomain Jobredeaux 274*9e965d6fSRomain Jobredeaux if proguard_config_output: 275*9e965d6fSRomain Jobredeaux args.add("-printconfiguration", proguard_config_output) 276*9e965d6fSRomain Jobredeaux outputs.append(proguard_config_output) 277*9e965d6fSRomain Jobredeaux 278*9e965d6fSRomain Jobredeaux if startup_profile: 279*9e965d6fSRomain Jobredeaux args.add("-startupprofile", startup_profile) 280*9e965d6fSRomain Jobredeaux inputs.append(startup_profile) 281*9e965d6fSRomain Jobredeaux 282*9e965d6fSRomain Jobredeaux if startup_profile_rewritten: 283*9e965d6fSRomain Jobredeaux args.add("-printstartupprofile", startup_profile) 284*9e965d6fSRomain Jobredeaux outputs.append(startup_profile_rewritten) 285*9e965d6fSRomain Jobredeaux 286*9e965d6fSRomain Jobredeaux if baseline_profile: 287*9e965d6fSRomain Jobredeaux args.add("-baselineprofile", baseline_profile) 288*9e965d6fSRomain Jobredeaux inputs.append(baseline_profile) 289*9e965d6fSRomain Jobredeaux 290*9e965d6fSRomain Jobredeaux if baseline_profile_rewritten: 291*9e965d6fSRomain Jobredeaux args.add("-printbaselineprofile", baseline_profile_rewritten) 292*9e965d6fSRomain Jobredeaux outputs.append(baseline_profile_rewritten) 293*9e965d6fSRomain Jobredeaux 294*9e965d6fSRomain Jobredeaux if runtype: 295*9e965d6fSRomain Jobredeaux args.add("-runtype " + runtype) 296*9e965d6fSRomain Jobredeaux 297*9e965d6fSRomain Jobredeaux if last_stage_output: 298*9e965d6fSRomain Jobredeaux args.add("-laststageoutput", last_stage_output) 299*9e965d6fSRomain Jobredeaux inputs.append(last_stage_output) 300*9e965d6fSRomain Jobredeaux 301*9e965d6fSRomain Jobredeaux if next_stage_output: 302*9e965d6fSRomain Jobredeaux args.add("-nextstageoutput", next_stage_output) 303*9e965d6fSRomain Jobredeaux outputs.append(next_stage_output) 304*9e965d6fSRomain Jobredeaux 305*9e965d6fSRomain Jobredeaux ctx.actions.run( 306*9e965d6fSRomain Jobredeaux outputs = outputs, 307*9e965d6fSRomain Jobredeaux inputs = inputs, 308*9e965d6fSRomain Jobredeaux executable = proguard_tool, 309*9e965d6fSRomain Jobredeaux arguments = [args], 310*9e965d6fSRomain Jobredeaux mnemonic = mnemonic, 311*9e965d6fSRomain Jobredeaux progress_message = progress_message, 312*9e965d6fSRomain Jobredeaux toolchain = None, # TODO(timpeut): correctly set this based off which optimizer is selected 313*9e965d6fSRomain Jobredeaux ) 314*9e965d6fSRomain Jobredeaux 315*9e965d6fSRomain Jobredeauxdef _get_proguard_temp_artifact_with_prefix(ctx, label, prefix, name): 316*9e965d6fSRomain Jobredeaux native_label_name = label.name.removesuffix(common.PACKAGED_RESOURCES_SUFFIX) 317*9e965d6fSRomain Jobredeaux return ctx.actions.declare_file("proguard/" + native_label_name + "/" + prefix + "_" + native_label_name + "_" + name) 318*9e965d6fSRomain Jobredeaux 319*9e965d6fSRomain Jobredeauxdef _get_proguard_temp_artifact(ctx, name): 320*9e965d6fSRomain Jobredeaux return _get_proguard_temp_artifact_with_prefix(ctx, ctx.label, "MIGRATED", name) 321*9e965d6fSRomain Jobredeaux 322*9e965d6fSRomain Jobredeauxdef _get_proguard_output_map(ctx): 323*9e965d6fSRomain Jobredeaux return ctx.actions.declare_file(ctx.label.name.removesuffix(common.PACKAGED_RESOURCES_SUFFIX) + "_proguard_MIGRATED_.map") 324*9e965d6fSRomain Jobredeaux 325*9e965d6fSRomain Jobredeauxdef _apply_proguard( 326*9e965d6fSRomain Jobredeaux ctx, 327*9e965d6fSRomain Jobredeaux input_jar = None, 328*9e965d6fSRomain Jobredeaux proguard_specs = [], 329*9e965d6fSRomain Jobredeaux proguard_optimization_passes = None, 330*9e965d6fSRomain Jobredeaux proguard_mapping = None, 331*9e965d6fSRomain Jobredeaux proguard_output_jar = None, 332*9e965d6fSRomain Jobredeaux proguard_output_map = None, 333*9e965d6fSRomain Jobredeaux proguard_seeds = None, 334*9e965d6fSRomain Jobredeaux proguard_usage = None, 335*9e965d6fSRomain Jobredeaux startup_profile = None, 336*9e965d6fSRomain Jobredeaux baseline_profile = None, 337*9e965d6fSRomain Jobredeaux proguard_tool = None): 338*9e965d6fSRomain Jobredeaux """Top-level method to apply proguard to a jar. 339*9e965d6fSRomain Jobredeaux 340*9e965d6fSRomain Jobredeaux Args: 341*9e965d6fSRomain Jobredeaux ctx: The context 342*9e965d6fSRomain Jobredeaux input_jar: File. The input jar to optimized. 343*9e965d6fSRomain Jobredeaux proguard_specs: List of Files. The proguard specs to use for optimization. 344*9e965d6fSRomain Jobredeaux proguard_optimization_passes: Integer. The number of proguard passes to apply. 345*9e965d6fSRomain Jobredeaux proguard_mapping: File. The proguard mapping to apply. 346*9e965d6fSRomain Jobredeaux proguard_output_jar: File. The output optimized jar. 347*9e965d6fSRomain Jobredeaux proguard_output_map: File. The output proguard map. 348*9e965d6fSRomain Jobredeaux proguard_seeds: File. The output proguard seeds. 349*9e965d6fSRomain Jobredeaux proguard_usage: File. The output proguard usage. 350*9e965d6fSRomain Jobredeaux startup_profile: File. The input merged startup profile to be optimized. 351*9e965d6fSRomain Jobredeaux baseline_profile: File. The input merged baseline profile to be optimized. 352*9e965d6fSRomain Jobredeaux proguard_tool: FilesToRun. The proguard executable. 353*9e965d6fSRomain Jobredeaux 354*9e965d6fSRomain Jobredeaux Returns: 355*9e965d6fSRomain Jobredeaux A struct of proguard outputs. 356*9e965d6fSRomain Jobredeaux """ 357*9e965d6fSRomain Jobredeaux if not proguard_specs: 358*9e965d6fSRomain Jobredeaux outputs = _get_proguard_output( 359*9e965d6fSRomain Jobredeaux ctx, 360*9e965d6fSRomain Jobredeaux proguard_output_jar = proguard_output_jar, 361*9e965d6fSRomain Jobredeaux proguard_seeds = None, 362*9e965d6fSRomain Jobredeaux proguard_usage = None, 363*9e965d6fSRomain Jobredeaux proguard_output_map = proguard_output_map, 364*9e965d6fSRomain Jobredeaux combined_library_jar = None, 365*9e965d6fSRomain Jobredeaux startup_profile_rewritten = None, 366*9e965d6fSRomain Jobredeaux baseline_profile_rewritten = None, 367*9e965d6fSRomain Jobredeaux ) 368*9e965d6fSRomain Jobredeaux 369*9e965d6fSRomain Jobredeaux # Fail at execution time if these artifacts are requested, to avoid issue where outputs are 370*9e965d6fSRomain Jobredeaux # declared without having any proguard specs. This can happen if specs is a select() that 371*9e965d6fSRomain Jobredeaux # resolves to an empty list. 372*9e965d6fSRomain Jobredeaux _fail_action( 373*9e965d6fSRomain Jobredeaux ctx, 374*9e965d6fSRomain Jobredeaux outputs.output_jar, 375*9e965d6fSRomain Jobredeaux outputs.mapping, 376*9e965d6fSRomain Jobredeaux outputs.config, 377*9e965d6fSRomain Jobredeaux proguard_seeds, 378*9e965d6fSRomain Jobredeaux proguard_usage, 379*9e965d6fSRomain Jobredeaux ) 380*9e965d6fSRomain Jobredeaux return outputs 381*9e965d6fSRomain Jobredeaux 382*9e965d6fSRomain Jobredeaux library_jar_list = [get_android_sdk(ctx).android_jar] 383*9e965d6fSRomain Jobredeaux if ctx.fragments.android.desugar_java8: 384*9e965d6fSRomain Jobredeaux library_jar_list.append(ctx.file._desugared_java8_legacy_apis) 385*9e965d6fSRomain Jobredeaux neverlink_infos = utils.collect_providers(StarlarkAndroidNeverlinkInfo, ctx.attr.deps) 386*9e965d6fSRomain Jobredeaux library_jars = depset(library_jar_list, transitive = [info.transitive_neverlink_libraries for info in neverlink_infos]) 387*9e965d6fSRomain Jobredeaux 388*9e965d6fSRomain Jobredeaux return _create_optimization_actions( 389*9e965d6fSRomain Jobredeaux ctx, 390*9e965d6fSRomain Jobredeaux proguard_specs, 391*9e965d6fSRomain Jobredeaux proguard_seeds, 392*9e965d6fSRomain Jobredeaux proguard_usage, 393*9e965d6fSRomain Jobredeaux proguard_mapping, 394*9e965d6fSRomain Jobredeaux proguard_output_jar, 395*9e965d6fSRomain Jobredeaux proguard_optimization_passes, 396*9e965d6fSRomain Jobredeaux proguard_output_map, 397*9e965d6fSRomain Jobredeaux input_jar, 398*9e965d6fSRomain Jobredeaux library_jars, 399*9e965d6fSRomain Jobredeaux startup_profile, 400*9e965d6fSRomain Jobredeaux baseline_profile, 401*9e965d6fSRomain Jobredeaux proguard_tool, 402*9e965d6fSRomain Jobredeaux ) 403*9e965d6fSRomain Jobredeaux 404*9e965d6fSRomain Jobredeauxdef _get_proguard_output( 405*9e965d6fSRomain Jobredeaux ctx, 406*9e965d6fSRomain Jobredeaux proguard_output_jar, 407*9e965d6fSRomain Jobredeaux proguard_seeds, 408*9e965d6fSRomain Jobredeaux proguard_usage, 409*9e965d6fSRomain Jobredeaux proguard_output_map, 410*9e965d6fSRomain Jobredeaux combined_library_jar, 411*9e965d6fSRomain Jobredeaux startup_profile_rewritten, 412*9e965d6fSRomain Jobredeaux baseline_profile_rewritten): 413*9e965d6fSRomain Jobredeaux """Helper method to get a struct of all proguard outputs.""" 414*9e965d6fSRomain Jobredeaux 415*9e965d6fSRomain Jobredeaux # Proto Output Map is currently empty from ProGuard. 416*9e965d6fSRomain Jobredeaux proguard_output_proto_map = None 417*9e965d6fSRomain Jobredeaux if proguard_output_map: 418*9e965d6fSRomain Jobredeaux proguard_output_proto_map = _get_proguard_temp_artifact(ctx, "_proguard.pbmap") 419*9e965d6fSRomain Jobredeaux ctx.actions.write(proguard_output_proto_map, content = "") 420*9e965d6fSRomain Jobredeaux 421*9e965d6fSRomain Jobredeaux config_output = _get_proguard_temp_artifact(ctx, "_proguard.config") 422*9e965d6fSRomain Jobredeaux 423*9e965d6fSRomain Jobredeaux return struct( 424*9e965d6fSRomain Jobredeaux output_jar = proguard_output_jar, 425*9e965d6fSRomain Jobredeaux mapping = proguard_output_map, 426*9e965d6fSRomain Jobredeaux proto_mapping = proguard_output_proto_map, 427*9e965d6fSRomain Jobredeaux seeds = proguard_seeds, 428*9e965d6fSRomain Jobredeaux usage = proguard_usage, 429*9e965d6fSRomain Jobredeaux library_jar = combined_library_jar, 430*9e965d6fSRomain Jobredeaux config = config_output, 431*9e965d6fSRomain Jobredeaux startup_profile_rewritten = startup_profile_rewritten, 432*9e965d6fSRomain Jobredeaux baseline_profile_rewritten = baseline_profile_rewritten, 433*9e965d6fSRomain Jobredeaux ) 434*9e965d6fSRomain Jobredeaux 435*9e965d6fSRomain Jobredeauxdef _create_optimization_actions( 436*9e965d6fSRomain Jobredeaux ctx, 437*9e965d6fSRomain Jobredeaux proguard_specs = None, 438*9e965d6fSRomain Jobredeaux proguard_seeds = None, 439*9e965d6fSRomain Jobredeaux proguard_usage = None, 440*9e965d6fSRomain Jobredeaux proguard_mapping = None, 441*9e965d6fSRomain Jobredeaux proguard_output_jar = None, 442*9e965d6fSRomain Jobredeaux num_passes = None, 443*9e965d6fSRomain Jobredeaux proguard_output_map = None, 444*9e965d6fSRomain Jobredeaux input_jar = None, 445*9e965d6fSRomain Jobredeaux library_jars = depset(), 446*9e965d6fSRomain Jobredeaux startup_profile = None, 447*9e965d6fSRomain Jobredeaux baseline_profile = None, 448*9e965d6fSRomain Jobredeaux proguard_tool = None): 449*9e965d6fSRomain Jobredeaux """Helper method to create all optimizaction actions based on the target configuration.""" 450*9e965d6fSRomain Jobredeaux if not proguard_specs: 451*9e965d6fSRomain Jobredeaux fail("Missing proguard_specs in create_optimization_actions") 452*9e965d6fSRomain Jobredeaux 453*9e965d6fSRomain Jobredeaux # Merge all library jars into a single jar 454*9e965d6fSRomain Jobredeaux combined_library_jar = _get_proguard_temp_artifact(ctx, "_migrated_combined_library_jars.jar") 455*9e965d6fSRomain Jobredeaux java.singlejar( 456*9e965d6fSRomain Jobredeaux ctx, 457*9e965d6fSRomain Jobredeaux library_jars, 458*9e965d6fSRomain Jobredeaux combined_library_jar, 459*9e965d6fSRomain Jobredeaux java_toolchain = common.get_java_toolchain(ctx), 460*9e965d6fSRomain Jobredeaux ) 461*9e965d6fSRomain Jobredeaux 462*9e965d6fSRomain Jobredeaux # Filter library jar with program jar 463*9e965d6fSRomain Jobredeaux filtered_library_jar = _get_proguard_temp_artifact(ctx, "_migrated_combined_library_jars_filtered.jar") 464*9e965d6fSRomain Jobredeaux common.filter_zip_exclude( 465*9e965d6fSRomain Jobredeaux ctx, 466*9e965d6fSRomain Jobredeaux filtered_library_jar, 467*9e965d6fSRomain Jobredeaux combined_library_jar, 468*9e965d6fSRomain Jobredeaux filter_zips = [input_jar], 469*9e965d6fSRomain Jobredeaux ) 470*9e965d6fSRomain Jobredeaux 471*9e965d6fSRomain Jobredeaux startup_profile_rewritten = None 472*9e965d6fSRomain Jobredeaux baseline_profile_rewritten = None 473*9e965d6fSRomain Jobredeaux if startup_profile: 474*9e965d6fSRomain Jobredeaux startup_profile_rewritten = _baseline_profiles.get_profile_artifact(ctx, "rewritten-startup-prof.txt") 475*9e965d6fSRomain Jobredeaux if baseline_profile and startup_profile: 476*9e965d6fSRomain Jobredeaux baseline_profile_rewritten = _baseline_profiles.get_profile_artifact(ctx, "rewritten-merged-prof.txt") 477*9e965d6fSRomain Jobredeaux 478*9e965d6fSRomain Jobredeaux outputs = _get_proguard_output( 479*9e965d6fSRomain Jobredeaux ctx, 480*9e965d6fSRomain Jobredeaux proguard_output_jar, 481*9e965d6fSRomain Jobredeaux proguard_seeds, 482*9e965d6fSRomain Jobredeaux proguard_usage, 483*9e965d6fSRomain Jobredeaux proguard_output_map, 484*9e965d6fSRomain Jobredeaux combined_library_jar, 485*9e965d6fSRomain Jobredeaux startup_profile_rewritten, 486*9e965d6fSRomain Jobredeaux baseline_profile_rewritten, 487*9e965d6fSRomain Jobredeaux ) 488*9e965d6fSRomain Jobredeaux 489*9e965d6fSRomain Jobredeaux # TODO(timpeut): Validate that optimizer target selection is correct 490*9e965d6fSRomain Jobredeaux mnemonic = ctx.fragments.java.bytecode_optimizer_mnemonic 491*9e965d6fSRomain Jobredeaux optimizer_target = ctx.executable._bytecode_optimizer 492*9e965d6fSRomain Jobredeaux 493*9e965d6fSRomain Jobredeaux # If num_passes is not specified run a single optimization action 494*9e965d6fSRomain Jobredeaux if not num_passes: 495*9e965d6fSRomain Jobredeaux _optimization_action( 496*9e965d6fSRomain Jobredeaux ctx, 497*9e965d6fSRomain Jobredeaux outputs.output_jar, 498*9e965d6fSRomain Jobredeaux input_jar, 499*9e965d6fSRomain Jobredeaux filtered_library_jar, 500*9e965d6fSRomain Jobredeaux proguard_specs, 501*9e965d6fSRomain Jobredeaux proguard_mapping = proguard_mapping, 502*9e965d6fSRomain Jobredeaux proguard_output_map = outputs.mapping, 503*9e965d6fSRomain Jobredeaux proguard_seeds = outputs.seeds, 504*9e965d6fSRomain Jobredeaux proguard_usage = outputs.usage, 505*9e965d6fSRomain Jobredeaux proguard_config_output = outputs.config, 506*9e965d6fSRomain Jobredeaux startup_profile = startup_profile, 507*9e965d6fSRomain Jobredeaux startup_profile_rewritten = outputs.startup_profile_rewritten, 508*9e965d6fSRomain Jobredeaux baseline_profile = baseline_profile, 509*9e965d6fSRomain Jobredeaux baseline_profile_rewritten = outputs.baseline_profile_rewritten, 510*9e965d6fSRomain Jobredeaux final = True, 511*9e965d6fSRomain Jobredeaux mnemonic = mnemonic, 512*9e965d6fSRomain Jobredeaux progress_message = "Trimming binary with %s: %s" % (mnemonic, ctx.label), 513*9e965d6fSRomain Jobredeaux proguard_tool = proguard_tool, 514*9e965d6fSRomain Jobredeaux ) 515*9e965d6fSRomain Jobredeaux return outputs 516*9e965d6fSRomain Jobredeaux 517*9e965d6fSRomain Jobredeaux # num_passes has been specified, create multiple proguard actions 518*9e965d6fSRomain Jobredeaux split_bytecode_optimization_passes = ctx.fragments.java.split_bytecode_optimization_pass 519*9e965d6fSRomain Jobredeaux bytecode_optimization_pass_actions = ctx.fragments.java.bytecode_optimization_pass_actions 520*9e965d6fSRomain Jobredeaux last_stage_output = _get_proguard_temp_artifact(ctx, "_proguard_preoptimization.jar") 521*9e965d6fSRomain Jobredeaux _optimization_action( 522*9e965d6fSRomain Jobredeaux ctx, 523*9e965d6fSRomain Jobredeaux outputs.output_jar, 524*9e965d6fSRomain Jobredeaux input_jar, 525*9e965d6fSRomain Jobredeaux filtered_library_jar, 526*9e965d6fSRomain Jobredeaux proguard_specs, 527*9e965d6fSRomain Jobredeaux proguard_mapping = proguard_mapping, 528*9e965d6fSRomain Jobredeaux proguard_output_map = None, 529*9e965d6fSRomain Jobredeaux proguard_seeds = outputs.seeds, 530*9e965d6fSRomain Jobredeaux proguard_usage = None, 531*9e965d6fSRomain Jobredeaux proguard_config_output = None, 532*9e965d6fSRomain Jobredeaux startup_profile = startup_profile, 533*9e965d6fSRomain Jobredeaux startup_profile_rewritten = None, 534*9e965d6fSRomain Jobredeaux baseline_profile = baseline_profile, 535*9e965d6fSRomain Jobredeaux baseline_profile_rewritten = None, 536*9e965d6fSRomain Jobredeaux final = False, 537*9e965d6fSRomain Jobredeaux runtype = "INITIAL", 538*9e965d6fSRomain Jobredeaux next_stage_output = last_stage_output, 539*9e965d6fSRomain Jobredeaux mnemonic = mnemonic, 540*9e965d6fSRomain Jobredeaux progress_message = "Trimming binary with %s: Verification/Shrinking Pass" % mnemonic, 541*9e965d6fSRomain Jobredeaux proguard_tool = proguard_tool, 542*9e965d6fSRomain Jobredeaux ) 543*9e965d6fSRomain Jobredeaux for i in range(1, num_passes + 1): 544*9e965d6fSRomain Jobredeaux if split_bytecode_optimization_passes and bytecode_optimization_pass_actions < 2: 545*9e965d6fSRomain Jobredeaux last_stage_output = _create_single_optimization_action( 546*9e965d6fSRomain Jobredeaux ctx, 547*9e965d6fSRomain Jobredeaux outputs.output_jar, 548*9e965d6fSRomain Jobredeaux input_jar, 549*9e965d6fSRomain Jobredeaux filtered_library_jar, 550*9e965d6fSRomain Jobredeaux proguard_specs, 551*9e965d6fSRomain Jobredeaux proguard_mapping, 552*9e965d6fSRomain Jobredeaux i, 553*9e965d6fSRomain Jobredeaux "_INITIAL", 554*9e965d6fSRomain Jobredeaux mnemonic, 555*9e965d6fSRomain Jobredeaux last_stage_output, 556*9e965d6fSRomain Jobredeaux optimizer_target, 557*9e965d6fSRomain Jobredeaux ) 558*9e965d6fSRomain Jobredeaux last_stage_output = _create_single_optimization_action( 559*9e965d6fSRomain Jobredeaux ctx, 560*9e965d6fSRomain Jobredeaux outputs.output_jar, 561*9e965d6fSRomain Jobredeaux input_jar, 562*9e965d6fSRomain Jobredeaux filtered_library_jar, 563*9e965d6fSRomain Jobredeaux proguard_specs, 564*9e965d6fSRomain Jobredeaux proguard_mapping, 565*9e965d6fSRomain Jobredeaux i, 566*9e965d6fSRomain Jobredeaux "_FINAL", 567*9e965d6fSRomain Jobredeaux mnemonic, 568*9e965d6fSRomain Jobredeaux last_stage_output, 569*9e965d6fSRomain Jobredeaux optimizer_target, 570*9e965d6fSRomain Jobredeaux ) 571*9e965d6fSRomain Jobredeaux else: 572*9e965d6fSRomain Jobredeaux for j in range(1, bytecode_optimization_pass_actions + 1): 573*9e965d6fSRomain Jobredeaux last_stage_output = _create_single_optimization_action( 574*9e965d6fSRomain Jobredeaux ctx, 575*9e965d6fSRomain Jobredeaux outputs.output_jar, 576*9e965d6fSRomain Jobredeaux input_jar, 577*9e965d6fSRomain Jobredeaux filtered_library_jar, 578*9e965d6fSRomain Jobredeaux proguard_specs, 579*9e965d6fSRomain Jobredeaux proguard_mapping, 580*9e965d6fSRomain Jobredeaux i, 581*9e965d6fSRomain Jobredeaux "_ACTION_%s_OF_%s" % (j, bytecode_optimization_pass_actions), 582*9e965d6fSRomain Jobredeaux mnemonic, 583*9e965d6fSRomain Jobredeaux last_stage_output, 584*9e965d6fSRomain Jobredeaux optimizer_target, 585*9e965d6fSRomain Jobredeaux ) 586*9e965d6fSRomain Jobredeaux 587*9e965d6fSRomain Jobredeaux _optimization_action( 588*9e965d6fSRomain Jobredeaux ctx, 589*9e965d6fSRomain Jobredeaux outputs.output_jar, 590*9e965d6fSRomain Jobredeaux input_jar, 591*9e965d6fSRomain Jobredeaux filtered_library_jar, 592*9e965d6fSRomain Jobredeaux proguard_specs, 593*9e965d6fSRomain Jobredeaux proguard_mapping = proguard_mapping, 594*9e965d6fSRomain Jobredeaux proguard_output_map = outputs.mapping, 595*9e965d6fSRomain Jobredeaux proguard_seeds = None, 596*9e965d6fSRomain Jobredeaux proguard_usage = outputs.usage, 597*9e965d6fSRomain Jobredeaux proguard_config_output = outputs.config, 598*9e965d6fSRomain Jobredeaux startup_profile = None, 599*9e965d6fSRomain Jobredeaux startup_profile_rewritten = outputs.startup_profile_rewritten, 600*9e965d6fSRomain Jobredeaux baseline_profile = None, 601*9e965d6fSRomain Jobredeaux baseline_profile_rewritten = outputs.baseline_profile_rewritten, 602*9e965d6fSRomain Jobredeaux final = True, 603*9e965d6fSRomain Jobredeaux runtype = "FINAL", 604*9e965d6fSRomain Jobredeaux last_stage_output = last_stage_output, 605*9e965d6fSRomain Jobredeaux mnemonic = mnemonic, 606*9e965d6fSRomain Jobredeaux progress_message = "Trimming binary with %s: Obfuscation and Final Output Pass" % mnemonic, 607*9e965d6fSRomain Jobredeaux proguard_tool = proguard_tool, 608*9e965d6fSRomain Jobredeaux ) 609*9e965d6fSRomain Jobredeaux return outputs 610*9e965d6fSRomain Jobredeaux 611*9e965d6fSRomain Jobredeauxdef _create_single_optimization_action( 612*9e965d6fSRomain Jobredeaux ctx, 613*9e965d6fSRomain Jobredeaux output_jar, 614*9e965d6fSRomain Jobredeaux program_jar, 615*9e965d6fSRomain Jobredeaux library_jar, 616*9e965d6fSRomain Jobredeaux proguard_specs, 617*9e965d6fSRomain Jobredeaux proguard_mapping, 618*9e965d6fSRomain Jobredeaux optimization_pass_num, 619*9e965d6fSRomain Jobredeaux runtype_suffix, 620*9e965d6fSRomain Jobredeaux mnemonic, 621*9e965d6fSRomain Jobredeaux last_stage_output, 622*9e965d6fSRomain Jobredeaux proguard_tool): 623*9e965d6fSRomain Jobredeaux next_stage_output = _get_proguard_temp_artifact(ctx, "_%s_optimization%s_%s.jar" % (mnemonic, runtype_suffix, optimization_pass_num)) 624*9e965d6fSRomain Jobredeaux _optimization_action( 625*9e965d6fSRomain Jobredeaux ctx, 626*9e965d6fSRomain Jobredeaux output_jar, 627*9e965d6fSRomain Jobredeaux program_jar, 628*9e965d6fSRomain Jobredeaux library_jar, 629*9e965d6fSRomain Jobredeaux proguard_specs, 630*9e965d6fSRomain Jobredeaux proguard_mapping = proguard_mapping, 631*9e965d6fSRomain Jobredeaux mnemonic = mnemonic, 632*9e965d6fSRomain Jobredeaux final = False, 633*9e965d6fSRomain Jobredeaux runtype = "OPTIMIZATION" + runtype_suffix, 634*9e965d6fSRomain Jobredeaux last_stage_output = last_stage_output, 635*9e965d6fSRomain Jobredeaux next_stage_output = next_stage_output, 636*9e965d6fSRomain Jobredeaux progress_message = "Trimming binary with %s: Optimization%s Pass %d" % (mnemonic, runtype_suffix, optimization_pass_num), 637*9e965d6fSRomain Jobredeaux proguard_tool = proguard_tool, 638*9e965d6fSRomain Jobredeaux ) 639*9e965d6fSRomain Jobredeaux return next_stage_output 640*9e965d6fSRomain Jobredeaux 641*9e965d6fSRomain Jobredeauxdef _merge_proguard_maps( 642*9e965d6fSRomain Jobredeaux ctx, 643*9e965d6fSRomain Jobredeaux output, 644*9e965d6fSRomain Jobredeaux inputs = [], 645*9e965d6fSRomain Jobredeaux proguard_maps_merger = None, 646*9e965d6fSRomain Jobredeaux toolchain_type = None): 647*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 648*9e965d6fSRomain Jobredeaux args.add_all(inputs, before_each = "--pg-map") 649*9e965d6fSRomain Jobredeaux args.add("--pg-map-output", output) 650*9e965d6fSRomain Jobredeaux 651*9e965d6fSRomain Jobredeaux ctx.actions.run( 652*9e965d6fSRomain Jobredeaux outputs = [output], 653*9e965d6fSRomain Jobredeaux executable = proguard_maps_merger, 654*9e965d6fSRomain Jobredeaux inputs = inputs, 655*9e965d6fSRomain Jobredeaux arguments = [args], 656*9e965d6fSRomain Jobredeaux mnemonic = "MergeProguardMaps", 657*9e965d6fSRomain Jobredeaux progress_message = "Merging app and desugared library Proguard maps for %s" % ctx.label, 658*9e965d6fSRomain Jobredeaux use_default_shell_env = True, 659*9e965d6fSRomain Jobredeaux toolchain = toolchain_type, 660*9e965d6fSRomain Jobredeaux ) 661*9e965d6fSRomain Jobredeaux 662*9e965d6fSRomain Jobredeauxdef _fail_action(ctx, *outputs): 663*9e965d6fSRomain Jobredeaux ctx.actions.run_shell( 664*9e965d6fSRomain Jobredeaux outputs = [output for output in outputs if output != None], 665*9e965d6fSRomain Jobredeaux command = "echo \"Unable to run proguard without `proguard_specs`\"; exit 1;", 666*9e965d6fSRomain Jobredeaux ) 667*9e965d6fSRomain Jobredeaux 668*9e965d6fSRomain Jobredeauxproguard = struct( 669*9e965d6fSRomain Jobredeaux apply_proguard = _apply_proguard, 670*9e965d6fSRomain Jobredeaux process_specs = _process_specs, 671*9e965d6fSRomain Jobredeaux generate_min_sdk_version_assumevalues = _generate_min_sdk_version_assumevalues, 672*9e965d6fSRomain Jobredeaux get_proguard_output_map = _get_proguard_output_map, 673*9e965d6fSRomain Jobredeaux get_proguard_specs = _get_proguard_specs, 674*9e965d6fSRomain Jobredeaux get_proguard_temp_artifact = _get_proguard_temp_artifact, 675*9e965d6fSRomain Jobredeaux get_proguard_temp_artifact_with_prefix = _get_proguard_temp_artifact_with_prefix, 676*9e965d6fSRomain Jobredeaux merge_proguard_maps = _merge_proguard_maps, 677*9e965d6fSRomain Jobredeaux) 678*9e965d6fSRomain Jobredeaux 679*9e965d6fSRomain Jobredeauxtesting = struct( 680*9e965d6fSRomain Jobredeaux validate_proguard_spec = _validate_proguard_spec, 681*9e965d6fSRomain Jobredeaux collect_transitive_proguard_specs = _collect_transitive_proguard_specs, 682*9e965d6fSRomain Jobredeaux optimization_action = _optimization_action, 683*9e965d6fSRomain Jobredeaux ProguardSpecContextInfo = _ProguardSpecContextInfo, 684*9e965d6fSRomain Jobredeaux) 685