1*9e965d6fSRomain Jobredeaux# Copyright 2023 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 Dex Commands.""" 16*9e965d6fSRomain Jobredeaux 17*9e965d6fSRomain Jobredeauxload("//rules:attrs.bzl", _attrs = "attrs") 18*9e965d6fSRomain Jobredeauxload("//rules:common.bzl", _common = "common") 19*9e965d6fSRomain Jobredeauxload("//rules:java.bzl", _java = "java") 20*9e965d6fSRomain Jobredeauxload("@bazel_skylib//lib:collections.bzl", "collections") 21*9e965d6fSRomain Jobredeauxload(":providers.bzl", "StarlarkAndroidDexInfo") 22*9e965d6fSRomain Jobredeauxload(":utils.bzl", "ANDROID_TOOLCHAIN_TYPE", "get_android_toolchain", "utils") 23*9e965d6fSRomain Jobredeaux 24*9e965d6fSRomain Jobredeaux_DEX_MEMORY = 4096 25*9e965d6fSRomain Jobredeaux_DEX_THREADS = 5 26*9e965d6fSRomain Jobredeaux 27*9e965d6fSRomain Jobredeaux_tristate = _attrs.tristate 28*9e965d6fSRomain Jobredeaux 29*9e965d6fSRomain Jobredeauxdef _resource_set_for_monolithic_dexing(): 30*9e965d6fSRomain Jobredeaux return {"cpu": _DEX_THREADS, "memory": _DEX_MEMORY} 31*9e965d6fSRomain Jobredeaux 32*9e965d6fSRomain Jobredeauxdef _process_incremental_dexing( 33*9e965d6fSRomain Jobredeaux ctx, 34*9e965d6fSRomain Jobredeaux output, 35*9e965d6fSRomain Jobredeaux deps = [], 36*9e965d6fSRomain Jobredeaux runtime_jars = [], 37*9e965d6fSRomain Jobredeaux dexopts = [], 38*9e965d6fSRomain Jobredeaux main_dex_list = None, 39*9e965d6fSRomain Jobredeaux min_sdk_version = 0, 40*9e965d6fSRomain Jobredeaux proguarded_jar = None, 41*9e965d6fSRomain Jobredeaux java_info = None, 42*9e965d6fSRomain Jobredeaux desugar_dict = {}, 43*9e965d6fSRomain Jobredeaux shuffle_jars = None, 44*9e965d6fSRomain Jobredeaux dexbuilder = None, 45*9e965d6fSRomain Jobredeaux dexbuilder_after_proguard = None, 46*9e965d6fSRomain Jobredeaux dexmerger = None, 47*9e965d6fSRomain Jobredeaux dexsharder = None, 48*9e965d6fSRomain Jobredeaux toolchain_type = None): 49*9e965d6fSRomain Jobredeaux info = _merge_infos(utils.collect_providers(StarlarkAndroidDexInfo, deps)) 50*9e965d6fSRomain Jobredeaux incremental_dexopts = _filter_dexopts(dexopts, ctx.fragments.android.get_dexopts_supported_in_incremental_dexing) 51*9e965d6fSRomain Jobredeaux inclusion_filter_jar = proguarded_jar 52*9e965d6fSRomain Jobredeaux if not proguarded_jar: 53*9e965d6fSRomain Jobredeaux dex_archives = [] 54*9e965d6fSRomain Jobredeaux for jar in runtime_jars: 55*9e965d6fSRomain Jobredeaux dex_archive = _get_dx_artifact(ctx, jar.basename + ".dex.zip") 56*9e965d6fSRomain Jobredeaux _dex( 57*9e965d6fSRomain Jobredeaux ctx, 58*9e965d6fSRomain Jobredeaux input = desugar_dict[jar] if jar in desugar_dict else jar, 59*9e965d6fSRomain Jobredeaux output = dex_archive, 60*9e965d6fSRomain Jobredeaux incremental_dexopts = incremental_dexopts, 61*9e965d6fSRomain Jobredeaux min_sdk_version = min_sdk_version, 62*9e965d6fSRomain Jobredeaux dex_exec = dexbuilder, 63*9e965d6fSRomain Jobredeaux toolchain_type = toolchain_type, 64*9e965d6fSRomain Jobredeaux ) 65*9e965d6fSRomain Jobredeaux dex_archives.append(dex_archive) 66*9e965d6fSRomain Jobredeaux dex_archives += _to_dexed_classpath( 67*9e965d6fSRomain Jobredeaux dex_archives_dict = {d.jar: d.dex for d in info.dex_archives_dict.get("".join(incremental_dexopts), depset()).to_list()}, 68*9e965d6fSRomain Jobredeaux classpath = _filter(java_info.transitive_runtime_jars.to_list(), excludes = _get_library_r_jars(deps)), 69*9e965d6fSRomain Jobredeaux runtime_jars = runtime_jars, 70*9e965d6fSRomain Jobredeaux ) 71*9e965d6fSRomain Jobredeaux else: 72*9e965d6fSRomain Jobredeaux java_resource_jar = ctx.actions.declare_file(ctx.label.name + "_files/java_resources.jar") 73*9e965d6fSRomain Jobredeaux if ctx.fragments.android.incremental_dexing_shards_after_proguard > 1: 74*9e965d6fSRomain Jobredeaux dex_archives = _shard_proguarded_jar_and_dex( 75*9e965d6fSRomain Jobredeaux ctx, 76*9e965d6fSRomain Jobredeaux java_resource_jar = java_resource_jar, 77*9e965d6fSRomain Jobredeaux num_shards = ctx.fragments.android.incremental_dexing_shards_after_proguard, 78*9e965d6fSRomain Jobredeaux dexopts = incremental_dexopts, 79*9e965d6fSRomain Jobredeaux proguarded_jar = proguarded_jar, 80*9e965d6fSRomain Jobredeaux main_dex_list = main_dex_list, 81*9e965d6fSRomain Jobredeaux min_sdk_version = min_sdk_version, 82*9e965d6fSRomain Jobredeaux shuffle_jars = shuffle_jars, 83*9e965d6fSRomain Jobredeaux dexbuilder_after_proguard = dexbuilder_after_proguard, 84*9e965d6fSRomain Jobredeaux toolchain_type = toolchain_type, 85*9e965d6fSRomain Jobredeaux ) 86*9e965d6fSRomain Jobredeaux inclusion_filter_jar = None 87*9e965d6fSRomain Jobredeaux else: 88*9e965d6fSRomain Jobredeaux # No need to shuffle if there is only one shard 89*9e965d6fSRomain Jobredeaux dex_archive = _get_dx_artifact(ctx, "classes.jar") 90*9e965d6fSRomain Jobredeaux _dex( 91*9e965d6fSRomain Jobredeaux ctx, 92*9e965d6fSRomain Jobredeaux input = proguarded_jar, 93*9e965d6fSRomain Jobredeaux output = dex_archive, 94*9e965d6fSRomain Jobredeaux incremental_dexopts = incremental_dexopts, 95*9e965d6fSRomain Jobredeaux min_sdk_version = min_sdk_version, 96*9e965d6fSRomain Jobredeaux dex_exec = dexbuilder_after_proguard, 97*9e965d6fSRomain Jobredeaux toolchain_type = toolchain_type, 98*9e965d6fSRomain Jobredeaux ) 99*9e965d6fSRomain Jobredeaux dex_archives = [dex_archive] 100*9e965d6fSRomain Jobredeaux 101*9e965d6fSRomain Jobredeaux if len(dex_archives) == 1: 102*9e965d6fSRomain Jobredeaux _dex_merge( 103*9e965d6fSRomain Jobredeaux ctx, 104*9e965d6fSRomain Jobredeaux output = output, 105*9e965d6fSRomain Jobredeaux inputs = dex_archives, 106*9e965d6fSRomain Jobredeaux multidex_strategy = "minimal", 107*9e965d6fSRomain Jobredeaux main_dex_list = main_dex_list, 108*9e965d6fSRomain Jobredeaux dexopts = _filter_dexopts(dexopts, ctx.fragments.android.get_dexopts_supported_in_dex_merger), 109*9e965d6fSRomain Jobredeaux dexmerger = dexmerger, 110*9e965d6fSRomain Jobredeaux toolchain_type = toolchain_type, 111*9e965d6fSRomain Jobredeaux ) 112*9e965d6fSRomain Jobredeaux else: 113*9e965d6fSRomain Jobredeaux shards = ctx.actions.declare_directory("dexsplits/" + ctx.label.name) 114*9e965d6fSRomain Jobredeaux dexes = ctx.actions.declare_directory("dexfiles/" + ctx.label.name) 115*9e965d6fSRomain Jobredeaux _shard_dexes( 116*9e965d6fSRomain Jobredeaux ctx, 117*9e965d6fSRomain Jobredeaux output = shards, 118*9e965d6fSRomain Jobredeaux inputs = dex_archives, 119*9e965d6fSRomain Jobredeaux dexopts = _filter_dexopts(dexopts, ctx.fragments.android.get_dexopts_supported_in_dex_sharder), 120*9e965d6fSRomain Jobredeaux main_dex_list = main_dex_list, 121*9e965d6fSRomain Jobredeaux inclusion_filter_jar = inclusion_filter_jar, 122*9e965d6fSRomain Jobredeaux dexsharder = dexsharder, 123*9e965d6fSRomain Jobredeaux toolchain_type = toolchain_type, 124*9e965d6fSRomain Jobredeaux ) 125*9e965d6fSRomain Jobredeaux 126*9e965d6fSRomain Jobredeaux # TODO(b/130571505): Implement this after SpawnActionTemplate is supported in Starlark 127*9e965d6fSRomain Jobredeaux android_common.create_dex_merger_actions( 128*9e965d6fSRomain Jobredeaux ctx, 129*9e965d6fSRomain Jobredeaux output = dexes, 130*9e965d6fSRomain Jobredeaux input = shards, 131*9e965d6fSRomain Jobredeaux dexopts = dexopts, 132*9e965d6fSRomain Jobredeaux dexmerger = dexmerger, 133*9e965d6fSRomain Jobredeaux ) 134*9e965d6fSRomain Jobredeaux _java.singlejar( 135*9e965d6fSRomain Jobredeaux ctx, 136*9e965d6fSRomain Jobredeaux output = output, 137*9e965d6fSRomain Jobredeaux inputs = [dexes], 138*9e965d6fSRomain Jobredeaux mnemonic = "MergeDexZips", 139*9e965d6fSRomain Jobredeaux progress_message = "Merging dex shards for %s." % ctx.label, 140*9e965d6fSRomain Jobredeaux java_toolchain = _common.get_java_toolchain(ctx), 141*9e965d6fSRomain Jobredeaux ) 142*9e965d6fSRomain Jobredeaux 143*9e965d6fSRomain Jobredeauxdef _process_optimized_dexing( 144*9e965d6fSRomain Jobredeaux ctx, 145*9e965d6fSRomain Jobredeaux output, 146*9e965d6fSRomain Jobredeaux input = None, 147*9e965d6fSRomain Jobredeaux proguard_output_map = None, 148*9e965d6fSRomain Jobredeaux postprocessing_output_map = None, 149*9e965d6fSRomain Jobredeaux dexopts = [], 150*9e965d6fSRomain Jobredeaux native_multidex = True, 151*9e965d6fSRomain Jobredeaux min_sdk_version = 0, 152*9e965d6fSRomain Jobredeaux main_dex_list = None, 153*9e965d6fSRomain Jobredeaux library_jar = None, 154*9e965d6fSRomain Jobredeaux startup_profile = None, 155*9e965d6fSRomain Jobredeaux optimizing_dexer = None, 156*9e965d6fSRomain Jobredeaux toolchain_type = None): 157*9e965d6fSRomain Jobredeaux inputs = [input] 158*9e965d6fSRomain Jobredeaux outputs = [output] 159*9e965d6fSRomain Jobredeaux 160*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 161*9e965d6fSRomain Jobredeaux args.add(input) 162*9e965d6fSRomain Jobredeaux args.add("--release") 163*9e965d6fSRomain Jobredeaux args.add("--no-desugaring") 164*9e965d6fSRomain Jobredeaux args.add("--output", output) 165*9e965d6fSRomain Jobredeaux args.add_all(dexopts) 166*9e965d6fSRomain Jobredeaux 167*9e965d6fSRomain Jobredeaux if proguard_output_map: 168*9e965d6fSRomain Jobredeaux args.add("--pg-map", proguard_output_map) 169*9e965d6fSRomain Jobredeaux args.add("--pg-map-output", postprocessing_output_map) 170*9e965d6fSRomain Jobredeaux inputs.append(proguard_output_map) 171*9e965d6fSRomain Jobredeaux outputs.append(postprocessing_output_map) 172*9e965d6fSRomain Jobredeaux 173*9e965d6fSRomain Jobredeaux if startup_profile and native_multidex: 174*9e965d6fSRomain Jobredeaux args.add("--startup-profile", startup_profile) 175*9e965d6fSRomain Jobredeaux inputs.append(startup_profile) 176*9e965d6fSRomain Jobredeaux 177*9e965d6fSRomain Jobredeaux # TODO(b/261110876): Pass min SDK through here based on the value in the merged manifest. The 178*9e965d6fSRomain Jobredeaux # current value is statically defined for the entire depot. 179*9e965d6fSRomain Jobredeaux # We currently set the minimum SDK version to 21 if you are doing native multidex as that is 180*9e965d6fSRomain Jobredeaux # required for native multidex to work in the first place and as a result is required for 181*9e965d6fSRomain Jobredeaux # correct behavior from the dexer. 182*9e965d6fSRomain Jobredeaux sdk = max(min_sdk_version, 21) if native_multidex else min_sdk_version 183*9e965d6fSRomain Jobredeaux if sdk != 0: 184*9e965d6fSRomain Jobredeaux args.add("--min-api", sdk) 185*9e965d6fSRomain Jobredeaux if main_dex_list: 186*9e965d6fSRomain Jobredeaux args.add("--main-dex-list", main_dex_list) 187*9e965d6fSRomain Jobredeaux inputs.append(main_dex_list) 188*9e965d6fSRomain Jobredeaux if library_jar: 189*9e965d6fSRomain Jobredeaux args.add("--lib", library_jar) 190*9e965d6fSRomain Jobredeaux inputs.append(library_jar) 191*9e965d6fSRomain Jobredeaux 192*9e965d6fSRomain Jobredeaux ctx.actions.run( 193*9e965d6fSRomain Jobredeaux outputs = outputs, 194*9e965d6fSRomain Jobredeaux executable = optimizing_dexer, 195*9e965d6fSRomain Jobredeaux inputs = inputs, 196*9e965d6fSRomain Jobredeaux arguments = [args], 197*9e965d6fSRomain Jobredeaux mnemonic = "OptimizingDex", 198*9e965d6fSRomain Jobredeaux progress_message = "Optimized dexing for " + str(ctx.label), 199*9e965d6fSRomain Jobredeaux use_default_shell_env = True, 200*9e965d6fSRomain Jobredeaux toolchain = toolchain_type, 201*9e965d6fSRomain Jobredeaux ) 202*9e965d6fSRomain Jobredeaux 203*9e965d6fSRomain Jobredeauxdef _process_monolithic_dexing( 204*9e965d6fSRomain Jobredeaux ctx, 205*9e965d6fSRomain Jobredeaux output, 206*9e965d6fSRomain Jobredeaux input, 207*9e965d6fSRomain Jobredeaux dexopts = [], 208*9e965d6fSRomain Jobredeaux min_sdk_version = 0, 209*9e965d6fSRomain Jobredeaux main_dex_list = None, 210*9e965d6fSRomain Jobredeaux dexbuilder = None, 211*9e965d6fSRomain Jobredeaux toolchain_type = None): 212*9e965d6fSRomain Jobredeaux # Create an artifact for the intermediate zip output generated by AndroidDexer that includes 213*9e965d6fSRomain Jobredeaux # non-.dex files. A subsequent TrimDexZip action will filter out all non-.dex files. 214*9e965d6fSRomain Jobredeaux classes_dex_intermediate = _get_dx_artifact(ctx, "intermediate_classes.dex.zip") 215*9e965d6fSRomain Jobredeaux inputs = [input] 216*9e965d6fSRomain Jobredeaux 217*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 218*9e965d6fSRomain Jobredeaux args.add("--dex") 219*9e965d6fSRomain Jobredeaux args.add_all(dexopts) 220*9e965d6fSRomain Jobredeaux if min_sdk_version > 0: 221*9e965d6fSRomain Jobredeaux args.add("--min_sdk_version", min_sdk_version) 222*9e965d6fSRomain Jobredeaux args.add("--multi-dex") 223*9e965d6fSRomain Jobredeaux if main_dex_list: 224*9e965d6fSRomain Jobredeaux args.add(main_dex_list, format = "--main-dex-list=%s") 225*9e965d6fSRomain Jobredeaux inputs.append(main_dex_list) 226*9e965d6fSRomain Jobredeaux args.add(classes_dex_intermediate, format = "--output=%s") 227*9e965d6fSRomain Jobredeaux args.add(input) 228*9e965d6fSRomain Jobredeaux 229*9e965d6fSRomain Jobredeaux ctx.actions.run( 230*9e965d6fSRomain Jobredeaux executable = dexbuilder, 231*9e965d6fSRomain Jobredeaux inputs = inputs, 232*9e965d6fSRomain Jobredeaux outputs = [classes_dex_intermediate], 233*9e965d6fSRomain Jobredeaux arguments = [args], 234*9e965d6fSRomain Jobredeaux progress_message = "Converting %s to dex format" % input.short_path, 235*9e965d6fSRomain Jobredeaux mnemonic = "AndroidDexer", 236*9e965d6fSRomain Jobredeaux use_default_shell_env = True, 237*9e965d6fSRomain Jobredeaux resource_set = _resource_set_for_monolithic_dexing, 238*9e965d6fSRomain Jobredeaux toolchain = toolchain_type, 239*9e965d6fSRomain Jobredeaux ) 240*9e965d6fSRomain Jobredeaux 241*9e965d6fSRomain Jobredeaux # Because the dexer also places resources into this zip, we also need to create a cleanup 242*9e965d6fSRomain Jobredeaux # action that removes all non-.dex files before staging for apk building. 243*9e965d6fSRomain Jobredeaux _java.singlejar( 244*9e965d6fSRomain Jobredeaux ctx, 245*9e965d6fSRomain Jobredeaux inputs = [classes_dex_intermediate], 246*9e965d6fSRomain Jobredeaux output = output, 247*9e965d6fSRomain Jobredeaux include_prefixes = ["classes"], 248*9e965d6fSRomain Jobredeaux java_toolchain = _common.get_java_toolchain(ctx), 249*9e965d6fSRomain Jobredeaux mnemonic = "TrimDexZip", 250*9e965d6fSRomain Jobredeaux progress_message = "Trimming %s." % classes_dex_intermediate.short_path, 251*9e965d6fSRomain Jobredeaux ) 252*9e965d6fSRomain Jobredeaux 253*9e965d6fSRomain Jobredeauxdef _shard_proguarded_jar_and_dex( 254*9e965d6fSRomain Jobredeaux ctx, 255*9e965d6fSRomain Jobredeaux java_resource_jar, 256*9e965d6fSRomain Jobredeaux num_shards = 50, 257*9e965d6fSRomain Jobredeaux dexopts = [], 258*9e965d6fSRomain Jobredeaux proguarded_jar = None, 259*9e965d6fSRomain Jobredeaux main_dex_list = None, 260*9e965d6fSRomain Jobredeaux min_sdk_version = 0, 261*9e965d6fSRomain Jobredeaux shuffle_jars = None, 262*9e965d6fSRomain Jobredeaux dexbuilder_after_proguard = None, 263*9e965d6fSRomain Jobredeaux toolchain_type = None): 264*9e965d6fSRomain Jobredeaux if num_shards <= 1: 265*9e965d6fSRomain Jobredeaux fail("num_shards expects to be larger than 1.") 266*9e965d6fSRomain Jobredeaux 267*9e965d6fSRomain Jobredeaux shards = _make_shard_artifacts(ctx, num_shards, ".jar.dex.zip") 268*9e965d6fSRomain Jobredeaux shuffle_outputs = _make_shard_artifacts(ctx, num_shards, ".jar") 269*9e965d6fSRomain Jobredeaux inputs = [] 270*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 271*9e965d6fSRomain Jobredeaux args.add_all(shuffle_outputs, before_each = "--output_jar") 272*9e965d6fSRomain Jobredeaux args.add("--output_resources", java_resource_jar) 273*9e965d6fSRomain Jobredeaux 274*9e965d6fSRomain Jobredeaux if main_dex_list: 275*9e965d6fSRomain Jobredeaux args.add("--main_dex_filter", main_dex_list) 276*9e965d6fSRomain Jobredeaux inputs.append(main_dex_list) 277*9e965d6fSRomain Jobredeaux 278*9e965d6fSRomain Jobredeaux # If we need to run Proguard, all the class files will be in the Proguarded jar, which has to 279*9e965d6fSRomain Jobredeaux # be converted to dex. 280*9e965d6fSRomain Jobredeaux args.add("--input_jar", proguarded_jar) 281*9e965d6fSRomain Jobredeaux inputs.append(proguarded_jar) 282*9e965d6fSRomain Jobredeaux 283*9e965d6fSRomain Jobredeaux ctx.actions.run( 284*9e965d6fSRomain Jobredeaux executable = shuffle_jars, 285*9e965d6fSRomain Jobredeaux outputs = shuffle_outputs + [java_resource_jar], 286*9e965d6fSRomain Jobredeaux inputs = inputs, 287*9e965d6fSRomain Jobredeaux arguments = [args], 288*9e965d6fSRomain Jobredeaux mnemonic = "ShardClassesToDex", 289*9e965d6fSRomain Jobredeaux progress_message = "Sharding classes for dexing for " + str(ctx.label), 290*9e965d6fSRomain Jobredeaux use_default_shell_env = True, 291*9e965d6fSRomain Jobredeaux toolchain = toolchain_type, 292*9e965d6fSRomain Jobredeaux ) 293*9e965d6fSRomain Jobredeaux 294*9e965d6fSRomain Jobredeaux for i in range(len(shards)): 295*9e965d6fSRomain Jobredeaux _dex( 296*9e965d6fSRomain Jobredeaux ctx, 297*9e965d6fSRomain Jobredeaux input = shuffle_outputs[i], 298*9e965d6fSRomain Jobredeaux output = shards[i], 299*9e965d6fSRomain Jobredeaux incremental_dexopts = dexopts, 300*9e965d6fSRomain Jobredeaux min_sdk_version = min_sdk_version, 301*9e965d6fSRomain Jobredeaux dex_exec = dexbuilder_after_proguard, 302*9e965d6fSRomain Jobredeaux toolchain_type = toolchain_type, 303*9e965d6fSRomain Jobredeaux ) 304*9e965d6fSRomain Jobredeaux return shards 305*9e965d6fSRomain Jobredeaux 306*9e965d6fSRomain Jobredeauxdef _make_shard_artifacts(ctx, n, suffix): 307*9e965d6fSRomain Jobredeaux return [_get_dx_artifact(ctx, "shard" + str(i) + suffix) for i in range(1, n + 1)] 308*9e965d6fSRomain Jobredeaux 309*9e965d6fSRomain Jobredeauxdef _shard_dexes( 310*9e965d6fSRomain Jobredeaux ctx, 311*9e965d6fSRomain Jobredeaux output, 312*9e965d6fSRomain Jobredeaux inputs = [], 313*9e965d6fSRomain Jobredeaux dexopts = [], 314*9e965d6fSRomain Jobredeaux main_dex_list = None, 315*9e965d6fSRomain Jobredeaux inclusion_filter_jar = None, 316*9e965d6fSRomain Jobredeaux dexsharder = None, 317*9e965d6fSRomain Jobredeaux toolchain_type = None): 318*9e965d6fSRomain Jobredeaux args = ctx.actions.args().use_param_file(param_file_arg = "@%s") 319*9e965d6fSRomain Jobredeaux args.add_all(inputs, before_each = "--input") 320*9e965d6fSRomain Jobredeaux args.add("--output", output.path) 321*9e965d6fSRomain Jobredeaux if main_dex_list: 322*9e965d6fSRomain Jobredeaux inputs.append(main_dex_list) 323*9e965d6fSRomain Jobredeaux args.add("--main-dex-list", main_dex_list) 324*9e965d6fSRomain Jobredeaux if inclusion_filter_jar: 325*9e965d6fSRomain Jobredeaux inputs.append(inclusion_filter_jar) 326*9e965d6fSRomain Jobredeaux args.add("--inclusion_filter_jar", inclusion_filter_jar) 327*9e965d6fSRomain Jobredeaux 328*9e965d6fSRomain Jobredeaux args.add_all(dexopts) 329*9e965d6fSRomain Jobredeaux 330*9e965d6fSRomain Jobredeaux ctx.actions.run( 331*9e965d6fSRomain Jobredeaux executable = dexsharder, 332*9e965d6fSRomain Jobredeaux outputs = [output], 333*9e965d6fSRomain Jobredeaux inputs = inputs, 334*9e965d6fSRomain Jobredeaux arguments = [args], 335*9e965d6fSRomain Jobredeaux mnemonic = "ShardForMultidex", 336*9e965d6fSRomain Jobredeaux progress_message = "Assembling dex files for " + ctx.label.name, 337*9e965d6fSRomain Jobredeaux use_default_shell_env = True, 338*9e965d6fSRomain Jobredeaux toolchain = toolchain_type, 339*9e965d6fSRomain Jobredeaux ) 340*9e965d6fSRomain Jobredeaux 341*9e965d6fSRomain Jobredeaux return output 342*9e965d6fSRomain Jobredeaux 343*9e965d6fSRomain Jobredeauxdef _append_java8_legacy_dex( 344*9e965d6fSRomain Jobredeaux ctx, 345*9e965d6fSRomain Jobredeaux output = None, 346*9e965d6fSRomain Jobredeaux input = None, 347*9e965d6fSRomain Jobredeaux java8_legacy_dex = None, 348*9e965d6fSRomain Jobredeaux dex_zips_merger = None): 349*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 350*9e965d6fSRomain Jobredeaux 351*9e965d6fSRomain Jobredeaux # Order matters here: we want java8_legacy_dex to be the highest-numbered classesN.dex 352*9e965d6fSRomain Jobredeaux args.add("--input_zip", input) 353*9e965d6fSRomain Jobredeaux args.add("--input_zip", java8_legacy_dex) 354*9e965d6fSRomain Jobredeaux args.add("--output_zip", output) 355*9e965d6fSRomain Jobredeaux 356*9e965d6fSRomain Jobredeaux ctx.actions.run( 357*9e965d6fSRomain Jobredeaux executable = dex_zips_merger, 358*9e965d6fSRomain Jobredeaux inputs = [input, java8_legacy_dex], 359*9e965d6fSRomain Jobredeaux outputs = [output], 360*9e965d6fSRomain Jobredeaux arguments = [args], 361*9e965d6fSRomain Jobredeaux mnemonic = "AppendJava8LegacyDex", 362*9e965d6fSRomain Jobredeaux use_default_shell_env = True, 363*9e965d6fSRomain Jobredeaux progress_message = "Adding Java8 legacy library for %s" % ctx.label, 364*9e965d6fSRomain Jobredeaux toolchain = ANDROID_TOOLCHAIN_TYPE, 365*9e965d6fSRomain Jobredeaux ) 366*9e965d6fSRomain Jobredeaux 367*9e965d6fSRomain Jobredeauxdef _to_dexed_classpath(dex_archives_dict = {}, classpath = [], runtime_jars = []): 368*9e965d6fSRomain Jobredeaux dexed_classpath = [] 369*9e965d6fSRomain Jobredeaux for jar in classpath: 370*9e965d6fSRomain Jobredeaux if jar not in dex_archives_dict: 371*9e965d6fSRomain Jobredeaux if jar not in runtime_jars: 372*9e965d6fSRomain Jobredeaux fail("Dependencies on .jar artifacts are not allowed in Android binaries, please use " + 373*9e965d6fSRomain Jobredeaux "a java_import to depend on " + jar.short_path + 374*9e965d6fSRomain Jobredeaux ". If this is an implicit dependency then the rule that " + 375*9e965d6fSRomain Jobredeaux "introduces it will need to be fixed to account for it correctly.") 376*9e965d6fSRomain Jobredeaux else: 377*9e965d6fSRomain Jobredeaux dexed_classpath.append(dex_archives_dict[jar]) 378*9e965d6fSRomain Jobredeaux return dexed_classpath 379*9e965d6fSRomain Jobredeaux 380*9e965d6fSRomain Jobredeauxdef _dex( 381*9e965d6fSRomain Jobredeaux ctx, 382*9e965d6fSRomain Jobredeaux input, 383*9e965d6fSRomain Jobredeaux output = None, 384*9e965d6fSRomain Jobredeaux incremental_dexopts = [], 385*9e965d6fSRomain Jobredeaux min_sdk_version = 0, 386*9e965d6fSRomain Jobredeaux dex_exec = None, 387*9e965d6fSRomain Jobredeaux toolchain_type = None): 388*9e965d6fSRomain Jobredeaux """Dexes a JAR. 389*9e965d6fSRomain Jobredeaux 390*9e965d6fSRomain Jobredeaux Args: 391*9e965d6fSRomain Jobredeaux ctx: The context. 392*9e965d6fSRomain Jobredeaux input: File. The jar to be dexed. 393*9e965d6fSRomain Jobredeaux output: File. The archive file containing all of the dexes. 394*9e965d6fSRomain Jobredeaux incremental_dexopts: List of strings. Additional command-line flags for the dexing tool when building dexes. 395*9e965d6fSRomain Jobredeaux min_sdk_version: Integer. The minimum targeted sdk version. 396*9e965d6fSRomain Jobredeaux dex_exec: File. The executable dex builder file. 397*9e965d6fSRomain Jobredeaux """ 398*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 399*9e965d6fSRomain Jobredeaux args.use_param_file("@%s", use_always = True) # Required for workers. 400*9e965d6fSRomain Jobredeaux args.set_param_file_format("multiline") 401*9e965d6fSRomain Jobredeaux 402*9e965d6fSRomain Jobredeaux args.add("--input_jar", input) 403*9e965d6fSRomain Jobredeaux args.add("--output_zip", output) 404*9e965d6fSRomain Jobredeaux args.add_all(incremental_dexopts) 405*9e965d6fSRomain Jobredeaux 406*9e965d6fSRomain Jobredeaux if min_sdk_version > 0: 407*9e965d6fSRomain Jobredeaux args.add("--min_sdk_version", min_sdk_version) 408*9e965d6fSRomain Jobredeaux 409*9e965d6fSRomain Jobredeaux execution_requirements = {} 410*9e965d6fSRomain Jobredeaux if ctx.fragments.android.persistent_android_dex_desugar: 411*9e965d6fSRomain Jobredeaux execution_requirements["supports-workers"] = "1" 412*9e965d6fSRomain Jobredeaux if ctx.fragments.android.persistent_multiplex_android_dex_desugar: 413*9e965d6fSRomain Jobredeaux execution_requirements["supports-multiplex-workers"] = "1" 414*9e965d6fSRomain Jobredeaux 415*9e965d6fSRomain Jobredeaux ctx.actions.run( 416*9e965d6fSRomain Jobredeaux executable = dex_exec, 417*9e965d6fSRomain Jobredeaux arguments = [args], 418*9e965d6fSRomain Jobredeaux inputs = [input], 419*9e965d6fSRomain Jobredeaux outputs = [output], 420*9e965d6fSRomain Jobredeaux mnemonic = "DexBuilder", 421*9e965d6fSRomain Jobredeaux progress_message = "Dexing " + input.path + " with applicable dexopts " + str(incremental_dexopts), 422*9e965d6fSRomain Jobredeaux execution_requirements = execution_requirements, 423*9e965d6fSRomain Jobredeaux toolchain = toolchain_type, 424*9e965d6fSRomain Jobredeaux ) 425*9e965d6fSRomain Jobredeaux 426*9e965d6fSRomain Jobredeauxdef _get_dx_artifact(ctx, basename): 427*9e965d6fSRomain Jobredeaux return ctx.actions.declare_file("_dx_migrated/" + ctx.label.name + "/" + basename) 428*9e965d6fSRomain Jobredeaux 429*9e965d6fSRomain Jobredeauxdef _get_effective_incremental_dexing( 430*9e965d6fSRomain Jobredeaux force_incremental_dexing = _tristate.auto, 431*9e965d6fSRomain Jobredeaux has_forbidden_dexopts = False, 432*9e965d6fSRomain Jobredeaux incremental_dexing_after_proguard_by_default = True, 433*9e965d6fSRomain Jobredeaux incremental_dexing_shards_after_proguard = True, 434*9e965d6fSRomain Jobredeaux is_binary_optimized = False, 435*9e965d6fSRomain Jobredeaux use_incremental_dexing = True): 436*9e965d6fSRomain Jobredeaux if (is_binary_optimized and 437*9e965d6fSRomain Jobredeaux force_incremental_dexing == _tristate.yes and incremental_dexing_shards_after_proguard <= 0): 438*9e965d6fSRomain Jobredeaux fail("Target cannot be incrementally dexed because it uses Proguard") 439*9e965d6fSRomain Jobredeaux 440*9e965d6fSRomain Jobredeaux if force_incremental_dexing == _tristate.yes: 441*9e965d6fSRomain Jobredeaux return True 442*9e965d6fSRomain Jobredeaux 443*9e965d6fSRomain Jobredeaux if force_incremental_dexing == _tristate.no: 444*9e965d6fSRomain Jobredeaux return False 445*9e965d6fSRomain Jobredeaux 446*9e965d6fSRomain Jobredeaux # If there are incompatible dexopts and the incremental_dexing attr is not set, we silently don't run 447*9e965d6fSRomain Jobredeaux # incremental dexing. 448*9e965d6fSRomain Jobredeaux if has_forbidden_dexopts or (is_binary_optimized and not incremental_dexing_after_proguard_by_default): 449*9e965d6fSRomain Jobredeaux return False 450*9e965d6fSRomain Jobredeaux 451*9e965d6fSRomain Jobredeaux # use_incremental_dexing config flag will take effect if incremental_dexing attr is not set 452*9e965d6fSRomain Jobredeaux return use_incremental_dexing 453*9e965d6fSRomain Jobredeaux 454*9e965d6fSRomain Jobredeauxdef _get_java8_legacy_dex_and_map(ctx, build_customized_files = False, binary_jar = None, android_jar = None): 455*9e965d6fSRomain Jobredeaux if not build_customized_files: 456*9e965d6fSRomain Jobredeaux return utils.only(get_android_toolchain(ctx).java8_legacy_dex.files.to_list()), None 457*9e965d6fSRomain Jobredeaux else: 458*9e965d6fSRomain Jobredeaux java8_legacy_dex_rules = _get_dx_artifact(ctx, "_java8_legacy.dex.pgcfg") 459*9e965d6fSRomain Jobredeaux java8_legacy_dex_map = _get_dx_artifact(ctx, "_java8_legacy.dex.map") 460*9e965d6fSRomain Jobredeaux java8_legacy_dex = _get_dx_artifact(ctx, "_java8_legacy.dex.zip") 461*9e965d6fSRomain Jobredeaux 462*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 463*9e965d6fSRomain Jobredeaux args.add("--rules", java8_legacy_dex_rules) 464*9e965d6fSRomain Jobredeaux args.add("--binary", binary_jar) 465*9e965d6fSRomain Jobredeaux args.add("--android_jar", android_jar) 466*9e965d6fSRomain Jobredeaux args.add("--output", java8_legacy_dex) 467*9e965d6fSRomain Jobredeaux args.add("--output_map", java8_legacy_dex_map) 468*9e965d6fSRomain Jobredeaux 469*9e965d6fSRomain Jobredeaux ctx.actions.run( 470*9e965d6fSRomain Jobredeaux executable = get_android_toolchain(ctx).build_java8_legacy_dex.files_to_run, 471*9e965d6fSRomain Jobredeaux inputs = [binary_jar, android_jar], 472*9e965d6fSRomain Jobredeaux outputs = [java8_legacy_dex_rules, java8_legacy_dex_map, java8_legacy_dex], 473*9e965d6fSRomain Jobredeaux arguments = [args], 474*9e965d6fSRomain Jobredeaux mnemonic = "BuildLegacyDex", 475*9e965d6fSRomain Jobredeaux progress_message = "Building Java8 legacy library for %s" % ctx.label, 476*9e965d6fSRomain Jobredeaux toolchain = ANDROID_TOOLCHAIN_TYPE, 477*9e965d6fSRomain Jobredeaux ) 478*9e965d6fSRomain Jobredeaux 479*9e965d6fSRomain Jobredeaux return java8_legacy_dex, java8_legacy_dex_map 480*9e965d6fSRomain Jobredeaux 481*9e965d6fSRomain Jobredeauxdef _get_library_r_jars(deps): 482*9e965d6fSRomain Jobredeaux transitive_resource_jars = [] 483*9e965d6fSRomain Jobredeaux for dep in utils.collect_providers(AndroidLibraryResourceClassJarProvider, deps): 484*9e965d6fSRomain Jobredeaux transitive_resource_jars += dep.jars.to_list() 485*9e965d6fSRomain Jobredeaux return transitive_resource_jars 486*9e965d6fSRomain Jobredeaux 487*9e965d6fSRomain Jobredeauxdef _dex_merge( 488*9e965d6fSRomain Jobredeaux ctx, 489*9e965d6fSRomain Jobredeaux output = None, 490*9e965d6fSRomain Jobredeaux inputs = [], 491*9e965d6fSRomain Jobredeaux multidex_strategy = "minimal", 492*9e965d6fSRomain Jobredeaux main_dex_list = None, 493*9e965d6fSRomain Jobredeaux dexopts = [], 494*9e965d6fSRomain Jobredeaux dexmerger = None, 495*9e965d6fSRomain Jobredeaux toolchain_type = None): 496*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 497*9e965d6fSRomain Jobredeaux args.add("--multidex", multidex_strategy) 498*9e965d6fSRomain Jobredeaux args.add_all(inputs, before_each = "--input") 499*9e965d6fSRomain Jobredeaux args.add("--output", output) 500*9e965d6fSRomain Jobredeaux args.add_all(dexopts) 501*9e965d6fSRomain Jobredeaux 502*9e965d6fSRomain Jobredeaux if main_dex_list: 503*9e965d6fSRomain Jobredeaux inputs.append(main_dex_list) 504*9e965d6fSRomain Jobredeaux args.add("--main-dex-list", main_dex_list) 505*9e965d6fSRomain Jobredeaux 506*9e965d6fSRomain Jobredeaux ctx.actions.run( 507*9e965d6fSRomain Jobredeaux executable = dexmerger, 508*9e965d6fSRomain Jobredeaux arguments = [args], 509*9e965d6fSRomain Jobredeaux inputs = inputs, 510*9e965d6fSRomain Jobredeaux outputs = [output], 511*9e965d6fSRomain Jobredeaux mnemonic = "DexMerger", 512*9e965d6fSRomain Jobredeaux progress_message = "Assembling dex files into " + output.short_path, 513*9e965d6fSRomain Jobredeaux toolchain = toolchain_type, 514*9e965d6fSRomain Jobredeaux ) 515*9e965d6fSRomain Jobredeaux 516*9e965d6fSRomain Jobredeauxdef _merge_infos(infos): 517*9e965d6fSRomain Jobredeaux dex_archives_dict = {} 518*9e965d6fSRomain Jobredeaux for info in infos: 519*9e965d6fSRomain Jobredeaux for dexopts in info.dex_archives_dict: 520*9e965d6fSRomain Jobredeaux if dexopts not in dex_archives_dict: 521*9e965d6fSRomain Jobredeaux dex_archives_dict[dexopts] = [info.dex_archives_dict[dexopts]] 522*9e965d6fSRomain Jobredeaux else: 523*9e965d6fSRomain Jobredeaux dex_archives_dict[dexopts].append(info.dex_archives_dict[dexopts]) 524*9e965d6fSRomain Jobredeaux return StarlarkAndroidDexInfo( 525*9e965d6fSRomain Jobredeaux dex_archives_dict = 526*9e965d6fSRomain Jobredeaux {dexopts: depset(direct = [], transitive = dex_archives) for dexopts, dex_archives in dex_archives_dict.items()}, 527*9e965d6fSRomain Jobredeaux ) 528*9e965d6fSRomain Jobredeaux 529*9e965d6fSRomain Jobredeauxdef _filter_dexopts(tokenized_dexopts, includes): 530*9e965d6fSRomain Jobredeaux return _normalize_dexopts(_filter(tokenized_dexopts, includes = includes)) 531*9e965d6fSRomain Jobredeaux 532*9e965d6fSRomain Jobredeauxdef _filter(candidates, includes = [], excludes = []): 533*9e965d6fSRomain Jobredeaux if excludes and includes: 534*9e965d6fSRomain Jobredeaux fail("Only one of excludes list and includes list can be set.") 535*9e965d6fSRomain Jobredeaux if includes: 536*9e965d6fSRomain Jobredeaux return [c for c in candidates if c in includes] 537*9e965d6fSRomain Jobredeaux if excludes: 538*9e965d6fSRomain Jobredeaux return [c for c in candidates if c not in excludes] 539*9e965d6fSRomain Jobredeaux return candidates 540*9e965d6fSRomain Jobredeaux 541*9e965d6fSRomain Jobredeauxdef _normalize_dexopts(tokenized_dexopts): 542*9e965d6fSRomain Jobredeaux def _dx_to_dexbuilder(opt): 543*9e965d6fSRomain Jobredeaux return opt.replace("--no-", "--no") 544*9e965d6fSRomain Jobredeaux 545*9e965d6fSRomain Jobredeaux return collections.uniq(sorted([_dx_to_dexbuilder(token) for token in tokenized_dexopts])) 546*9e965d6fSRomain Jobredeaux 547*9e965d6fSRomain Jobredeauxdef _generate_main_dex_list( 548*9e965d6fSRomain Jobredeaux ctx, 549*9e965d6fSRomain Jobredeaux jar, 550*9e965d6fSRomain Jobredeaux android_jar = None, 551*9e965d6fSRomain Jobredeaux desugar_java8_libs = True, 552*9e965d6fSRomain Jobredeaux main_dex_classes = None, 553*9e965d6fSRomain Jobredeaux main_dex_list_opts = [], 554*9e965d6fSRomain Jobredeaux main_dex_proguard_spec = None, 555*9e965d6fSRomain Jobredeaux proguard_specs = [], 556*9e965d6fSRomain Jobredeaux legacy_apis = [], 557*9e965d6fSRomain Jobredeaux shrinked_android_jar = None, 558*9e965d6fSRomain Jobredeaux toolchain_type = None, 559*9e965d6fSRomain Jobredeaux main_dex_list_creator = None, 560*9e965d6fSRomain Jobredeaux legacy_main_dex_list_generator = None, 561*9e965d6fSRomain Jobredeaux proguard_tool = None): 562*9e965d6fSRomain Jobredeaux main_dex_list = _get_dx_artifact(ctx, "main_dex_list.txt") 563*9e965d6fSRomain Jobredeaux if not proguard_specs: 564*9e965d6fSRomain Jobredeaux proguard_specs.append(main_dex_classes) 565*9e965d6fSRomain Jobredeaux if main_dex_proguard_spec: 566*9e965d6fSRomain Jobredeaux proguard_specs.append(main_dex_proguard_spec) 567*9e965d6fSRomain Jobredeaux 568*9e965d6fSRomain Jobredeaux # If legacy_main_dex_list_generator is not set by either the SDK or the flag, use ProGuard and 569*9e965d6fSRomain Jobredeaux # the main dext list creator specified by the android_sdk rule. If 570*9e965d6fSRomain Jobredeaux # legacy_main_dex_list_generator is provided, use that tool instead. 571*9e965d6fSRomain Jobredeaux # TODO(b/147692286): Remove the old main-dex list generation that relied on ProGuard. 572*9e965d6fSRomain Jobredeaux if not legacy_main_dex_list_generator: 573*9e965d6fSRomain Jobredeaux if not shrinked_android_jar: 574*9e965d6fSRomain Jobredeaux fail("In \"legacy\" multidex mode, either legacy_main_dex_list_generator or " + 575*9e965d6fSRomain Jobredeaux "shrinked_android_jar must be set in the android_sdk.") 576*9e965d6fSRomain Jobredeaux 577*9e965d6fSRomain Jobredeaux # Process the input jar through Proguard into an intermediate, streamlined jar. 578*9e965d6fSRomain Jobredeaux stripped_jar = _get_dx_artifact(ctx, "main_dex_intermediate.jar") 579*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 580*9e965d6fSRomain Jobredeaux args.add("-forceprocessing") 581*9e965d6fSRomain Jobredeaux args.add("-injars", jar) 582*9e965d6fSRomain Jobredeaux args.add("-libraryjars", shrinked_android_jar) 583*9e965d6fSRomain Jobredeaux args.add("-outjars", stripped_jar) 584*9e965d6fSRomain Jobredeaux args.add("-dontwarn") 585*9e965d6fSRomain Jobredeaux args.add("-dontnote") 586*9e965d6fSRomain Jobredeaux args.add("-dontoptimize") 587*9e965d6fSRomain Jobredeaux args.add("-dontobfuscate") 588*9e965d6fSRomain Jobredeaux ctx.actions.run( 589*9e965d6fSRomain Jobredeaux outputs = [stripped_jar], 590*9e965d6fSRomain Jobredeaux executable = proguard_tool, 591*9e965d6fSRomain Jobredeaux args = [args], 592*9e965d6fSRomain Jobredeaux inputs = [jar, shrinked_android_jar], 593*9e965d6fSRomain Jobredeaux mnemonic = "MainDexClassesIntermediate", 594*9e965d6fSRomain Jobredeaux progress_message = "Generating streamlined input jar for main dex classes list", 595*9e965d6fSRomain Jobredeaux use_default_shell_dev = True, 596*9e965d6fSRomain Jobredeaux toolchain = toolchain_type, 597*9e965d6fSRomain Jobredeaux ) 598*9e965d6fSRomain Jobredeaux 599*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 600*9e965d6fSRomain Jobredeaux args.add_all([main_dex_list, stripped_jar, jar]) 601*9e965d6fSRomain Jobredeaux args.add_all(main_dex_list_opts) 602*9e965d6fSRomain Jobredeaux 603*9e965d6fSRomain Jobredeaux ctx.actions.run( 604*9e965d6fSRomain Jobredeaux outputs = [main_dex_list], 605*9e965d6fSRomain Jobredeaux executable = main_dex_list_creator, 606*9e965d6fSRomain Jobredeaux arguments = [args], 607*9e965d6fSRomain Jobredeaux inputs = [jar, stripped_jar], 608*9e965d6fSRomain Jobredeaux mnemonic = "MainDexClasses", 609*9e965d6fSRomain Jobredeaux progress_message = "Generating main dex classes list", 610*9e965d6fSRomain Jobredeaux toolchain = toolchain_type, 611*9e965d6fSRomain Jobredeaux ) 612*9e965d6fSRomain Jobredeaux else: 613*9e965d6fSRomain Jobredeaux inputs = [jar, android_jar] + proguard_specs 614*9e965d6fSRomain Jobredeaux 615*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 616*9e965d6fSRomain Jobredeaux args.add("--main-dex-list-output", main_dex_list) 617*9e965d6fSRomain Jobredeaux args.add("--lib", android_jar) 618*9e965d6fSRomain Jobredeaux if desugar_java8_libs: 619*9e965d6fSRomain Jobredeaux args.add_all(legacy_apis, before_each = "--lib") 620*9e965d6fSRomain Jobredeaux inputs += legacy_apis 621*9e965d6fSRomain Jobredeaux args.add_all(proguard_specs, before_each = "--main-dex-rules") 622*9e965d6fSRomain Jobredeaux args.add(jar) 623*9e965d6fSRomain Jobredeaux ctx.actions.run( 624*9e965d6fSRomain Jobredeaux executable = legacy_main_dex_list_generator, 625*9e965d6fSRomain Jobredeaux arguments = [args], 626*9e965d6fSRomain Jobredeaux outputs = [main_dex_list], 627*9e965d6fSRomain Jobredeaux inputs = inputs, 628*9e965d6fSRomain Jobredeaux mnemonic = "MainDexClasses", 629*9e965d6fSRomain Jobredeaux progress_message = "Generating main dex classes list", 630*9e965d6fSRomain Jobredeaux toolchain = toolchain_type, 631*9e965d6fSRomain Jobredeaux ) 632*9e965d6fSRomain Jobredeaux return main_dex_list 633*9e965d6fSRomain Jobredeaux 634*9e965d6fSRomain Jobredeauxdef _transform_dex_list_through_proguard_map( 635*9e965d6fSRomain Jobredeaux ctx, 636*9e965d6fSRomain Jobredeaux proguard_output_map = None, 637*9e965d6fSRomain Jobredeaux main_dex_list = None, 638*9e965d6fSRomain Jobredeaux toolchain_type = None, 639*9e965d6fSRomain Jobredeaux dex_list_obfuscator = None): 640*9e965d6fSRomain Jobredeaux if not proguard_output_map: 641*9e965d6fSRomain Jobredeaux return main_dex_list 642*9e965d6fSRomain Jobredeaux 643*9e965d6fSRomain Jobredeaux obfuscated_main_dex_list = _get_dx_artifact(ctx, "main_dex_list_obfuscated.txt") 644*9e965d6fSRomain Jobredeaux 645*9e965d6fSRomain Jobredeaux args = ctx.actions.args() 646*9e965d6fSRomain Jobredeaux args.add("--input", main_dex_list) 647*9e965d6fSRomain Jobredeaux args.add("--output", obfuscated_main_dex_list) 648*9e965d6fSRomain Jobredeaux args.add("--obfuscation_map", proguard_output_map) 649*9e965d6fSRomain Jobredeaux ctx.actions.run( 650*9e965d6fSRomain Jobredeaux executable = dex_list_obfuscator, 651*9e965d6fSRomain Jobredeaux arguments = [args], 652*9e965d6fSRomain Jobredeaux outputs = [obfuscated_main_dex_list], 653*9e965d6fSRomain Jobredeaux inputs = [main_dex_list], 654*9e965d6fSRomain Jobredeaux mnemonic = "MainDexProguardClasses", 655*9e965d6fSRomain Jobredeaux progress_message = "Obfuscating main dex classes list", 656*9e965d6fSRomain Jobredeaux toolchain = toolchain_type, 657*9e965d6fSRomain Jobredeaux ) 658*9e965d6fSRomain Jobredeaux 659*9e965d6fSRomain Jobredeaux return obfuscated_main_dex_list 660*9e965d6fSRomain Jobredeaux 661*9e965d6fSRomain Jobredeauxdex = struct( 662*9e965d6fSRomain Jobredeaux append_java8_legacy_dex = _append_java8_legacy_dex, 663*9e965d6fSRomain Jobredeaux dex = _dex, 664*9e965d6fSRomain Jobredeaux dex_merge = _dex_merge, 665*9e965d6fSRomain Jobredeaux generate_main_dex_list = _generate_main_dex_list, 666*9e965d6fSRomain Jobredeaux get_dx_artifact = _get_dx_artifact, 667*9e965d6fSRomain Jobredeaux get_effective_incremental_dexing = _get_effective_incremental_dexing, 668*9e965d6fSRomain Jobredeaux get_java8_legacy_dex_and_map = _get_java8_legacy_dex_and_map, 669*9e965d6fSRomain Jobredeaux filter_dexopts = _filter_dexopts, 670*9e965d6fSRomain Jobredeaux merge_infos = _merge_infos, 671*9e965d6fSRomain Jobredeaux normalize_dexopts = _normalize_dexopts, 672*9e965d6fSRomain Jobredeaux process_monolithic_dexing = _process_monolithic_dexing, 673*9e965d6fSRomain Jobredeaux process_incremental_dexing = _process_incremental_dexing, 674*9e965d6fSRomain Jobredeaux process_optimized_dexing = _process_optimized_dexing, 675*9e965d6fSRomain Jobredeaux transform_dex_list_through_proguard_map = _transform_dex_list_through_proguard_map, 676*9e965d6fSRomain Jobredeaux) 677