blob: 691bdeb2400ee93d5fcb2a634bbdb5870e255592 [file] [log] [blame]
Ian Zernydcb172e2022-02-22 15:36:45 +01001#!/usr/bin/env python3
Ian Zerny5ffa58f2020-02-26 08:37:14 +01002# Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
3# for details. All rights reserved. Use of this source code is governed by a
4# BSD-style license that can be found in the LICENSE file.
5
6import argparse
7import os
8import subprocess
9import sys
10import zipfile
11
Ian Zerny0e53ff12021-06-15 13:40:14 +020012import archive
13import jdk
14import retrace
Ian Zerny5ffa58f2020-02-26 08:37:14 +010015import utils
16
17
18def make_parser():
19 parser = argparse.ArgumentParser(description = 'Compile a dump artifact.')
20 parser.add_argument(
Ian Zerny0e53ff12021-06-15 13:40:14 +020021 '--summary',
22 help='List a summary of the contents of the dumps.',
23 default=False,
24 action='store_true')
25 parser.add_argument(
Ian Zerny5ffa58f2020-02-26 08:37:14 +010026 '-d',
27 '--dump',
Christoffer Quist Adamsend84a6f02020-05-16 12:29:35 +020028 help='Dump file or directory to compile',
Ian Zerny5ffa58f2020-02-26 08:37:14 +010029 default=None)
30 parser.add_argument(
Rico Wind9ed87b92020-03-06 12:37:18 +010031 '--temp',
32 help='Temp directory to extract the dump to, allows you to rerun the command'
33 ' more easily in the terminal with changes',
34 default=None)
35 parser.add_argument(
Ian Zerny5ffa58f2020-02-26 08:37:14 +010036 '-c',
37 '--compiler',
Rico Windf73f18d2020-03-03 09:28:54 +010038 help='Compiler to use',
Ian Zerny5ffa58f2020-02-26 08:37:14 +010039 default=None)
40 parser.add_argument(
Christoffer Quist Adamsenf86fc0b2021-12-10 12:39:36 +010041 '--minify',
42 help='Force enable/disable minification'
43 ' (defaults to app proguard config)',
44 choices=['default', 'force-enable', 'force-disable'],
45 default='default')
46 parser.add_argument(
47 '--optimize',
48 help='Force enable/disable optimizations'
49 ' (defaults to app proguard config)',
50 choices=['default', 'force-enable', 'force-disable'],
51 default='default')
52 parser.add_argument(
53 '--shrink',
54 help='Force enable/disable shrinking'
55 ' (defaults to app proguard config)',
56 choices=['default', 'force-enable', 'force-disable'],
57 default='default')
58 parser.add_argument(
Ian Zerny5ffa58f2020-02-26 08:37:14 +010059 '-v',
60 '--version',
61 help='Compiler version to use (default read from dump version file).'
62 'Valid arguments are:'
Rico Wind1b52acf2021-03-21 12:36:55 +010063 ' "main" to run from your own tree,'
Morten Krogh-Jespersen51db2b02020-11-11 12:49:26 +010064 ' "source" to run from build classes directly,'
Ian Zerny5ffa58f2020-02-26 08:37:14 +010065 ' "X.Y.Z" to run a specific version, or'
Rico Wind1b52acf2021-03-21 12:36:55 +010066 ' <hash> to run that hash from main.',
Ian Zerny5ffa58f2020-02-26 08:37:14 +010067 default=None)
68 parser.add_argument(
Morten Krogh-Jespersend8bceb52020-03-06 12:56:48 +010069 '--r8-jar',
70 help='Path to an R8 jar.',
71 default=None)
72 parser.add_argument(
Christoffer Quist Adamsen2f48f3f2021-10-14 17:25:03 +020073 '--r8-flags', '--r8_flags',
74 help='Additional option(s) for the compiler.')
75 parser.add_argument(
Morten Krogh-Jespersen1fbfd592021-11-26 13:41:32 +010076 '--override',
Morten Krogh-Jespersen9206a662020-11-23 08:47:06 +010077 help='Do not override any extracted dump in temp-dir',
78 default=False,
79 action='store_true')
80 parser.add_argument(
Ian Zerny5ffa58f2020-02-26 08:37:14 +010081 '--nolib',
82 help='Use the non-lib distribution (default uses the lib distribution)',
83 default=False,
84 action='store_true')
85 parser.add_argument(
Morten Krogh-Jespersen6c702402021-06-21 12:29:48 +020086 '--print-times',
Rico Wind28653642020-03-31 13:59:07 +020087 help='Print timing information from r8',
88 default=False,
89 action='store_true')
90 parser.add_argument(
Ian Zerny5ffa58f2020-02-26 08:37:14 +010091 '--ea',
92 help='Enable Java assertions when running the compiler (default disabled)',
93 default=False,
94 action='store_true')
95 parser.add_argument(
Morten Krogh-Jespersen45d7a7b2020-11-02 08:31:09 +010096 '--classfile',
97 help='Run with classfile output',
98 default=False,
99 action='store_true')
100 parser.add_argument(
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100101 '--debug-agent',
102 help='Enable Java debug agent and suspend compilation (default disabled)',
103 default=False,
104 action='store_true')
Ian Zerny77bdf5f2020-07-08 11:46:24 +0200105 parser.add_argument(
106 '--xmx',
107 help='Set JVM max heap size (-Xmx)',
108 default=None)
109 parser.add_argument(
110 '--threads',
111 help='Set the number of threads to use',
112 default=None)
113 parser.add_argument(
114 '--min-api',
115 help='Set min-api (default read from dump properties file)',
116 default=None)
Søren Gjesse7360f2b2020-08-10 09:13:35 +0200117 parser.add_argument(
Clément Béradaae4ca2020-10-27 14:26:41 +0000118 '--desugared-lib',
119 help='Set desugared-library (default set from dump)',
120 default=None)
121 parser.add_argument(
Morten Krogh-Jespersend86a81b2020-11-13 12:33:26 +0100122 '--disable-desugared-lib',
123 help='Disable desugared-libary if it will be set from dump',
124 default=False,
125 action='store_true'
126 )
127 parser.add_argument(
Søren Gjesse7360f2b2020-08-10 09:13:35 +0200128 '--loop',
129 help='Run the compilation in a loop',
130 default=False,
131 action='store_true')
Morten Krogh-Jespersen9e201ea2022-06-14 12:41:50 +0200132 parser.add_argument(
133 '--enable-missing-library-api-modeling',
134 help='Run with api modeling',
135 default=False,
136 action='store_true')
137 parser.add_argument(
138 '--android-platform-build',
139 help='Run as a platform build',
140 default=False,
141 action='store_true')
Morten Krogh-Jespersenaa2f9ec2022-07-04 13:10:17 +0200142 parser.add_argument(
143 '--compilation-mode', '--compilation_mode',
144 help='Run compilation in specified mode',
145 choices=['debug', 'release'],
146 default=None)
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100147 return parser
148
149def error(msg):
Rico Wind3d369b42021-01-12 10:26:24 +0100150 print(msg)
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100151 sys.exit(1)
152
153class Dump(object):
154
155 def __init__(self, directory):
156 self.directory = directory
157
158 def if_exists(self, name):
159 f = os.path.join(self.directory, name)
160 if os.path.exists(f):
161 return f
162 return None
163
164 def program_jar(self):
165 return self.if_exists('program.jar')
166
Christoffer Quist Adamsenfcfc63a2020-05-15 19:04:24 +0200167 def feature_jars(self):
168 feature_jars = []
169 i = 1
170 while True:
171 feature_jar = self.if_exists('feature-%s.jar' % i)
172 if feature_jar:
173 feature_jars.append(feature_jar)
174 i = i + 1
175 else:
176 return feature_jars
177
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100178 def library_jar(self):
179 return self.if_exists('library.jar')
180
181 def classpath_jar(self):
182 return self.if_exists('classpath.jar')
183
Clément Béradaae4ca2020-10-27 14:26:41 +0000184 def desugared_library_json(self):
185 return self.if_exists('desugared-library.json')
186
Clément Béra64a3c4c2020-11-10 08:16:17 +0000187 def proguard_input_map(self):
188 if self.if_exists('proguard_input.config'):
Rico Wind3d369b42021-01-12 10:26:24 +0100189 print("Unimplemented: proguard_input configuration.")
Clément Béra64a3c4c2020-11-10 08:16:17 +0000190
Morten Krogh-Jespersen1e774252021-03-01 16:56:07 +0100191 def main_dex_list_resource(self):
Christoffer Quist Adamsencd7f7ec2022-08-26 13:39:11 +0200192 return self.if_exists('main-dex-list.txt')
Clément Béra64a3c4c2020-11-10 08:16:17 +0000193
Morten Krogh-Jespersen1e774252021-03-01 16:56:07 +0100194 def main_dex_rules_resource(self):
195 return self.if_exists('main-dex-rules.txt')
196
Christoffer Quist Adamsencd7f7ec2022-08-26 13:39:11 +0200197 def startup_profile_resources(self):
198 startup_profile_resources = []
199 while True:
200 current_startup_profile_index = len(startup_profile_resources) + 1
201 startup_profile_resource = self.if_exists(
202 'startup-profile-%s.txt' % current_startup_profile_index)
203 if startup_profile_resource is None:
204 return startup_profile_resources
205 startup_profile_resources.append(startup_profile_resource)
206
Christoffer Quist Adamsenfcfc63a2020-05-15 19:04:24 +0200207 def build_properties_file(self):
208 return self.if_exists('build.properties')
209
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100210 def config_file(self):
211 return self.if_exists('proguard.config')
212
213 def version_file(self):
214 return self.if_exists('r8-version')
215
216 def version(self):
217 f = self.version_file()
218 if f:
219 return open(f).read().split(' ')[0]
220 return None
221
Ian Zerny0e53ff12021-06-15 13:40:14 +0200222def read_dump_from_args(args, temp):
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100223 if args.dump is None:
Christoffer Quist Adamsend84a6f02020-05-16 12:29:35 +0200224 error("A dump file or directory must be specified")
Ian Zerny674099e2021-06-15 13:44:37 +0200225 return read_dump(args.dump, temp, args.override)
Ian Zerny0e53ff12021-06-15 13:40:14 +0200226
227def read_dump(dump, temp, override=False):
228 if os.path.isdir(dump):
229 return Dump(dump)
230 dump_file = zipfile.ZipFile(os.path.abspath(dump), 'r')
231 with utils.ChangedWorkingDirectory(temp, quiet=True):
232 if override or not os.path.isfile('r8-version'):
Morten Krogh-Jespersen9206a662020-11-23 08:47:06 +0100233 dump_file.extractall()
Ian Zerny202330b2021-05-03 13:23:04 +0200234 if not os.path.isfile('r8-version'):
Morten Krogh-Jespersen9206a662020-11-23 08:47:06 +0100235 error("Did not extract into %s. Either the zip file is invalid or the "
236 "dump is missing files" % temp)
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100237 return Dump(temp)
238
Christoffer Quist Adamsenfcfc63a2020-05-15 19:04:24 +0200239def determine_build_properties(args, dump):
240 build_properties = {}
241 build_properties_file = dump.build_properties_file()
242 if build_properties_file:
243 with open(build_properties_file) as f:
244 build_properties_contents = f.readlines()
245 for line in build_properties_contents:
246 stripped = line.strip()
247 if stripped:
248 pair = stripped.split('=')
249 build_properties[pair[0]] = pair[1]
250 return build_properties
251
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100252def determine_version(args, dump):
253 if args.version is None:
254 return dump.version()
255 return args.version
256
Søren Gjesse0f8d88b2021-09-28 15:15:54 +0200257def determine_compiler(args, build_properties):
Morten Krogh-Jespersenbb624e42021-04-19 14:33:48 +0200258 compilers = ['d8', 'r8', 'r8full', 'l8']
Søren Gjesse0f8d88b2021-09-28 15:15:54 +0200259 compiler = args.compiler
260 if not compiler and 'tool' in build_properties:
261 compiler = build_properties.get('tool').lower()
262 if (compiler == 'r8'):
263 if not 'force-proguard-compatibility' in build_properties:
264 error("Unable to determine R8 compiler variant from build.properties."
265 " No value for 'force-proguard-compatibility'.")
266 if build_properties.get('force-proguard-compatibility').lower() == 'false':
267 compiler = compiler + 'full'
268 if compiler not in compilers:
Rico Windf73f18d2020-03-03 09:28:54 +0100269 error("Unable to determine a compiler to use. Specified %s,"
270 " Valid options: %s" % (args.compiler, ', '.join(compilers)))
Søren Gjesse0f8d88b2021-09-28 15:15:54 +0200271 return compiler
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100272
273def determine_output(args, temp):
274 return os.path.join(temp, 'out.jar')
275
Ian Zerny77bdf5f2020-07-08 11:46:24 +0200276def determine_min_api(args, build_properties):
277 if args.min_api:
278 return args.min_api
279 if 'min-api' in build_properties:
280 return build_properties.get('min-api')
281 return None
282
Christoffer Quist Adamsenfcfc63a2020-05-15 19:04:24 +0200283def determine_feature_output(feature_jar, temp):
284 return os.path.join(temp, os.path.basename(feature_jar)[:-4] + ".out.jar")
285
Morten Krogh-Jespersen45d7a7b2020-11-02 08:31:09 +0100286def determine_program_jar(args, dump):
287 if hasattr(args, 'program_jar') and args.program_jar:
288 return args.program_jar
289 return dump.program_jar()
290
291def determine_class_file(args, build_properties):
292 if args.classfile:
293 return args.classfile
294 if 'classfile' in build_properties:
295 return True
296 return None
297
Morten Krogh-Jespersen9e201ea2022-06-14 12:41:50 +0200298def determine_android_platform_build(args, build_properties):
299 if args.android_platform_build:
Morten Krogh-Jespersen9e201ea2022-06-14 12:41:50 +0200300 return True
Morten Krogh-Jespersenaa2f9ec2022-07-04 13:10:17 +0200301 return build_properties.get('android-platform-build') == 'true'
Morten Krogh-Jespersen9e201ea2022-06-14 12:41:50 +0200302
303def determine_enable_missing_library_api_modeling(args, build_properties):
304 if args.enable_missing_library_api_modeling:
Morten Krogh-Jespersen9e201ea2022-06-14 12:41:50 +0200305 return True
Morten Krogh-Jespersenaa2f9ec2022-07-04 13:10:17 +0200306 return build_properties.get('enable-missing-library-api-modeling') == 'true'
307
308def determine_compilation_mode(args, build_properties):
309 if args.compilation_mode:
310 return args.compilation_mode
311 return build_properties.get('mode')
Morten Krogh-Jespersen9e201ea2022-06-14 12:41:50 +0200312
Søren Gjesse1768e252021-10-06 12:50:36 +0200313def determine_properties(build_properties):
314 args = []
315 for key, value in build_properties.items():
316 # When writing dumps all system properties starting with com.android.tools.r8
317 # are written to the build.properties file in the format
318 # system-property-com.android.tools.r8.XXX=<value>
319 if key.startswith('system-property-'):
320 name = key[len('system-property-'):]
321 if name.endswith('dumpinputtofile') or name.endswith('dumpinputtodirectory'):
322 continue
323 if len(value) == 0:
324 args.append('-D' + name)
325 else:
326 args.append('-D' + name + '=' + value)
327 return args
328
Ian Zerny171c6a62022-04-04 14:25:30 +0200329def download_distribution(version, nolib, temp):
Rico Wind1b52acf2021-03-21 12:36:55 +0100330 if version == 'main':
Ian Zerny171c6a62022-04-04 14:25:30 +0200331 return utils.R8_JAR if nolib else utils.R8LIB_JAR
Morten Krogh-Jespersen51db2b02020-11-11 12:49:26 +0100332 if version == 'source':
333 return '%s:%s' % (utils.BUILD_JAVA_MAIN_DIR, utils.ALL_DEPS_JAR)
Ian Zerny171c6a62022-04-04 14:25:30 +0200334 name = 'r8.jar' if nolib else 'r8lib.jar'
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100335 source = archive.GetUploadDestination(version, name, is_hash(version))
336 dest = os.path.join(temp, 'r8.jar')
337 utils.download_file_from_cloud_storage(source, dest)
338 return dest
339
Rico Windc9e52f72021-08-19 08:30:26 +0200340
Christoffer Quist Adamsenf86fc0b2021-12-10 12:39:36 +0100341def clean_config(file, args):
Rico Windc9e52f72021-08-19 08:30:26 +0200342 with open(file) as f:
343 lines = f.readlines()
Christoffer Quist Adamsenf86fc0b2021-12-10 12:39:36 +0100344 minify = args.minify
345 optimize = args.optimize
346 shrink = args.shrink
Rico Windc9e52f72021-08-19 08:30:26 +0200347 with open(file, 'w') as f:
Christoffer Quist Adamsenf86fc0b2021-12-10 12:39:36 +0100348 if minify == 'force-disable':
349 print('Adding config line: -dontobfuscate')
350 f.write('-dontobfuscate\n')
351 if optimize == 'force-disable':
352 print('Adding config line: -dontoptimize')
353 f.write('-dontoptimize\n')
354 if shrink == 'force-disable':
355 print('Adding config line: -dontshrink')
356 f.write('-dontshrink\n')
Rico Windc9e52f72021-08-19 08:30:26 +0200357 for line in lines:
Christoffer Quist Adamsenf86fc0b2021-12-10 12:39:36 +0100358 if clean_config_line(line, minify, optimize, shrink):
Rico Windc9e52f72021-08-19 08:30:26 +0200359 print('Removing from config line: \n%s' % line)
Christoffer Quist Adamsenf86fc0b2021-12-10 12:39:36 +0100360 else:
361 f.write(line)
Rico Windc9e52f72021-08-19 08:30:26 +0200362
Christoffer Quist Adamsenf86fc0b2021-12-10 12:39:36 +0100363def clean_config_line(line, minify, optimize, shrink):
364 if ('-injars' in line or '-libraryjars' in line or
365 '-print' in line):
366 return True
367 if minify == 'force-enable' and '-dontobfuscate' in line:
368 return True
369 if optimize == 'force-enable' and '-dontoptimize' in line:
370 return True
371 if shrink == 'force-enable' and '-dontshrink' in line:
372 return True
373 return False
Rico Windc9e52f72021-08-19 08:30:26 +0200374
Morten Krogh-Jespersen327e76d2022-06-23 09:31:13 +0200375def prepare_r8_wrapper(dist, temp, jdkhome):
376 compile_with_javac(
377 dist,
378 temp,
379 jdkhome,
380 os.path.join(
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100381 utils.REPO_ROOT,
Morten Krogh-Jespersen327e76d2022-06-23 09:31:13 +0200382 'src/main/java/com/android/tools/r8/utils/CompileDumpCompatR8.java'))
383
384def prepare_d8_wrapper(dist, temp, jdkhome):
385 compile_with_javac(
386 dist,
387 temp,
388 jdkhome,
389 os.path.join(
390 utils.REPO_ROOT,
391 'src/main/java/com/android/tools/r8/utils/CompileDumpD8.java'))
392
393def compile_with_javac(dist, temp, jdkhome, path):
Ian Zerny268c9632020-11-13 11:36:35 +0100394 cmd = [
Rico Wind33936d12021-04-07 08:04:14 +0200395 jdk.GetJavacExecutable(jdkhome),
Morten Krogh-Jespersen327e76d2022-06-23 09:31:13 +0200396 path,
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100397 '-d', temp,
398 '-cp', dist,
Ian Zerny268c9632020-11-13 11:36:35 +0100399 ]
400 utils.PrintCmd(cmd)
401 subprocess.check_output(cmd)
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100402
403def is_hash(version):
404 return len(version) == 40
405
Rico Wind33936d12021-04-07 08:04:14 +0200406def run1(out, args, otherargs, jdkhome=None):
Ian Zerny09d42832022-11-17 07:45:02 +0100407 jvmargs = []
408 compilerargs = []
409 for arg in otherargs:
410 if arg.startswith('-D'):
411 jvmargs.append(arg)
412 else:
413 compilerargs.append(arg)
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100414 with utils.TempDir() as temp:
Søren Gjesse7360f2b2020-08-10 09:13:35 +0200415 if out:
416 temp = out
Rico Wind9ed87b92020-03-06 12:37:18 +0100417 if not os.path.exists(temp):
418 os.makedirs(temp)
Ian Zerny0e53ff12021-06-15 13:40:14 +0200419 dump = read_dump_from_args(args, temp)
Ian Zerny46bc4cf2020-08-03 15:58:27 +0200420 if not dump.program_jar():
421 error("Cannot compile dump with no program classes")
422 if not dump.library_jar():
Rico Wind3d369b42021-01-12 10:26:24 +0100423 print("WARNING: Unexpected lack of library classes in dump")
Christoffer Quist Adamsenfcfc63a2020-05-15 19:04:24 +0200424 build_properties = determine_build_properties(args, dump)
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100425 version = determine_version(args, dump)
Søren Gjesse0f8d88b2021-09-28 15:15:54 +0200426 compiler = determine_compiler(args, build_properties)
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100427 out = determine_output(args, temp)
Ian Zerny77bdf5f2020-07-08 11:46:24 +0200428 min_api = determine_min_api(args, build_properties)
Morten Krogh-Jespersen45d7a7b2020-11-02 08:31:09 +0100429 classfile = determine_class_file(args, build_properties)
Morten Krogh-Jespersen9e201ea2022-06-14 12:41:50 +0200430 android_platform_build = determine_android_platform_build(args, build_properties)
431 enable_missing_library_api_modeling = determine_enable_missing_library_api_modeling(args, build_properties)
Morten Krogh-Jespersenaa2f9ec2022-07-04 13:10:17 +0200432 mode = determine_compilation_mode(args, build_properties)
Ian Zerny171c6a62022-04-04 14:25:30 +0200433 jar = args.r8_jar if args.r8_jar else download_distribution(version, args.nolib, temp)
Ian Zerny268c9632020-11-13 11:36:35 +0100434 if ':' not in jar and not os.path.exists(jar):
435 error("Distribution does not exist: " + jar)
Rico Wind33936d12021-04-07 08:04:14 +0200436 cmd = [jdk.GetJavaExecutable(jdkhome)]
Ian Zerny09d42832022-11-17 07:45:02 +0100437 cmd.extend(jvmargs)
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100438 if args.debug_agent:
439 if not args.nolib:
Rico Wind3d369b42021-01-12 10:26:24 +0100440 print("WARNING: Running debugging agent on r8lib is questionable...")
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100441 cmd.append(
442 '-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005')
Ian Zerny77bdf5f2020-07-08 11:46:24 +0200443 if args.xmx:
444 cmd.append('-Xmx' + args.xmx)
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100445 if args.ea:
446 cmd.append('-ea')
Morten Krogh-Jespersen23f0b032021-07-06 18:10:15 +0200447 cmd.append('-Dcom.android.tools.r8.enableTestAssertions=1')
Morten Krogh-Jespersen6c702402021-06-21 12:29:48 +0200448 if args.print_times:
Rico Wind28653642020-03-31 13:59:07 +0200449 cmd.append('-Dcom.android.tools.r8.printtimes=1')
Christoffer Quist Adamsen2f48f3f2021-10-14 17:25:03 +0200450 if args.r8_flags:
451 cmd.extend(args.r8_flags.split(' '))
Morten Krogh-Jespersen43f3cea2020-11-12 17:09:51 +0100452 if hasattr(args, 'properties'):
453 cmd.extend(args.properties);
Søren Gjesse1768e252021-10-06 12:50:36 +0200454 cmd.extend(determine_properties(build_properties))
Morten Krogh-Jespersen327e76d2022-06-23 09:31:13 +0200455 cmd.extend(['-cp', '%s:%s' % (temp, jar)])
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100456 if compiler == 'd8':
Ian Zerny1ad7cac2023-01-09 14:03:04 +0100457 prepare_d8_wrapper(jar, temp, jdkhome)
Morten Krogh-Jespersen327e76d2022-06-23 09:31:13 +0200458 cmd.append('com.android.tools.r8.utils.CompileDumpD8')
Morten Krogh-Jespersenbb624e42021-04-19 14:33:48 +0200459 if compiler == 'l8':
460 cmd.append('com.android.tools.r8.L8')
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100461 if compiler.startswith('r8'):
Ian Zerny1ad7cac2023-01-09 14:03:04 +0100462 prepare_r8_wrapper(jar, temp, jdkhome)
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100463 cmd.append('com.android.tools.r8.utils.CompileDumpCompatR8')
464 if compiler == 'r8':
465 cmd.append('--compat')
Morten Krogh-Jespersenaa2f9ec2022-07-04 13:10:17 +0200466 if mode == 'debug':
467 cmd.append('--debug')
468 else:
469 cmd.append('--release')
Morten Krogh-Jespersen45d7a7b2020-11-02 08:31:09 +0100470 # For recompilation of dumps run_on_app_dumps pass in a program jar.
471 cmd.append(determine_program_jar(args, dump))
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100472 cmd.extend(['--output', out])
Christoffer Quist Adamsenfcfc63a2020-05-15 19:04:24 +0200473 for feature_jar in dump.feature_jars():
474 cmd.extend(['--feature-jar', feature_jar,
475 determine_feature_output(feature_jar, temp)])
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100476 if dump.library_jar():
477 cmd.extend(['--lib', dump.library_jar()])
Morten Krogh-Jespersenbb624e42021-04-19 14:33:48 +0200478 if dump.classpath_jar() and compiler != 'l8':
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100479 cmd.extend(['--classpath', dump.classpath_jar()])
Morten Krogh-Jespersend86a81b2020-11-13 12:33:26 +0100480 if dump.desugared_library_json() and not args.disable_desugared_lib:
Clément Béradaae4ca2020-10-27 14:26:41 +0000481 cmd.extend(['--desugared-lib', dump.desugared_library_json()])
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100482 if compiler != 'd8' and dump.config_file():
Morten Krogh-Jespersen51a16352020-11-04 09:31:15 +0100483 if hasattr(args, 'config_file_consumer') and args.config_file_consumer:
484 args.config_file_consumer(dump.config_file())
Rico Windc9e52f72021-08-19 08:30:26 +0200485 else:
486 # If we get a dump from the wild we can't use -injars, -libraryjars or
487 # -print{mapping,usage}
Christoffer Quist Adamsenf86fc0b2021-12-10 12:39:36 +0100488 clean_config(dump.config_file(), args)
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100489 cmd.extend(['--pg-conf', dump.config_file()])
Christoffer Quist Adamsencd7f7ec2022-08-26 13:39:11 +0200490 if dump.main_dex_list_resource():
491 cmd.extend(['--main-dex-list', dump.main_dex_list_resource()])
Morten Krogh-Jespersen1e774252021-03-01 16:56:07 +0100492 if dump.main_dex_rules_resource():
493 cmd.extend(['--main-dex-rules', dump.main_dex_rules_resource()])
Christoffer Quist Adamsencd7f7ec2022-08-26 13:39:11 +0200494 for startup_profile_resource in dump.startup_profile_resources():
495 cmd.extend(['--startup-profile', startup_profile_resource])
Morten Krogh-Jespersenbb624e42021-04-19 14:33:48 +0200496 if compiler == 'l8':
497 if dump.config_file():
498 cmd.extend(['--pg-map-output', '%s.map' % out])
499 elif compiler != 'd8':
Ian Zerny588120b2020-04-03 13:08:03 +0200500 cmd.extend(['--pg-map-output', '%s.map' % out])
Ian Zerny77bdf5f2020-07-08 11:46:24 +0200501 if min_api:
502 cmd.extend(['--min-api', min_api])
Morten Krogh-Jespersen45d7a7b2020-11-02 08:31:09 +0100503 if classfile:
504 cmd.extend(['--classfile'])
Morten Krogh-Jespersen9e201ea2022-06-14 12:41:50 +0200505 if android_platform_build:
506 cmd.extend(['--android-platform-build'])
507 if enable_missing_library_api_modeling:
508 cmd.extend(['--enable-missing-library-api-modeling'])
Ian Zerny77bdf5f2020-07-08 11:46:24 +0200509 if args.threads:
510 cmd.extend(['--threads', args.threads])
Ian Zerny09d42832022-11-17 07:45:02 +0100511 cmd.extend(compilerargs)
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100512 utils.PrintCmd(cmd)
513 try:
Morten Krogh-Jespersen6c702402021-06-21 12:29:48 +0200514 print(subprocess.check_output(cmd, stderr=subprocess.STDOUT).decode('utf-8'))
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100515 return 0
Rico Wind3d369b42021-01-12 10:26:24 +0100516 except subprocess.CalledProcessError as e:
Ian Zerny9ff31b72021-04-22 11:36:26 +0200517 if args.nolib \
518 or version == 'source' \
519 or not try_retrace_output(e, version, temp):
Morten Krogh-Jespersen86222742021-03-02 11:13:33 +0100520 print(e.output.decode('UTF-8'))
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100521 return 1
522
Ian Zerny9ff31b72021-04-22 11:36:26 +0200523def try_retrace_output(e, version, temp):
524 try:
525 stacktrace = os.path.join(temp, 'stacktrace')
526 open(stacktrace, 'w+').write(e.output.decode('UTF-8'))
527 print("=" * 80)
528 print(" RETRACED OUTPUT")
529 print("=" * 80)
530 retrace.run(get_map_file(version, temp), stacktrace, no_r8lib=False)
531 return True
532 except Exception as e2:
533 print("Failed to retrace for version: %s" % version)
534 print(e2)
535 return False
536
537def get_map_file(version, temp):
538 if version == 'main':
539 return utils.R8LIB_MAP
540 download_path = archive.GetUploadDestination(
541 version,
542 'r8lib.jar.map',
543 is_hash(version))
544 if utils.file_exists_on_cloud_storage(download_path):
545 map_path = os.path.join(temp, 'mapping.map')
546 utils.download_file_from_cloud_storage(download_path, map_path)
547 return map_path
548 else:
549 print('Could not find map file from argument: %s.' % version)
550 return None
551
Ian Zerny0e53ff12021-06-15 13:40:14 +0200552def summarize_dump_files(dumpfiles):
553 if len(dumpfiles) == 0:
554 error('Summary command expects a list of dumps to summarize')
555 for f in dumpfiles:
556 print(f + ':')
557 try:
558 with utils.TempDir() as temp:
559 dump = read_dump(f, temp)
560 summarize_dump(dump)
561 except IOError as e:
562 print("Error: " + str(e))
563 except zipfile.BadZipfile as e:
564 print("Error: " + str(e))
565
566def summarize_dump(dump):
567 version = dump.version()
568 if not version:
569 print('No dump version info')
570 return
571 print('version=' + version)
572 props = dump.build_properties_file()
573 if props:
574 with open(props) as props_file:
575 print(props_file.read())
576 if dump.library_jar():
577 print('library.jar present')
578 if dump.classpath_jar():
579 print('classpath.jar present')
580 prog = dump.program_jar()
581 if prog:
582 print('program.jar content:')
583 summarize_jar(prog)
584
585def summarize_jar(jar):
586 with zipfile.ZipFile(jar) as zip:
587 pkgs = {}
588 for info in zip.infolist():
589 if info.filename.endswith('.class'):
590 pkg, clazz = os.path.split(info.filename)
591 count = pkgs.get(pkg, 0)
592 pkgs[pkg] = count + 1
593 sorted = list(pkgs.keys())
594 sorted.sort()
595 for p in sorted:
596 print(' ' + p + ': ' + str(pkgs[p]))
597
Søren Gjesse7360f2b2020-08-10 09:13:35 +0200598def run(args, otherargs):
Ian Zerny0e53ff12021-06-15 13:40:14 +0200599 if args.summary:
600 summarize_dump_files(otherargs)
601 elif args.loop:
Søren Gjesse7360f2b2020-08-10 09:13:35 +0200602 count = 1
603 while True:
604 print('Iteration {:03d}'.format(count))
605 out = args.temp
606 if out:
607 out = os.path.join(out, '{:03d}'.format(count))
608 run1(out, args, otherargs)
609 count += 1
610 else:
611 run1(args.temp, args, otherargs)
612
Ian Zerny5ffa58f2020-02-26 08:37:14 +0100613if __name__ == '__main__':
614 (args, otherargs) = make_parser().parse_known_args(sys.argv[1:])
615 sys.exit(run(args, otherargs))