1*8975f5c5SAndroid Build Coastguard Worker#!/usr/bin/env python3 2*8975f5c5SAndroid Build Coastguard Worker# 3*8975f5c5SAndroid Build Coastguard Worker# Copyright 2013 The Chromium Authors 4*8975f5c5SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be 5*8975f5c5SAndroid Build Coastguard Worker# found in the LICENSE file. 6*8975f5c5SAndroid Build Coastguard Worker 7*8975f5c5SAndroid Build Coastguard Workerimport argparse 8*8975f5c5SAndroid Build Coastguard Workerimport collections 9*8975f5c5SAndroid Build Coastguard Workerimport logging 10*8975f5c5SAndroid Build Coastguard Workerimport os 11*8975f5c5SAndroid Build Coastguard Workerimport re 12*8975f5c5SAndroid Build Coastguard Workerimport shutil 13*8975f5c5SAndroid Build Coastguard Workerimport shlex 14*8975f5c5SAndroid Build Coastguard Workerimport sys 15*8975f5c5SAndroid Build Coastguard Workerimport tempfile 16*8975f5c5SAndroid Build Coastguard Workerimport zipfile 17*8975f5c5SAndroid Build Coastguard Worker 18*8975f5c5SAndroid Build Coastguard Workerfrom util import build_utils 19*8975f5c5SAndroid Build Coastguard Workerfrom util import md5_check 20*8975f5c5SAndroid Build Coastguard Workerimport action_helpers # build_utils adds //build to sys.path. 21*8975f5c5SAndroid Build Coastguard Workerimport zip_helpers 22*8975f5c5SAndroid Build Coastguard Worker 23*8975f5c5SAndroid Build Coastguard Worker 24*8975f5c5SAndroid Build Coastguard Worker_DEX_XMX = '2G' # Increase this when __final_dex OOMs. 25*8975f5c5SAndroid Build Coastguard Worker 26*8975f5c5SAndroid Build Coastguard WorkerDEFAULT_IGNORE_WARNINGS = ( 27*8975f5c5SAndroid Build Coastguard Worker # Warning: Running R8 version main (build engineering), which cannot be 28*8975f5c5SAndroid Build Coastguard Worker # represented as a semantic version. Using an artificial version newer than 29*8975f5c5SAndroid Build Coastguard Worker # any known version for selecting Proguard configurations embedded under 30*8975f5c5SAndroid Build Coastguard Worker # META-INF/. This means that all rules with a '-upto-' qualifier will be 31*8975f5c5SAndroid Build Coastguard Worker # excluded and all rules with a -from- qualifier will be included. 32*8975f5c5SAndroid Build Coastguard Worker r'Running R8 version main', ) 33*8975f5c5SAndroid Build Coastguard Worker 34*8975f5c5SAndroid Build Coastguard Worker_IGNORE_SERVICE_ENTRIES = ( 35*8975f5c5SAndroid Build Coastguard Worker # ServiceLoader call is used only for ProtoBuf full (non-lite). 36*8975f5c5SAndroid Build Coastguard Worker # BaseGeneratedExtensionRegistryLite$Loader conflicts with 37*8975f5c5SAndroid Build Coastguard Worker # ChromeGeneratedExtensionRegistryLite$Loader. 38*8975f5c5SAndroid Build Coastguard Worker 'META-INF/services/com.google.protobuf.GeneratedExtensionRegistryLoader', 39*8975f5c5SAndroid Build Coastguard Worker # Uses ServiceLoader to find all implementing classes, so multiple are 40*8975f5c5SAndroid Build Coastguard Worker # expected. 41*8975f5c5SAndroid Build Coastguard Worker 'META-INF/services/androidx.appsearch.app.AppSearchDocumentClassMap', 42*8975f5c5SAndroid Build Coastguard Worker) 43*8975f5c5SAndroid Build Coastguard Worker 44*8975f5c5SAndroid Build Coastguard WorkerINTERFACE_DESUGARING_WARNINGS = (r'default or static interface methods', ) 45*8975f5c5SAndroid Build Coastguard Worker 46*8975f5c5SAndroid Build Coastguard Worker_SKIPPED_CLASS_FILE_NAMES = ( 47*8975f5c5SAndroid Build Coastguard Worker 'module-info.class', # Explicitly skipped by r8/utils/FileUtils#isClassFile 48*8975f5c5SAndroid Build Coastguard Worker) 49*8975f5c5SAndroid Build Coastguard Worker 50*8975f5c5SAndroid Build Coastguard Worker 51*8975f5c5SAndroid Build Coastguard Workerdef _ParseArgs(args): 52*8975f5c5SAndroid Build Coastguard Worker args = build_utils.ExpandFileArgs(args) 53*8975f5c5SAndroid Build Coastguard Worker parser = argparse.ArgumentParser() 54*8975f5c5SAndroid Build Coastguard Worker 55*8975f5c5SAndroid Build Coastguard Worker action_helpers.add_depfile_arg(parser) 56*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--output', required=True, help='Dex output path.') 57*8975f5c5SAndroid Build Coastguard Worker parser.add_argument( 58*8975f5c5SAndroid Build Coastguard Worker '--class-inputs', 59*8975f5c5SAndroid Build Coastguard Worker action='append', 60*8975f5c5SAndroid Build Coastguard Worker help='GN-list of .jars with .class files.') 61*8975f5c5SAndroid Build Coastguard Worker parser.add_argument( 62*8975f5c5SAndroid Build Coastguard Worker '--class-inputs-filearg', 63*8975f5c5SAndroid Build Coastguard Worker action='append', 64*8975f5c5SAndroid Build Coastguard Worker help='GN-list of .jars with .class files (added to depfile).') 65*8975f5c5SAndroid Build Coastguard Worker parser.add_argument( 66*8975f5c5SAndroid Build Coastguard Worker '--dex-inputs', action='append', help='GN-list of .jars with .dex files.') 67*8975f5c5SAndroid Build Coastguard Worker parser.add_argument( 68*8975f5c5SAndroid Build Coastguard Worker '--dex-inputs-filearg', 69*8975f5c5SAndroid Build Coastguard Worker action='append', 70*8975f5c5SAndroid Build Coastguard Worker help='GN-list of .jars with .dex files (added to depfile).') 71*8975f5c5SAndroid Build Coastguard Worker parser.add_argument( 72*8975f5c5SAndroid Build Coastguard Worker '--incremental-dir', 73*8975f5c5SAndroid Build Coastguard Worker help='Path of directory to put intermediate dex files.') 74*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--library', 75*8975f5c5SAndroid Build Coastguard Worker action='store_true', 76*8975f5c5SAndroid Build Coastguard Worker help='Allow numerous dex files within output.') 77*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--r8-jar-path', required=True, help='Path to R8 jar.') 78*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--skip-custom-d8', 79*8975f5c5SAndroid Build Coastguard Worker action='store_true', 80*8975f5c5SAndroid Build Coastguard Worker help='When rebuilding the CustomD8 jar, this may be ' 81*8975f5c5SAndroid Build Coastguard Worker 'necessary to avoid incompatibility with the new r8 ' 82*8975f5c5SAndroid Build Coastguard Worker 'jar.') 83*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--custom-d8-jar-path', 84*8975f5c5SAndroid Build Coastguard Worker required=True, 85*8975f5c5SAndroid Build Coastguard Worker help='Path to our customized d8 jar.') 86*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--desugar-dependencies', 87*8975f5c5SAndroid Build Coastguard Worker help='Path to store desugar dependencies.') 88*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--desugar', action='store_true') 89*8975f5c5SAndroid Build Coastguard Worker parser.add_argument( 90*8975f5c5SAndroid Build Coastguard Worker '--bootclasspath', 91*8975f5c5SAndroid Build Coastguard Worker action='append', 92*8975f5c5SAndroid Build Coastguard Worker help='GN-list of bootclasspath. Needed for --desugar') 93*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--show-desugar-default-interface-warnings', 94*8975f5c5SAndroid Build Coastguard Worker action='store_true', 95*8975f5c5SAndroid Build Coastguard Worker help='Enable desugaring warnings.') 96*8975f5c5SAndroid Build Coastguard Worker parser.add_argument( 97*8975f5c5SAndroid Build Coastguard Worker '--classpath', 98*8975f5c5SAndroid Build Coastguard Worker action='append', 99*8975f5c5SAndroid Build Coastguard Worker help='GN-list of full classpath. Needed for --desugar') 100*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--release', 101*8975f5c5SAndroid Build Coastguard Worker action='store_true', 102*8975f5c5SAndroid Build Coastguard Worker help='Run D8 in release mode.') 103*8975f5c5SAndroid Build Coastguard Worker parser.add_argument( 104*8975f5c5SAndroid Build Coastguard Worker '--min-api', help='Minimum Android API level compatibility.') 105*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--force-enable-assertions', 106*8975f5c5SAndroid Build Coastguard Worker action='store_true', 107*8975f5c5SAndroid Build Coastguard Worker help='Forcefully enable javac generated assertion code.') 108*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--assertion-handler', 109*8975f5c5SAndroid Build Coastguard Worker help='The class name of the assertion handler class.') 110*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--warnings-as-errors', 111*8975f5c5SAndroid Build Coastguard Worker action='store_true', 112*8975f5c5SAndroid Build Coastguard Worker help='Treat all warnings as errors.') 113*8975f5c5SAndroid Build Coastguard Worker parser.add_argument('--dump-inputs', 114*8975f5c5SAndroid Build Coastguard Worker action='store_true', 115*8975f5c5SAndroid Build Coastguard Worker help='Use when filing D8 bugs to capture inputs.' 116*8975f5c5SAndroid Build Coastguard Worker ' Stores inputs to d8inputs.zip') 117*8975f5c5SAndroid Build Coastguard Worker options = parser.parse_args(args) 118*8975f5c5SAndroid Build Coastguard Worker 119*8975f5c5SAndroid Build Coastguard Worker if options.force_enable_assertions and options.assertion_handler: 120*8975f5c5SAndroid Build Coastguard Worker parser.error('Cannot use both --force-enable-assertions and ' 121*8975f5c5SAndroid Build Coastguard Worker '--assertion-handler') 122*8975f5c5SAndroid Build Coastguard Worker 123*8975f5c5SAndroid Build Coastguard Worker options.class_inputs = action_helpers.parse_gn_list(options.class_inputs) 124*8975f5c5SAndroid Build Coastguard Worker options.class_inputs_filearg = action_helpers.parse_gn_list( 125*8975f5c5SAndroid Build Coastguard Worker options.class_inputs_filearg) 126*8975f5c5SAndroid Build Coastguard Worker options.bootclasspath = action_helpers.parse_gn_list(options.bootclasspath) 127*8975f5c5SAndroid Build Coastguard Worker options.classpath = action_helpers.parse_gn_list(options.classpath) 128*8975f5c5SAndroid Build Coastguard Worker options.dex_inputs = action_helpers.parse_gn_list(options.dex_inputs) 129*8975f5c5SAndroid Build Coastguard Worker options.dex_inputs_filearg = action_helpers.parse_gn_list( 130*8975f5c5SAndroid Build Coastguard Worker options.dex_inputs_filearg) 131*8975f5c5SAndroid Build Coastguard Worker 132*8975f5c5SAndroid Build Coastguard Worker return options 133*8975f5c5SAndroid Build Coastguard Worker 134*8975f5c5SAndroid Build Coastguard Worker 135*8975f5c5SAndroid Build Coastguard Workerdef CreateStderrFilter(filters): 136*8975f5c5SAndroid Build Coastguard Worker def filter_stderr(output): 137*8975f5c5SAndroid Build Coastguard Worker # Set this when debugging R8 output. 138*8975f5c5SAndroid Build Coastguard Worker if os.environ.get('R8_SHOW_ALL_OUTPUT', '0') != '0': 139*8975f5c5SAndroid Build Coastguard Worker return output 140*8975f5c5SAndroid Build Coastguard Worker 141*8975f5c5SAndroid Build Coastguard Worker # All missing definitions are logged as a single warning, but start on a 142*8975f5c5SAndroid Build Coastguard Worker # new line like "Missing class ...". 143*8975f5c5SAndroid Build Coastguard Worker warnings = re.split(r'^(?=Warning|Error|Missing (?:class|field|method))', 144*8975f5c5SAndroid Build Coastguard Worker output, 145*8975f5c5SAndroid Build Coastguard Worker flags=re.MULTILINE) 146*8975f5c5SAndroid Build Coastguard Worker preamble, *warnings = warnings 147*8975f5c5SAndroid Build Coastguard Worker 148*8975f5c5SAndroid Build Coastguard Worker combined_pattern = '|'.join(filters) 149*8975f5c5SAndroid Build Coastguard Worker preamble = build_utils.FilterLines(preamble, combined_pattern) 150*8975f5c5SAndroid Build Coastguard Worker 151*8975f5c5SAndroid Build Coastguard Worker compiled_re = re.compile(combined_pattern, re.DOTALL) 152*8975f5c5SAndroid Build Coastguard Worker warnings = [w for w in warnings if not compiled_re.search(w)] 153*8975f5c5SAndroid Build Coastguard Worker 154*8975f5c5SAndroid Build Coastguard Worker return preamble + ''.join(warnings) 155*8975f5c5SAndroid Build Coastguard Worker 156*8975f5c5SAndroid Build Coastguard Worker return filter_stderr 157*8975f5c5SAndroid Build Coastguard Worker 158*8975f5c5SAndroid Build Coastguard Worker 159*8975f5c5SAndroid Build Coastguard Workerdef _RunD8(dex_cmd, input_paths, output_path, warnings_as_errors, 160*8975f5c5SAndroid Build Coastguard Worker show_desugar_default_interface_warnings): 161*8975f5c5SAndroid Build Coastguard Worker dex_cmd = dex_cmd + ['--output', output_path] + input_paths 162*8975f5c5SAndroid Build Coastguard Worker 163*8975f5c5SAndroid Build Coastguard Worker # Missing deps can happen for prebuilts that are missing transitive deps 164*8975f5c5SAndroid Build Coastguard Worker # and have set enable_bytecode_checks=false. 165*8975f5c5SAndroid Build Coastguard Worker filters = list(DEFAULT_IGNORE_WARNINGS) 166*8975f5c5SAndroid Build Coastguard Worker if not show_desugar_default_interface_warnings: 167*8975f5c5SAndroid Build Coastguard Worker filters += INTERFACE_DESUGARING_WARNINGS 168*8975f5c5SAndroid Build Coastguard Worker 169*8975f5c5SAndroid Build Coastguard Worker stderr_filter = CreateStderrFilter(filters) 170*8975f5c5SAndroid Build Coastguard Worker 171*8975f5c5SAndroid Build Coastguard Worker is_debug = logging.getLogger().isEnabledFor(logging.DEBUG) 172*8975f5c5SAndroid Build Coastguard Worker 173*8975f5c5SAndroid Build Coastguard Worker # Avoid deleting the flag file when DEX_DEBUG is set in case the flag file 174*8975f5c5SAndroid Build Coastguard Worker # needs to be examined after the build. 175*8975f5c5SAndroid Build Coastguard Worker with tempfile.NamedTemporaryFile(mode='w', delete=not is_debug) as flag_file: 176*8975f5c5SAndroid Build Coastguard Worker # Chosen arbitrarily. Needed to avoid command-line length limits. 177*8975f5c5SAndroid Build Coastguard Worker MAX_ARGS = 50 178*8975f5c5SAndroid Build Coastguard Worker orig_dex_cmd = dex_cmd 179*8975f5c5SAndroid Build Coastguard Worker if len(dex_cmd) > MAX_ARGS: 180*8975f5c5SAndroid Build Coastguard Worker # Add all flags to D8 (anything after the first --) as well as all 181*8975f5c5SAndroid Build Coastguard Worker # positional args at the end to the flag file. 182*8975f5c5SAndroid Build Coastguard Worker for idx, cmd in enumerate(dex_cmd): 183*8975f5c5SAndroid Build Coastguard Worker if cmd.startswith('--'): 184*8975f5c5SAndroid Build Coastguard Worker flag_file.write('\n'.join(dex_cmd[idx:])) 185*8975f5c5SAndroid Build Coastguard Worker flag_file.flush() 186*8975f5c5SAndroid Build Coastguard Worker dex_cmd = dex_cmd[:idx] 187*8975f5c5SAndroid Build Coastguard Worker dex_cmd.append('@' + flag_file.name) 188*8975f5c5SAndroid Build Coastguard Worker break 189*8975f5c5SAndroid Build Coastguard Worker 190*8975f5c5SAndroid Build Coastguard Worker # stdout sometimes spams with things like: 191*8975f5c5SAndroid Build Coastguard Worker # Stripped invalid locals information from 1 method. 192*8975f5c5SAndroid Build Coastguard Worker try: 193*8975f5c5SAndroid Build Coastguard Worker build_utils.CheckOutput(dex_cmd, 194*8975f5c5SAndroid Build Coastguard Worker stderr_filter=stderr_filter, 195*8975f5c5SAndroid Build Coastguard Worker fail_on_output=warnings_as_errors) 196*8975f5c5SAndroid Build Coastguard Worker except Exception as e: 197*8975f5c5SAndroid Build Coastguard Worker if isinstance(e, build_utils.CalledProcessError): 198*8975f5c5SAndroid Build Coastguard Worker output = e.output # pylint: disable=no-member 199*8975f5c5SAndroid Build Coastguard Worker if "global synthetic for 'Record desugaring'" in output: 200*8975f5c5SAndroid Build Coastguard Worker sys.stderr.write('Java records are not supported.\n') 201*8975f5c5SAndroid Build Coastguard Worker sys.stderr.write( 202*8975f5c5SAndroid Build Coastguard Worker 'See https://chromium.googlesource.com/chromium/src/+/' + 203*8975f5c5SAndroid Build Coastguard Worker 'main/styleguide/java/java.md#Records\n') 204*8975f5c5SAndroid Build Coastguard Worker sys.exit(1) 205*8975f5c5SAndroid Build Coastguard Worker if orig_dex_cmd is not dex_cmd: 206*8975f5c5SAndroid Build Coastguard Worker sys.stderr.write('Full command: ' + shlex.join(orig_dex_cmd) + '\n') 207*8975f5c5SAndroid Build Coastguard Worker raise 208*8975f5c5SAndroid Build Coastguard Worker 209*8975f5c5SAndroid Build Coastguard Worker 210*8975f5c5SAndroid Build Coastguard Workerdef _ZipAligned(dex_files, output_path, services_map): 211*8975f5c5SAndroid Build Coastguard Worker """Creates a .dex.jar with 4-byte aligned files. 212*8975f5c5SAndroid Build Coastguard Worker 213*8975f5c5SAndroid Build Coastguard Worker Args: 214*8975f5c5SAndroid Build Coastguard Worker dex_files: List of dex files. 215*8975f5c5SAndroid Build Coastguard Worker output_path: The output file in which to write the zip. 216*8975f5c5SAndroid Build Coastguard Worker services_map: map of path->data for META-INF/services 217*8975f5c5SAndroid Build Coastguard Worker """ 218*8975f5c5SAndroid Build Coastguard Worker with zipfile.ZipFile(output_path, 'w') as z: 219*8975f5c5SAndroid Build Coastguard Worker for i, dex_file in enumerate(dex_files): 220*8975f5c5SAndroid Build Coastguard Worker name = 'classes{}.dex'.format(i + 1 if i > 0 else '') 221*8975f5c5SAndroid Build Coastguard Worker zip_helpers.add_to_zip_hermetic(z, name, src_path=dex_file, alignment=4) 222*8975f5c5SAndroid Build Coastguard Worker for path, data in sorted(services_map.items()): 223*8975f5c5SAndroid Build Coastguard Worker zip_helpers.add_to_zip_hermetic(z, path, data=data, alignment=4) 224*8975f5c5SAndroid Build Coastguard Worker 225*8975f5c5SAndroid Build Coastguard Worker 226*8975f5c5SAndroid Build Coastguard Workerdef _CreateServicesMap(service_jars): 227*8975f5c5SAndroid Build Coastguard Worker ret = {} 228*8975f5c5SAndroid Build Coastguard Worker origins = {} 229*8975f5c5SAndroid Build Coastguard Worker for jar_path in service_jars: 230*8975f5c5SAndroid Build Coastguard Worker with zipfile.ZipFile(jar_path, 'r') as z: 231*8975f5c5SAndroid Build Coastguard Worker for n in z.namelist(): 232*8975f5c5SAndroid Build Coastguard Worker if n.startswith('META-INF/services/') and not n.endswith('/'): 233*8975f5c5SAndroid Build Coastguard Worker if n in _IGNORE_SERVICE_ENTRIES: 234*8975f5c5SAndroid Build Coastguard Worker continue 235*8975f5c5SAndroid Build Coastguard Worker data = z.read(n) 236*8975f5c5SAndroid Build Coastguard Worker if ret.get(n, data) == data: 237*8975f5c5SAndroid Build Coastguard Worker ret[n] = data 238*8975f5c5SAndroid Build Coastguard Worker origins[n] = jar_path 239*8975f5c5SAndroid Build Coastguard Worker else: 240*8975f5c5SAndroid Build Coastguard Worker # We should arguably just concat the files here, but Chrome's own 241*8975f5c5SAndroid Build Coastguard Worker # uses (via ServiceLoaderUtil) all assume only one entry. 242*8975f5c5SAndroid Build Coastguard Worker raise Exception(f"""\ 243*8975f5c5SAndroid Build Coastguard WorkerConflicting contents for: {n} 244*8975f5c5SAndroid Build Coastguard Worker{origins[n]}: 245*8975f5c5SAndroid Build Coastguard Worker{ret[n]} 246*8975f5c5SAndroid Build Coastguard Worker{jar_path}: 247*8975f5c5SAndroid Build Coastguard Worker{data} 248*8975f5c5SAndroid Build Coastguard Worker 249*8975f5c5SAndroid Build Coastguard WorkerIf this entry can be safely ignored (because the ServiceLoader.load() call is \ 250*8975f5c5SAndroid Build Coastguard Workernever hit), update _IGNORE_SERVICE_ENTRIES in dex.py. 251*8975f5c5SAndroid Build Coastguard Worker""") 252*8975f5c5SAndroid Build Coastguard Worker return ret 253*8975f5c5SAndroid Build Coastguard Worker 254*8975f5c5SAndroid Build Coastguard Worker 255*8975f5c5SAndroid Build Coastguard Workerdef _CreateFinalDex(d8_inputs, 256*8975f5c5SAndroid Build Coastguard Worker output, 257*8975f5c5SAndroid Build Coastguard Worker tmp_dir, 258*8975f5c5SAndroid Build Coastguard Worker dex_cmd, 259*8975f5c5SAndroid Build Coastguard Worker options=None, 260*8975f5c5SAndroid Build Coastguard Worker service_jars=None): 261*8975f5c5SAndroid Build Coastguard Worker tmp_dex_output = os.path.join(tmp_dir, 'tmp_dex_output.zip') 262*8975f5c5SAndroid Build Coastguard Worker needs_dexing = not all(f.endswith('.dex') for f in d8_inputs) 263*8975f5c5SAndroid Build Coastguard Worker needs_dexmerge = output.endswith('.dex') or not (options and options.library) 264*8975f5c5SAndroid Build Coastguard Worker services_map = _CreateServicesMap(service_jars or []) 265*8975f5c5SAndroid Build Coastguard Worker if needs_dexing or needs_dexmerge: 266*8975f5c5SAndroid Build Coastguard Worker tmp_dex_dir = os.path.join(tmp_dir, 'tmp_dex_dir') 267*8975f5c5SAndroid Build Coastguard Worker os.mkdir(tmp_dex_dir) 268*8975f5c5SAndroid Build Coastguard Worker 269*8975f5c5SAndroid Build Coastguard Worker _RunD8(dex_cmd, d8_inputs, tmp_dex_dir, 270*8975f5c5SAndroid Build Coastguard Worker (not options or options.warnings_as_errors), 271*8975f5c5SAndroid Build Coastguard Worker (options and options.show_desugar_default_interface_warnings)) 272*8975f5c5SAndroid Build Coastguard Worker logging.debug('Performed dex merging') 273*8975f5c5SAndroid Build Coastguard Worker 274*8975f5c5SAndroid Build Coastguard Worker dex_files = [os.path.join(tmp_dex_dir, f) for f in os.listdir(tmp_dex_dir)] 275*8975f5c5SAndroid Build Coastguard Worker 276*8975f5c5SAndroid Build Coastguard Worker if output.endswith('.dex'): 277*8975f5c5SAndroid Build Coastguard Worker if len(dex_files) > 1: 278*8975f5c5SAndroid Build Coastguard Worker raise Exception('%d files created, expected 1' % len(dex_files)) 279*8975f5c5SAndroid Build Coastguard Worker tmp_dex_output = dex_files[0] 280*8975f5c5SAndroid Build Coastguard Worker else: 281*8975f5c5SAndroid Build Coastguard Worker _ZipAligned(sorted(dex_files), tmp_dex_output, services_map) 282*8975f5c5SAndroid Build Coastguard Worker else: 283*8975f5c5SAndroid Build Coastguard Worker # Skip dexmerger. Just put all incrementals into the .jar individually. 284*8975f5c5SAndroid Build Coastguard Worker _ZipAligned(sorted(d8_inputs), tmp_dex_output, services_map) 285*8975f5c5SAndroid Build Coastguard Worker logging.debug('Quick-zipped %d files', len(d8_inputs)) 286*8975f5c5SAndroid Build Coastguard Worker 287*8975f5c5SAndroid Build Coastguard Worker # The dex file is complete and can be moved out of tmp_dir. 288*8975f5c5SAndroid Build Coastguard Worker shutil.move(tmp_dex_output, output) 289*8975f5c5SAndroid Build Coastguard Worker 290*8975f5c5SAndroid Build Coastguard Worker 291*8975f5c5SAndroid Build Coastguard Workerdef _IntermediateDexFilePathsFromInputJars(class_inputs, incremental_dir): 292*8975f5c5SAndroid Build Coastguard Worker """Returns list of intermediate dex file paths, .jar files with services.""" 293*8975f5c5SAndroid Build Coastguard Worker dex_files = [] 294*8975f5c5SAndroid Build Coastguard Worker service_jars = set() 295*8975f5c5SAndroid Build Coastguard Worker for jar in class_inputs: 296*8975f5c5SAndroid Build Coastguard Worker with zipfile.ZipFile(jar, 'r') as z: 297*8975f5c5SAndroid Build Coastguard Worker for subpath in z.namelist(): 298*8975f5c5SAndroid Build Coastguard Worker if _IsClassFile(subpath): 299*8975f5c5SAndroid Build Coastguard Worker subpath = subpath[:-5] + 'dex' 300*8975f5c5SAndroid Build Coastguard Worker dex_files.append(os.path.join(incremental_dir, subpath)) 301*8975f5c5SAndroid Build Coastguard Worker elif subpath.startswith('META-INF/services/'): 302*8975f5c5SAndroid Build Coastguard Worker service_jars.add(jar) 303*8975f5c5SAndroid Build Coastguard Worker return dex_files, sorted(service_jars) 304*8975f5c5SAndroid Build Coastguard Worker 305*8975f5c5SAndroid Build Coastguard Worker 306*8975f5c5SAndroid Build Coastguard Workerdef _DeleteStaleIncrementalDexFiles(dex_dir, dex_files): 307*8975f5c5SAndroid Build Coastguard Worker """Deletes intermediate .dex files that are no longer needed.""" 308*8975f5c5SAndroid Build Coastguard Worker all_files = build_utils.FindInDirectory(dex_dir) 309*8975f5c5SAndroid Build Coastguard Worker desired_files = set(dex_files) 310*8975f5c5SAndroid Build Coastguard Worker for path in all_files: 311*8975f5c5SAndroid Build Coastguard Worker if path not in desired_files: 312*8975f5c5SAndroid Build Coastguard Worker os.unlink(path) 313*8975f5c5SAndroid Build Coastguard Worker 314*8975f5c5SAndroid Build Coastguard Worker 315*8975f5c5SAndroid Build Coastguard Workerdef _ParseDesugarDeps(desugar_dependencies_file): 316*8975f5c5SAndroid Build Coastguard Worker # pylint: disable=line-too-long 317*8975f5c5SAndroid Build Coastguard Worker """Returns a dict of dependent/dependency mapping parsed from the file. 318*8975f5c5SAndroid Build Coastguard Worker 319*8975f5c5SAndroid Build Coastguard Worker Example file format: 320*8975f5c5SAndroid Build Coastguard Worker $ tail out/Debug/gen/base/base_java__dex.desugardeps 321*8975f5c5SAndroid Build Coastguard Worker org/chromium/base/task/SingleThreadTaskRunnerImpl.class 322*8975f5c5SAndroid Build Coastguard Worker <- org/chromium/base/task/SingleThreadTaskRunner.class 323*8975f5c5SAndroid Build Coastguard Worker <- org/chromium/base/task/TaskRunnerImpl.class 324*8975f5c5SAndroid Build Coastguard Worker org/chromium/base/task/TaskRunnerImpl.class 325*8975f5c5SAndroid Build Coastguard Worker <- org/chromium/base/task/TaskRunner.class 326*8975f5c5SAndroid Build Coastguard Worker org/chromium/base/task/TaskRunnerImplJni$1.class 327*8975f5c5SAndroid Build Coastguard Worker <- obj/base/jni_java.turbine.jar:org/jni_zero/JniStaticTestMocker.class 328*8975f5c5SAndroid Build Coastguard Worker org/chromium/base/task/TaskRunnerImplJni.class 329*8975f5c5SAndroid Build Coastguard Worker <- org/chromium/base/task/TaskRunnerImpl$Natives.class 330*8975f5c5SAndroid Build Coastguard Worker """ 331*8975f5c5SAndroid Build Coastguard Worker # pylint: enable=line-too-long 332*8975f5c5SAndroid Build Coastguard Worker dependents_from_dependency = collections.defaultdict(set) 333*8975f5c5SAndroid Build Coastguard Worker if desugar_dependencies_file and os.path.exists(desugar_dependencies_file): 334*8975f5c5SAndroid Build Coastguard Worker with open(desugar_dependencies_file, 'r') as f: 335*8975f5c5SAndroid Build Coastguard Worker dependent = None 336*8975f5c5SAndroid Build Coastguard Worker for line in f: 337*8975f5c5SAndroid Build Coastguard Worker line = line.rstrip() 338*8975f5c5SAndroid Build Coastguard Worker if line.startswith(' <- '): 339*8975f5c5SAndroid Build Coastguard Worker dependency = line[len(' <- '):] 340*8975f5c5SAndroid Build Coastguard Worker # Note that this is a reversed mapping from the one in CustomD8.java. 341*8975f5c5SAndroid Build Coastguard Worker dependents_from_dependency[dependency].add(dependent) 342*8975f5c5SAndroid Build Coastguard Worker else: 343*8975f5c5SAndroid Build Coastguard Worker dependent = line 344*8975f5c5SAndroid Build Coastguard Worker return dependents_from_dependency 345*8975f5c5SAndroid Build Coastguard Worker 346*8975f5c5SAndroid Build Coastguard Worker 347*8975f5c5SAndroid Build Coastguard Workerdef _ComputeRequiredDesugarClasses(changes, desugar_dependencies_file, 348*8975f5c5SAndroid Build Coastguard Worker class_inputs, classpath): 349*8975f5c5SAndroid Build Coastguard Worker dependents_from_dependency = _ParseDesugarDeps(desugar_dependencies_file) 350*8975f5c5SAndroid Build Coastguard Worker required_classes = set() 351*8975f5c5SAndroid Build Coastguard Worker # Gather classes that need to be re-desugared from changes in the classpath. 352*8975f5c5SAndroid Build Coastguard Worker for jar in classpath: 353*8975f5c5SAndroid Build Coastguard Worker for subpath in changes.IterChangedSubpaths(jar): 354*8975f5c5SAndroid Build Coastguard Worker dependency = '{}:{}'.format(jar, subpath) 355*8975f5c5SAndroid Build Coastguard Worker required_classes.update(dependents_from_dependency[dependency]) 356*8975f5c5SAndroid Build Coastguard Worker 357*8975f5c5SAndroid Build Coastguard Worker for jar in class_inputs: 358*8975f5c5SAndroid Build Coastguard Worker for subpath in changes.IterChangedSubpaths(jar): 359*8975f5c5SAndroid Build Coastguard Worker required_classes.update(dependents_from_dependency[subpath]) 360*8975f5c5SAndroid Build Coastguard Worker 361*8975f5c5SAndroid Build Coastguard Worker return required_classes 362*8975f5c5SAndroid Build Coastguard Worker 363*8975f5c5SAndroid Build Coastguard Worker 364*8975f5c5SAndroid Build Coastguard Workerdef _IsClassFile(path): 365*8975f5c5SAndroid Build Coastguard Worker if os.path.basename(path) in _SKIPPED_CLASS_FILE_NAMES: 366*8975f5c5SAndroid Build Coastguard Worker return False 367*8975f5c5SAndroid Build Coastguard Worker return path.endswith('.class') 368*8975f5c5SAndroid Build Coastguard Worker 369*8975f5c5SAndroid Build Coastguard Worker 370*8975f5c5SAndroid Build Coastguard Workerdef _ExtractClassFiles(changes, tmp_dir, class_inputs, required_classes_set): 371*8975f5c5SAndroid Build Coastguard Worker classes_list = [] 372*8975f5c5SAndroid Build Coastguard Worker for jar in class_inputs: 373*8975f5c5SAndroid Build Coastguard Worker if changes: 374*8975f5c5SAndroid Build Coastguard Worker changed_class_list = (set(changes.IterChangedSubpaths(jar)) 375*8975f5c5SAndroid Build Coastguard Worker | required_classes_set) 376*8975f5c5SAndroid Build Coastguard Worker predicate = lambda x: x in changed_class_list and _IsClassFile(x) 377*8975f5c5SAndroid Build Coastguard Worker else: 378*8975f5c5SAndroid Build Coastguard Worker predicate = _IsClassFile 379*8975f5c5SAndroid Build Coastguard Worker 380*8975f5c5SAndroid Build Coastguard Worker classes_list.extend( 381*8975f5c5SAndroid Build Coastguard Worker build_utils.ExtractAll(jar, path=tmp_dir, predicate=predicate)) 382*8975f5c5SAndroid Build Coastguard Worker return classes_list 383*8975f5c5SAndroid Build Coastguard Worker 384*8975f5c5SAndroid Build Coastguard Worker 385*8975f5c5SAndroid Build Coastguard Workerdef _CreateIntermediateDexFiles(changes, options, tmp_dir, dex_cmd): 386*8975f5c5SAndroid Build Coastguard Worker # Create temporary directory for classes to be extracted to. 387*8975f5c5SAndroid Build Coastguard Worker tmp_extract_dir = os.path.join(tmp_dir, 'tmp_extract_dir') 388*8975f5c5SAndroid Build Coastguard Worker os.mkdir(tmp_extract_dir) 389*8975f5c5SAndroid Build Coastguard Worker 390*8975f5c5SAndroid Build Coastguard Worker # Do a full rebuild when changes occur in non-input files. 391*8975f5c5SAndroid Build Coastguard Worker allowed_changed = set(options.class_inputs) 392*8975f5c5SAndroid Build Coastguard Worker allowed_changed.update(options.dex_inputs) 393*8975f5c5SAndroid Build Coastguard Worker allowed_changed.update(options.classpath) 394*8975f5c5SAndroid Build Coastguard Worker strings_changed = changes.HasStringChanges() 395*8975f5c5SAndroid Build Coastguard Worker non_direct_input_changed = next( 396*8975f5c5SAndroid Build Coastguard Worker (p for p in changes.IterChangedPaths() if p not in allowed_changed), None) 397*8975f5c5SAndroid Build Coastguard Worker 398*8975f5c5SAndroid Build Coastguard Worker if strings_changed or non_direct_input_changed: 399*8975f5c5SAndroid Build Coastguard Worker logging.debug('Full dex required: strings_changed=%s path_changed=%s', 400*8975f5c5SAndroid Build Coastguard Worker strings_changed, non_direct_input_changed) 401*8975f5c5SAndroid Build Coastguard Worker changes = None 402*8975f5c5SAndroid Build Coastguard Worker 403*8975f5c5SAndroid Build Coastguard Worker if changes is None: 404*8975f5c5SAndroid Build Coastguard Worker required_desugar_classes_set = set() 405*8975f5c5SAndroid Build Coastguard Worker else: 406*8975f5c5SAndroid Build Coastguard Worker required_desugar_classes_set = _ComputeRequiredDesugarClasses( 407*8975f5c5SAndroid Build Coastguard Worker changes, options.desugar_dependencies, options.class_inputs, 408*8975f5c5SAndroid Build Coastguard Worker options.classpath) 409*8975f5c5SAndroid Build Coastguard Worker logging.debug('Class files needing re-desugar: %d', 410*8975f5c5SAndroid Build Coastguard Worker len(required_desugar_classes_set)) 411*8975f5c5SAndroid Build Coastguard Worker class_files = _ExtractClassFiles(changes, tmp_extract_dir, 412*8975f5c5SAndroid Build Coastguard Worker options.class_inputs, 413*8975f5c5SAndroid Build Coastguard Worker required_desugar_classes_set) 414*8975f5c5SAndroid Build Coastguard Worker logging.debug('Extracted class files: %d', len(class_files)) 415*8975f5c5SAndroid Build Coastguard Worker 416*8975f5c5SAndroid Build Coastguard Worker # If the only change is deleting a file, class_files will be empty. 417*8975f5c5SAndroid Build Coastguard Worker if class_files: 418*8975f5c5SAndroid Build Coastguard Worker # Dex necessary classes into intermediate dex files. 419*8975f5c5SAndroid Build Coastguard Worker dex_cmd = dex_cmd + ['--intermediate', '--file-per-class-file'] 420*8975f5c5SAndroid Build Coastguard Worker if options.desugar_dependencies and not options.skip_custom_d8: 421*8975f5c5SAndroid Build Coastguard Worker # Adding os.sep to remove the entire prefix. 422*8975f5c5SAndroid Build Coastguard Worker dex_cmd += ['--file-tmp-prefix', tmp_extract_dir + os.sep] 423*8975f5c5SAndroid Build Coastguard Worker if changes is None and os.path.exists(options.desugar_dependencies): 424*8975f5c5SAndroid Build Coastguard Worker # Since incremental dexing only ever adds to the desugar_dependencies 425*8975f5c5SAndroid Build Coastguard Worker # file, whenever full dexes are required the .desugardeps files need to 426*8975f5c5SAndroid Build Coastguard Worker # be manually removed. 427*8975f5c5SAndroid Build Coastguard Worker os.unlink(options.desugar_dependencies) 428*8975f5c5SAndroid Build Coastguard Worker _RunD8(dex_cmd, class_files, options.incremental_dir, 429*8975f5c5SAndroid Build Coastguard Worker options.warnings_as_errors, 430*8975f5c5SAndroid Build Coastguard Worker options.show_desugar_default_interface_warnings) 431*8975f5c5SAndroid Build Coastguard Worker logging.debug('Dexed class files.') 432*8975f5c5SAndroid Build Coastguard Worker 433*8975f5c5SAndroid Build Coastguard Worker 434*8975f5c5SAndroid Build Coastguard Workerdef _OnStaleMd5(changes, options, final_dex_inputs, service_jars, dex_cmd): 435*8975f5c5SAndroid Build Coastguard Worker logging.debug('_OnStaleMd5') 436*8975f5c5SAndroid Build Coastguard Worker with build_utils.TempDir() as tmp_dir: 437*8975f5c5SAndroid Build Coastguard Worker if options.incremental_dir: 438*8975f5c5SAndroid Build Coastguard Worker # Create directory for all intermediate dex files. 439*8975f5c5SAndroid Build Coastguard Worker if not os.path.exists(options.incremental_dir): 440*8975f5c5SAndroid Build Coastguard Worker os.makedirs(options.incremental_dir) 441*8975f5c5SAndroid Build Coastguard Worker 442*8975f5c5SAndroid Build Coastguard Worker _DeleteStaleIncrementalDexFiles(options.incremental_dir, final_dex_inputs) 443*8975f5c5SAndroid Build Coastguard Worker logging.debug('Stale files deleted') 444*8975f5c5SAndroid Build Coastguard Worker _CreateIntermediateDexFiles(changes, options, tmp_dir, dex_cmd) 445*8975f5c5SAndroid Build Coastguard Worker 446*8975f5c5SAndroid Build Coastguard Worker _CreateFinalDex(final_dex_inputs, 447*8975f5c5SAndroid Build Coastguard Worker options.output, 448*8975f5c5SAndroid Build Coastguard Worker tmp_dir, 449*8975f5c5SAndroid Build Coastguard Worker dex_cmd, 450*8975f5c5SAndroid Build Coastguard Worker options=options, 451*8975f5c5SAndroid Build Coastguard Worker service_jars=service_jars) 452*8975f5c5SAndroid Build Coastguard Worker 453*8975f5c5SAndroid Build Coastguard Worker 454*8975f5c5SAndroid Build Coastguard Workerdef MergeDexForIncrementalInstall(r8_jar_path, src_paths, dest_dex_jar, 455*8975f5c5SAndroid Build Coastguard Worker min_api): 456*8975f5c5SAndroid Build Coastguard Worker dex_cmd = build_utils.JavaCmd(xmx=_DEX_XMX) + [ 457*8975f5c5SAndroid Build Coastguard Worker '-cp', 458*8975f5c5SAndroid Build Coastguard Worker r8_jar_path, 459*8975f5c5SAndroid Build Coastguard Worker 'com.android.tools.r8.D8', 460*8975f5c5SAndroid Build Coastguard Worker '--min-api', 461*8975f5c5SAndroid Build Coastguard Worker min_api, 462*8975f5c5SAndroid Build Coastguard Worker ] 463*8975f5c5SAndroid Build Coastguard Worker with build_utils.TempDir() as tmp_dir: 464*8975f5c5SAndroid Build Coastguard Worker _CreateFinalDex(src_paths, 465*8975f5c5SAndroid Build Coastguard Worker dest_dex_jar, 466*8975f5c5SAndroid Build Coastguard Worker tmp_dir, 467*8975f5c5SAndroid Build Coastguard Worker dex_cmd, 468*8975f5c5SAndroid Build Coastguard Worker service_jars=src_paths) 469*8975f5c5SAndroid Build Coastguard Worker 470*8975f5c5SAndroid Build Coastguard Worker 471*8975f5c5SAndroid Build Coastguard Workerdef main(args): 472*8975f5c5SAndroid Build Coastguard Worker build_utils.InitLogging('DEX_DEBUG') 473*8975f5c5SAndroid Build Coastguard Worker options = _ParseArgs(args) 474*8975f5c5SAndroid Build Coastguard Worker 475*8975f5c5SAndroid Build Coastguard Worker options.class_inputs += options.class_inputs_filearg 476*8975f5c5SAndroid Build Coastguard Worker options.dex_inputs += options.dex_inputs_filearg 477*8975f5c5SAndroid Build Coastguard Worker 478*8975f5c5SAndroid Build Coastguard Worker input_paths = ([ 479*8975f5c5SAndroid Build Coastguard Worker build_utils.JAVA_PATH_FOR_INPUTS, options.r8_jar_path, 480*8975f5c5SAndroid Build Coastguard Worker options.custom_d8_jar_path 481*8975f5c5SAndroid Build Coastguard Worker ] + options.class_inputs + options.dex_inputs) 482*8975f5c5SAndroid Build Coastguard Worker 483*8975f5c5SAndroid Build Coastguard Worker depfile_deps = options.class_inputs_filearg + options.dex_inputs_filearg 484*8975f5c5SAndroid Build Coastguard Worker 485*8975f5c5SAndroid Build Coastguard Worker output_paths = [options.output] 486*8975f5c5SAndroid Build Coastguard Worker 487*8975f5c5SAndroid Build Coastguard Worker track_subpaths_allowlist = [] 488*8975f5c5SAndroid Build Coastguard Worker if options.incremental_dir: 489*8975f5c5SAndroid Build Coastguard Worker final_dex_inputs, service_jars = _IntermediateDexFilePathsFromInputJars( 490*8975f5c5SAndroid Build Coastguard Worker options.class_inputs, options.incremental_dir) 491*8975f5c5SAndroid Build Coastguard Worker output_paths += final_dex_inputs 492*8975f5c5SAndroid Build Coastguard Worker track_subpaths_allowlist += options.class_inputs 493*8975f5c5SAndroid Build Coastguard Worker else: 494*8975f5c5SAndroid Build Coastguard Worker final_dex_inputs = list(options.class_inputs) 495*8975f5c5SAndroid Build Coastguard Worker service_jars = final_dex_inputs 496*8975f5c5SAndroid Build Coastguard Worker service_jars += options.dex_inputs 497*8975f5c5SAndroid Build Coastguard Worker final_dex_inputs += options.dex_inputs 498*8975f5c5SAndroid Build Coastguard Worker 499*8975f5c5SAndroid Build Coastguard Worker dex_cmd = build_utils.JavaCmd(xmx=_DEX_XMX) 500*8975f5c5SAndroid Build Coastguard Worker 501*8975f5c5SAndroid Build Coastguard Worker if options.dump_inputs: 502*8975f5c5SAndroid Build Coastguard Worker dex_cmd += ['-Dcom.android.tools.r8.dumpinputtofile=d8inputs.zip'] 503*8975f5c5SAndroid Build Coastguard Worker 504*8975f5c5SAndroid Build Coastguard Worker if not options.skip_custom_d8: 505*8975f5c5SAndroid Build Coastguard Worker dex_cmd += [ 506*8975f5c5SAndroid Build Coastguard Worker '-cp', 507*8975f5c5SAndroid Build Coastguard Worker '{}:{}'.format(options.r8_jar_path, options.custom_d8_jar_path), 508*8975f5c5SAndroid Build Coastguard Worker 'org.chromium.build.CustomD8', 509*8975f5c5SAndroid Build Coastguard Worker ] 510*8975f5c5SAndroid Build Coastguard Worker else: 511*8975f5c5SAndroid Build Coastguard Worker dex_cmd += [ 512*8975f5c5SAndroid Build Coastguard Worker '-cp', 513*8975f5c5SAndroid Build Coastguard Worker options.r8_jar_path, 514*8975f5c5SAndroid Build Coastguard Worker 'com.android.tools.r8.D8', 515*8975f5c5SAndroid Build Coastguard Worker ] 516*8975f5c5SAndroid Build Coastguard Worker 517*8975f5c5SAndroid Build Coastguard Worker if options.release: 518*8975f5c5SAndroid Build Coastguard Worker dex_cmd += ['--release'] 519*8975f5c5SAndroid Build Coastguard Worker if options.min_api: 520*8975f5c5SAndroid Build Coastguard Worker dex_cmd += ['--min-api', options.min_api] 521*8975f5c5SAndroid Build Coastguard Worker 522*8975f5c5SAndroid Build Coastguard Worker if not options.desugar: 523*8975f5c5SAndroid Build Coastguard Worker dex_cmd += ['--no-desugaring'] 524*8975f5c5SAndroid Build Coastguard Worker elif options.classpath: 525*8975f5c5SAndroid Build Coastguard Worker # The classpath is used by D8 to for interface desugaring. 526*8975f5c5SAndroid Build Coastguard Worker if options.desugar_dependencies and not options.skip_custom_d8: 527*8975f5c5SAndroid Build Coastguard Worker dex_cmd += ['--desugar-dependencies', options.desugar_dependencies] 528*8975f5c5SAndroid Build Coastguard Worker if track_subpaths_allowlist: 529*8975f5c5SAndroid Build Coastguard Worker track_subpaths_allowlist += options.classpath 530*8975f5c5SAndroid Build Coastguard Worker depfile_deps += options.classpath 531*8975f5c5SAndroid Build Coastguard Worker input_paths += options.classpath 532*8975f5c5SAndroid Build Coastguard Worker # Still pass the entire classpath in case a new dependency is needed by 533*8975f5c5SAndroid Build Coastguard Worker # desugar, so that desugar_dependencies will be updated for the next build. 534*8975f5c5SAndroid Build Coastguard Worker for path in options.classpath: 535*8975f5c5SAndroid Build Coastguard Worker dex_cmd += ['--classpath', path] 536*8975f5c5SAndroid Build Coastguard Worker 537*8975f5c5SAndroid Build Coastguard Worker if options.classpath: 538*8975f5c5SAndroid Build Coastguard Worker dex_cmd += ['--lib', build_utils.JAVA_HOME] 539*8975f5c5SAndroid Build Coastguard Worker for path in options.bootclasspath: 540*8975f5c5SAndroid Build Coastguard Worker dex_cmd += ['--lib', path] 541*8975f5c5SAndroid Build Coastguard Worker depfile_deps += options.bootclasspath 542*8975f5c5SAndroid Build Coastguard Worker input_paths += options.bootclasspath 543*8975f5c5SAndroid Build Coastguard Worker 544*8975f5c5SAndroid Build Coastguard Worker 545*8975f5c5SAndroid Build Coastguard Worker if options.assertion_handler: 546*8975f5c5SAndroid Build Coastguard Worker dex_cmd += ['--force-assertions-handler:' + options.assertion_handler] 547*8975f5c5SAndroid Build Coastguard Worker if options.force_enable_assertions: 548*8975f5c5SAndroid Build Coastguard Worker dex_cmd += ['--force-enable-assertions'] 549*8975f5c5SAndroid Build Coastguard Worker 550*8975f5c5SAndroid Build Coastguard Worker # The changes feature from md5_check allows us to only re-dex the class files 551*8975f5c5SAndroid Build Coastguard Worker # that have changed and the class files that need to be re-desugared by D8. 552*8975f5c5SAndroid Build Coastguard Worker md5_check.CallAndWriteDepfileIfStale( 553*8975f5c5SAndroid Build Coastguard Worker lambda changes: _OnStaleMd5(changes, options, final_dex_inputs, 554*8975f5c5SAndroid Build Coastguard Worker service_jars, dex_cmd), 555*8975f5c5SAndroid Build Coastguard Worker options, 556*8975f5c5SAndroid Build Coastguard Worker input_paths=input_paths, 557*8975f5c5SAndroid Build Coastguard Worker input_strings=dex_cmd + [str(bool(options.incremental_dir))], 558*8975f5c5SAndroid Build Coastguard Worker output_paths=output_paths, 559*8975f5c5SAndroid Build Coastguard Worker pass_changes=True, 560*8975f5c5SAndroid Build Coastguard Worker track_subpaths_allowlist=track_subpaths_allowlist, 561*8975f5c5SAndroid Build Coastguard Worker depfile_deps=depfile_deps) 562*8975f5c5SAndroid Build Coastguard Worker 563*8975f5c5SAndroid Build Coastguard Worker 564*8975f5c5SAndroid Build Coastguard Workerif __name__ == '__main__': 565*8975f5c5SAndroid Build Coastguard Worker sys.exit(main(sys.argv[1:])) 566