blob: 78c817268ae542fa506ddf61556dea908a9f82d1 [file] [log] [blame]
Mads Ager418d1ca2017-05-22 09:35:49 +02001#!/usr/bin/env python
2# Copyright (c) 2017, 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
Tamas Kenezfc34cd82017-07-13 12:43:57 +02006from __future__ import print_function
Tamas Kenez02bff032017-07-18 12:13:58 +02007from glob import glob
Rico Windb57bbc12018-09-20 19:23:32 +02008import copy
Mads Ager418d1ca2017-05-22 09:35:49 +02009import optparse
10import os
Mads Ager418d1ca2017-05-22 09:35:49 +020011import sys
Tamas Kenezf2ee2a32017-06-21 10:30:20 +020012import time
Mads Ager418d1ca2017-05-22 09:35:49 +020013
Søren Gjesse5ecb04a2017-06-13 09:44:32 +020014import gmail_data
Ian Zerny877c1862017-07-06 11:12:26 +020015import gmscore_data
Rico Wind1f4172c2018-09-06 16:29:03 +020016import golem
Christoffer Quist Adamsena2a58772018-10-03 09:47:46 +020017import nest_data
Søren Gjesse889e09d2019-11-07 16:33:51 +010018from sanitize_libraries import SanitizeLibraries, SanitizeLibrariesInPgconf
Mathias Ravdd6a6de2018-05-18 10:18:33 +020019import toolhelper
Ian Zerny877c1862017-07-06 11:12:26 +020020import utils
21import youtube_data
Rico Wind86bfc832018-09-18 07:48:21 +020022import chrome_data
Morten Krogh-Jespersen04c7c302019-10-01 15:04:33 +020023import r8_data
Morten Krogh-Jespersencd6712c2019-10-09 13:09:47 +020024import iosched_data
Mads Ager418d1ca2017-05-22 09:35:49 +020025
26TYPES = ['dex', 'deploy', 'proguarded']
Morten Krogh-Jespersencd6712c2019-10-09 13:09:47 +020027APPS = ['gmscore', 'nest', 'youtube', 'gmail', 'chrome', 'r8', 'iosched']
Tamas Kenez63a51d02019-01-07 15:53:02 +010028COMPILERS = ['d8', 'r8']
29COMPILER_BUILDS = ['full', 'lib']
30
Rico Wind5fdec152018-12-17 09:16:14 +010031# We use this magic exit code to signal that the program OOM'ed
32OOM_EXIT_CODE = 42
Jinseong Jeon158a3f12019-02-08 01:40:59 -080033# According to Popen.returncode doc:
34# A negative value -N indicates that the child was terminated by signal N.
35TIMEOUT_KILL_CODE = -9
Mads Ager418d1ca2017-05-22 09:35:49 +020036
Morten Krogh-Jespersen0981b722019-10-09 10:00:33 +020037# Log file names
38FIND_MIN_XMX_FILE = 'find_min_xmx_results'
39FIND_MIN_XMX_DIR = 'find_min_xmx'
40
Tamas Kenez5b1c5852017-07-21 13:38:33 +020041def ParseOptions(argv):
Mads Ager418d1ca2017-05-22 09:35:49 +020042 result = optparse.OptionParser()
Søren Gjesse932881f2017-06-13 10:43:36 +020043 result.add_option('--compiler',
Rico Windb57bbc12018-09-20 19:23:32 +020044 help='The compiler to use',
Tamas Kenez5b1c5852017-07-21 13:38:33 +020045 choices=COMPILERS)
Tamas Kenez63a51d02019-01-07 15:53:02 +010046 result.add_option('--compiler-build',
47 help='Compiler build to use',
48 choices=COMPILER_BUILDS,
49 default='lib')
Mads Ager418d1ca2017-05-22 09:35:49 +020050 result.add_option('--app',
Rico Windb57bbc12018-09-20 19:23:32 +020051 help='What app to run on',
Mads Ager418d1ca2017-05-22 09:35:49 +020052 choices=APPS)
Rico Windb57bbc12018-09-20 19:23:32 +020053 result.add_option('--run-all',
54 help='Compile all possible combinations',
55 default=False,
56 action='store_true')
Morten Krogh-Jespersenb7e1a182019-10-09 13:04:54 +020057 result.add_option('--expect-oom',
58 help='Expect that compilation will fail with an OOM',
59 default=False,
60 action='store_true')
Mads Ager418d1ca2017-05-22 09:35:49 +020061 result.add_option('--type',
Tamas Kenez3fdaabd2017-06-15 13:05:12 +020062 help='Default for R8: deploy, for D8: proguarded',
Mads Ager418d1ca2017-05-22 09:35:49 +020063 choices=TYPES)
64 result.add_option('--out',
Rico Windb57bbc12018-09-20 19:23:32 +020065 help='Where to place the output',
Rico Winde9485ba2018-10-01 07:04:16 +020066 default=utils.BUILD)
Mads Ager418d1ca2017-05-22 09:35:49 +020067 result.add_option('--no-build',
Rico Windb57bbc12018-09-20 19:23:32 +020068 help='Run without building first',
Mads Ager418d1ca2017-05-22 09:35:49 +020069 default=False,
70 action='store_true')
Morten Krogh-Jespersen322c2f12019-10-08 10:41:21 +020071 result.add_option('--max-memory',
72 help='The maximum memory in MB to run with',
73 type='int')
Rico Wind5fdec152018-12-17 09:16:14 +010074 result.add_option('--find-min-xmx',
75 help='Find the minimum amount of memory we can run in',
76 default=False,
77 action='store_true')
Morten Krogh-Jespersen04c7c302019-10-01 15:04:33 +020078 result.add_option('--find-min-xmx-min-memory',
79 help='Setting the minimum memory baseline to run in',
80 type='int')
81 result.add_option('--find-min-xmx-max-memory',
82 help='Setting the maximum memory baseline to run in',
83 type='int')
84 result.add_option('--find-min-xmx-range-size',
85 help='Setting the size of the acceptable memory range',
86 type='int',
87 default=32)
Morten Krogh-Jespersen0981b722019-10-09 10:00:33 +020088 result.add_option('--find-min-xmx-archive',
89 help='Archive find-min-xmx results on GCS',
90 default=False,
91 action='store_true')
Jinseong Jeon158a3f12019-02-08 01:40:59 -080092 result.add_option('--timeout',
Morten Krogh-Jespersen0981b722019-10-09 10:00:33 +020093 type='int',
Jinseong Jeon158a3f12019-02-08 01:40:59 -080094 default=0,
95 help='Set timeout instead of waiting for OOM.')
Rico Wind1f4172c2018-09-06 16:29:03 +020096 result.add_option('--golem',
Rico Windb57bbc12018-09-20 19:23:32 +020097 help='Running on golem, do not build or download',
Rico Wind1f4172c2018-09-06 16:29:03 +020098 default=False,
99 action='store_true')
Rico Wind139eece2018-09-25 09:42:09 +0200100 result.add_option('--ignore-java-version',
101 help='Do not check java version',
102 default=False,
103 action='store_true')
Mads Ager418d1ca2017-05-22 09:35:49 +0200104 result.add_option('--no-libraries',
Rico Windb57bbc12018-09-20 19:23:32 +0200105 help='Do not pass in libraries, even if they exist in conf',
Mads Ager418d1ca2017-05-22 09:35:49 +0200106 default=False,
107 action='store_true')
108 result.add_option('--no-debug',
109 help='Run without debug asserts.',
110 default=False,
111 action='store_true')
112 result.add_option('--version',
Rico Windb57bbc12018-09-20 19:23:32 +0200113 help='The version of the app to run')
Mads Ager418d1ca2017-05-22 09:35:49 +0200114 result.add_option('-k',
115 help='Override the default ProGuard keep rules')
Tamas Kenez139acc12017-06-14 17:14:58 +0200116 result.add_option('--compiler-flags',
117 help='Additional option(s) for the compiler. ' +
118 'If passing several options use a quoted string.')
Mads Ager418d1ca2017-05-22 09:35:49 +0200119 result.add_option('--r8-flags',
Tamas Kenez139acc12017-06-14 17:14:58 +0200120 help='Additional option(s) for the compiler. ' +
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200121 'Same as --compiler-flags, keeping it for backward'
122 ' compatibility. ' +
Mads Ager418d1ca2017-05-22 09:35:49 +0200123 'If passing several options use a quoted string.')
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200124 # TODO(tamaskenez) remove track-memory-to-file as soon as we updated golem
125 # to use --print-memoryuse instead
Mads Ager418d1ca2017-05-22 09:35:49 +0200126 result.add_option('--track-memory-to-file',
127 help='Track how much memory the jvm is using while ' +
128 ' compiling. Output to the specified file.')
129 result.add_option('--profile',
130 help='Profile R8 run.',
131 default=False,
132 action='store_true')
133 result.add_option('--dump-args-file',
134 help='Dump a file with the arguments for the specified ' +
135 'configuration. For use as a @<file> argument to perform ' +
136 'the run.')
Tamas Kenezf2ee2a32017-06-21 10:30:20 +0200137 result.add_option('--print-runtimeraw',
138 metavar='BENCHMARKNAME',
Tamas Kenez02bff032017-07-18 12:13:58 +0200139 help='Print the line \'<BENCHMARKNAME>(RunTimeRaw):' +
140 ' <elapsed> ms\' at the end where <elapsed> is' +
141 ' the elapsed time in milliseconds.')
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200142 result.add_option('--print-memoryuse',
143 metavar='BENCHMARKNAME',
Tamas Kenez02bff032017-07-18 12:13:58 +0200144 help='Print the line \'<BENCHMARKNAME>(MemoryUse):' +
145 ' <mem>\' at the end where <mem> is the peak' +
146 ' peak resident set size (VmHWM) in bytes.')
147 result.add_option('--print-dexsegments',
148 metavar='BENCHMARKNAME',
149 help='Print the sizes of individual dex segments as ' +
150 '\'<BENCHMARKNAME>-<segment>(CodeSize): <bytes>\'')
Morten Krogh-Jespersenae9557c2019-10-23 15:14:02 +0200151 result.add_option('--track-time-in-memory',
152 help='Plot the times taken from memory starting point to '
153 'end-point with defined memory increment',
154 default=False,
155 action='store_true')
156 result.add_option('--track-time-in-memory-max',
157 help='Setting the maximum memory baseline to run in',
158 type='int')
159 result.add_option('--track-time-in-memory-min',
160 help='Setting the minimum memory baseline to run in',
161 type='int')
162 result.add_option('--track-time-in-memory-increment',
163 help='Setting the increment',
164 type='int',
165 default=32)
Søren Gjesse04a94332020-01-27 15:35:42 +0100166 result.add_option('--print-times',
167 help='Include timing',
168 default=False,
169 action='store_true')
Søren Gjesse943389f2020-03-13 10:40:25 +0100170 result.add_option('--cpu-list',
171 help='Run under \'taskset\' with these CPUs. See '
172 'the \'taskset\' -c option for the format')
Morten Krogh-Jespersenb7e1a182019-10-09 13:04:54 +0200173
Tamas Kenez5b1c5852017-07-21 13:38:33 +0200174 return result.parse_args(argv)
Mads Ager418d1ca2017-05-22 09:35:49 +0200175
Man Cao29b9ef12019-03-25 11:19:35 -0700176# Most apps have -printmapping, -printseeds, -printusage and
177# -printconfiguration in the Proguard configuration. However we don't
178# want to write these files in the locations specified.
179# Instead generate an auxiliary Proguard configuration placing these
180# output files together with the dex output.
Søren Gjesse3a5aed92017-06-14 15:36:02 +0200181def GenerateAdditionalProguardConfiguration(temp, outdir):
182 name = "output.config"
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200183 with open(os.path.join(temp, name), 'w') as f:
184 f.write('-printmapping ' + os.path.join(outdir, 'proguard.map') + "\n")
185 f.write('-printseeds ' + os.path.join(outdir, 'proguard.seeds') + "\n")
Søren Gjesse59459582018-04-06 10:12:45 +0200186 f.write('-printusage ' + os.path.join(outdir, 'proguard.usage') + "\n")
Man Cao29b9ef12019-03-25 11:19:35 -0700187 f.write('-printconfiguration ' + os.path.join(outdir, 'proguard.config') + "\n")
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200188 return os.path.abspath(f.name)
Søren Gjesse3a5aed92017-06-14 15:36:02 +0200189
Rico Wind3f9302b2018-09-21 08:53:09 +0200190# Please add bug number for disabled permutations and please explicitly
191# do Bug: #BUG in the commit message of disabling to ensure re-enabling
192DISABLED_PERMUTATIONS = [
Ian Zernyd459b5f2018-10-03 06:46:21 +0200193 # (app, version, type), e.g., ('gmail', '180826.15', 'deploy'),
Søren Gjesse04638962020-02-28 09:59:30 +0100194 ('youtube', '15.09', 'deploy'), # b/150267318
Rico Wind3f9302b2018-09-21 08:53:09 +0200195]
196
Rico Windb57bbc12018-09-20 19:23:32 +0200197def get_permutations():
198 data_providers = {
199 'gmscore': gmscore_data,
Christoffer Quist Adamsena2a58772018-10-03 09:47:46 +0200200 'nest': nest_data,
Rico Windb57bbc12018-09-20 19:23:32 +0200201 'youtube': youtube_data,
202 'chrome': chrome_data,
Morten Krogh-Jespersen04c7c302019-10-01 15:04:33 +0200203 'gmail': gmail_data,
Morten Krogh-Jespersencd6712c2019-10-09 13:09:47 +0200204 'r8': r8_data,
205 'iosched': iosched_data,
Rico Windb57bbc12018-09-20 19:23:32 +0200206 }
207 # Check to ensure that we add all variants here.
208 assert len(APPS) == len(data_providers)
209 for app, data in data_providers.iteritems():
210 for version in data.VERSIONS:
211 for type in data.VERSIONS[version]:
Rico Wind3f9302b2018-09-21 08:53:09 +0200212 if (app, version, type) not in DISABLED_PERMUTATIONS:
Tamas Keneza730a7e2018-12-10 15:02:28 +0100213 for use_r8lib in [False, True]:
214 yield app, version, type, use_r8lib
Rico Windb57bbc12018-09-20 19:23:32 +0200215
216def run_all(options, args):
217 # Args will be destroyed
218 assert len(args) == 0
Tamas Keneza730a7e2018-12-10 15:02:28 +0100219 for name, version, type, use_r8lib in get_permutations():
Rico Windb57bbc12018-09-20 19:23:32 +0200220 compiler = 'r8' if type == 'deploy' else 'd8'
Tamas Kenez63a51d02019-01-07 15:53:02 +0100221 compiler_build = 'lib' if use_r8lib else 'full'
222 print('Executing %s/%s with %s %s %s' % (compiler, compiler_build, name,
223 version, type))
Tamas Keneza730a7e2018-12-10 15:02:28 +0100224
Rico Windb57bbc12018-09-20 19:23:32 +0200225 fixed_options = copy.copy(options)
226 fixed_options.app = name
227 fixed_options.version = version
228 fixed_options.compiler = compiler
Tamas Kenez63a51d02019-01-07 15:53:02 +0100229 fixed_options.compiler_build = compiler_build
Rico Windb57bbc12018-09-20 19:23:32 +0200230 fixed_options.type = type
231 exit_code = run_with_options(fixed_options, [])
232 if exit_code != 0:
Tamas Kenez63a51d02019-01-07 15:53:02 +0100233 print('Failed %s %s %s with %s/%s' % (name, version, type, compiler,
234 compiler_build))
Rico Windb57bbc12018-09-20 19:23:32 +0200235 exit(exit_code)
236
Rico Wind5fdec152018-12-17 09:16:14 +0100237def find_min_xmx(options, args):
238 # Args will be destroyed
239 assert len(args) == 0
240 # If we can run in 128 MB then we are good (which we can for small examples
241 # or D8 on medium sized examples)
Morten Krogh-Jespersen04c7c302019-10-01 15:04:33 +0200242 if options.find_min_xmx_min_memory:
243 not_working = options.find_min_xmx_min_memory
244 elif options.compiler == 'd8':
245 not_working = 128
246 else:
247 not_working = 1024
248 if options.find_min_xmx_max_memory:
249 working = options.find_min_xmx_max_memory
250 else:
251 working = 1024 * 8
Rico Wind5fdec152018-12-17 09:16:14 +0100252 exit_code = 0
Morten Krogh-Jespersen04c7c302019-10-01 15:04:33 +0200253 range = options.find_min_xmx_range_size
254 while working - not_working > range:
Rico Wind5fdec152018-12-17 09:16:14 +0100255 next_candidate = working - ((working - not_working)/2)
256 print('working: %s, non_working: %s, next_candidate: %s' %
257 (working, not_working, next_candidate))
258 extra_args = ['-Xmx%sM' % next_candidate]
Rico Wind5fdec152018-12-17 09:16:14 +0100259 t0 = time.time()
260 exit_code = run_with_options(options, [], extra_args)
261 t1 = time.time()
262 print('Running took: %s ms' % (1000.0 * (t1 - t0)))
Jinseong Jeon158a3f12019-02-08 01:40:59 -0800263 if exit_code != 0:
264 if exit_code not in [OOM_EXIT_CODE, TIMEOUT_KILL_CODE]:
265 print('Non OOM/Timeout error executing, exiting')
266 return 2
Rico Wind5fdec152018-12-17 09:16:14 +0100267 if exit_code == 0:
268 working = next_candidate
Jinseong Jeon158a3f12019-02-08 01:40:59 -0800269 elif exit_code == TIMEOUT_KILL_CODE:
270 print('Timeout. Continue to the next candidate.')
271 not_working = next_candidate
Rico Wind5fdec152018-12-17 09:16:14 +0100272 else:
273 assert exit_code == OOM_EXIT_CODE
274 not_working = next_candidate
275
Morten Krogh-Jespersen04c7c302019-10-01 15:04:33 +0200276 assert working - not_working <= range
Morten Krogh-Jespersen0981b722019-10-09 10:00:33 +0200277 found_range = 'Found range: %s - %s' % (not_working, working)
278 print(found_range)
279
280 if options.find_min_xmx_archive:
281 sha = utils.get_HEAD_sha1()
282 (version, _) = get_version_and_data(options)
283 destination = os.path.join(
284 utils.R8_TEST_RESULTS_BUCKET,
285 FIND_MIN_XMX_DIR,
286 sha,
287 options.compiler,
288 options.compiler_build,
289 options.app,
290 version,
291 get_type(options))
292 gs_destination = 'gs://%s' % destination
293 utils.archive_value(FIND_MIN_XMX_FILE, gs_destination, found_range + '\n')
294
Rico Wind5fdec152018-12-17 09:16:14 +0100295 return 0
296
Morten Krogh-Jespersenf2412302019-10-22 10:18:04 +0200297def print_min_xmx_ranges_for_hash(hash, compiler, compiler_build):
298 app_directory = os.path.join(
299 utils.R8_TEST_RESULTS_BUCKET,
300 FIND_MIN_XMX_DIR,
301 hash,
302 compiler,
303 compiler_build)
304 gs_base = 'gs://%s' % app_directory
305 for app in utils.ls_files_on_cloud_storage(gs_base).strip().split('\n'):
306 for version in utils.ls_files_on_cloud_storage(app).strip().split('\n'):
307 for type in utils.ls_files_on_cloud_storage(version).strip().split('\n'):
308 gs_location = '%s%s' % (type, FIND_MIN_XMX_FILE)
309 value = utils.cat_file_on_cloud_storage(gs_location, ignore_errors=True)
310 print('%s\n' % value)
311
Morten Krogh-Jespersenae9557c2019-10-23 15:14:02 +0200312def track_time_in_memory(options, args):
313 # Args will be destroyed
314 assert len(args) == 0
315 if not options.track_time_in_memory_min:
316 raise Exception(
317 'You have to specify --track_time_in_memory_min when running with '
318 '--track-time-in-memory')
319 if not options.track_time_in_memory_max:
320 raise Exception(
321 'You have to specify --track_time_in_memory_max when running with '
322 '--track-time-in-memory')
323 if not options.track_time_in_memory_increment:
324 raise Exception(
325 'You have to specify --track_time_in_memory_increment when running '
326 'with --track-time-in-memory')
327 current = options.track_time_in_memory_min
328 print('Memory (KB)\tTime (ms)')
329 with utils.TempDir() as temp:
330 stdout = os.path.join(temp, 'stdout')
331 stdout_fd = open(stdout, 'w')
332 while current <= options.track_time_in_memory_max:
333 extra_args = ['-Xmx%sM' % current]
334 t0 = time.time()
335 exit_code = run_with_options(options, [], extra_args, stdout_fd, quiet=True)
336 t1 = time.time()
337 total = (1000.0 * (t1 - t0)) if exit_code == 0 else -1
338 print('%s\t%s' % (current, total))
339 current += options.track_time_in_memory_increment
340
341 return 0
342
Tamas Kenez5b1c5852017-07-21 13:38:33 +0200343def main(argv):
Tamas Kenez5b1c5852017-07-21 13:38:33 +0200344 (options, args) = ParseOptions(argv)
Morten Krogh-Jespersenb7e1a182019-10-09 13:04:54 +0200345 if options.expect_oom and not options.max_memory:
346 raise Exception(
347 'You should only use --expect-oom if also specifying --max-memory')
348 if options.expect_oom and options.timeout:
349 raise Exception(
350 'You should not use --timeout when also specifying --expect-oom')
Morten Krogh-Jespersenae9557c2019-10-23 15:14:02 +0200351 if options.find_min_xmx and options.track_time_in_memory:
352 raise Exception(
353 'You cannot both find the min xmx and track time at the same time')
Rico Windb57bbc12018-09-20 19:23:32 +0200354 if options.run_all:
355 return run_all(options, args)
Rico Wind5fdec152018-12-17 09:16:14 +0100356 if options.find_min_xmx:
357 return find_min_xmx(options, args)
Morten Krogh-Jespersenae9557c2019-10-23 15:14:02 +0200358 if options.track_time_in_memory:
359 return track_time_in_memory(options, args)
Morten Krogh-Jespersenb7e1a182019-10-09 13:04:54 +0200360 exit_code = run_with_options(options, args)
361 if options.expect_oom:
362 exit_code = 0 if exit_code == OOM_EXIT_CODE else 1
363 return exit_code
Rico Windb57bbc12018-09-20 19:23:32 +0200364
Morten Krogh-Jespersen0981b722019-10-09 10:00:33 +0200365def get_version_and_data(options):
366 if options.app == 'gmscore':
367 version = options.version or 'v9'
368 data = gmscore_data
369 elif options.app == 'nest':
370 version = options.version or '20180926'
371 data = nest_data
372 elif options.app == 'youtube':
373 version = options.version or '12.22'
374 data = youtube_data
375 elif options.app == 'chrome':
376 version = options.version or '180917'
377 data = chrome_data
378 elif options.app == 'gmail':
379 version = options.version or '170604.16'
380 data = gmail_data
381 elif options.app == 'r8':
382 version = options.version or 'cf'
383 data = r8_data
Morten Krogh-Jespersencd6712c2019-10-09 13:09:47 +0200384 elif options.app == 'iosched':
385 version = options.version or '2019'
386 data = iosched_data
Morten Krogh-Jespersen0981b722019-10-09 10:00:33 +0200387 else:
388 raise Exception("You need to specify '--app={}'".format('|'.join(APPS)))
389 return version, data
390
391def get_type(options):
392 if not options.type:
393 return 'deploy' if options.compiler == 'r8' else 'proguarded'
394 return options.type
395
Søren Gjesse94793ca2019-11-08 13:53:08 +0100396def has_injars_and_libraryjars(pgconfs):
397 # Check if there are -injars and -libraryjars in the configuration.
398 has_injars = False
399 has_libraryjars = False
400 for pgconf in pgconfs:
401 pgconf_dirname = os.path.abspath(os.path.dirname(pgconf))
402 with open(pgconf) as pgconf_file:
403 for line in pgconf_file:
404 trimmed = line.strip()
405 if trimmed.startswith('-injars'):
406 has_injars = True
407 elif trimmed.startswith('-libraryjars'):
408 has_libraryjars = True
409 if has_injars and has_libraryjars:
410 return True
411 return False
412
Søren Gjesse889e09d2019-11-07 16:33:51 +0100413def check_no_injars_and_no_libraryjars(pgconfs):
414 # Ensure that there are no -injars or -libraryjars in the configuration.
415 for pgconf in pgconfs:
416 pgconf_dirname = os.path.abspath(os.path.dirname(pgconf))
417 with open(pgconf) as pgconf_file:
418 for line in pgconf_file:
419 trimmed = line.strip()
420 if trimmed.startswith('-injars'):
421 raise Exception("Unexpected -injars found in " + pgconf)
422 elif trimmed.startswith('-libraryjars'):
423 raise Exception("Unexpected -libraryjars found in " + pgconf)
424
Morten Krogh-Jespersen94a9b102019-11-01 09:45:44 +0000425def run_with_options(options, args, extra_args=None, stdout=None, quiet=False):
426 if extra_args is None:
427 extra_args = []
Rico Windb57bbc12018-09-20 19:23:32 +0200428 app_provided_pg_conf = False;
Rico Windadd08132018-12-14 14:17:15 +0100429 # todo(121018500): remove when memory is under control
Rico Wind20602b72019-01-09 09:17:13 +0100430 if not any('-Xmx' in arg for arg in extra_args):
Morten Krogh-Jespersen322c2f12019-10-08 10:41:21 +0200431 if options.max_memory:
432 extra_args.append('-Xmx%sM' % options.max_memory)
433 else:
434 extra_args.append('-Xmx8G')
Rico Wind1f4172c2018-09-06 16:29:03 +0200435 if options.golem:
436 golem.link_third_party()
Rico Wind9bd3f5f2018-10-01 10:53:18 +0200437 options.out = os.getcwd()
Rico Windafdbbfd2019-02-22 09:32:07 +0100438 if not options.ignore_java_version:
439 utils.check_java_version()
440
Søren Gjesse04a94332020-01-27 15:35:42 +0100441 if options.print_times:
442 extra_args.append('-Dcom.android.tools.r8.printtimes=1')
443
Mads Ager418d1ca2017-05-22 09:35:49 +0200444 outdir = options.out
Morten Krogh-Jespersen0981b722019-10-09 10:00:33 +0200445 (version_id, data) = get_version_and_data(options)
446
Tamas Kenez5b1c5852017-07-21 13:38:33 +0200447 if options.compiler not in COMPILERS:
448 raise Exception("You need to specify '--compiler={}'"
449 .format('|'.join(COMPILERS)))
Mads Ager418d1ca2017-05-22 09:35:49 +0200450
Tamas Kenez63a51d02019-01-07 15:53:02 +0100451 if options.compiler_build not in COMPILER_BUILDS:
452 raise Exception("You need to specify '--compiler-build={}'"
453 .format('|'.join(COMPILER_BUILDS)))
454
Morten Krogh-Jespersen0981b722019-10-09 10:00:33 +0200455 if not version_id in data.VERSIONS.keys():
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200456 print('No version {} for application {}'
Morten Krogh-Jespersen0981b722019-10-09 10:00:33 +0200457 .format(version_id, options.app))
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200458 print('Valid versions are {}'.format(data.VERSIONS.keys()))
Mads Ager418d1ca2017-05-22 09:35:49 +0200459 return 1
460
Morten Krogh-Jespersen0981b722019-10-09 10:00:33 +0200461 version = data.VERSIONS[version_id]
Mads Ager418d1ca2017-05-22 09:35:49 +0200462
Morten Krogh-Jespersen0981b722019-10-09 10:00:33 +0200463 type = get_type(options)
Tamas Kenez3fdaabd2017-06-15 13:05:12 +0200464
Morten Krogh-Jespersen0981b722019-10-09 10:00:33 +0200465 if type not in version:
466 print('No type {} for version {}'.format(type, version))
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200467 print('Valid types are {}'.format(version.keys()))
Mads Ager418d1ca2017-05-22 09:35:49 +0200468 return 1
Morten Krogh-Jespersen0981b722019-10-09 10:00:33 +0200469 values = version[type]
Søren Gjesse94793ca2019-11-08 13:53:08 +0100470 inputs = []
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200471 # For R8 'deploy' the JAR is located using the Proguard configuration
Christoffer Quist Adamsena2a58772018-10-03 09:47:46 +0200472 # -injars option. For chrome and nest we don't have the injars in the
473 # proguard files.
Tamas Kenez63a51d02019-01-07 15:53:02 +0100474 if 'inputs' in values and (options.compiler != 'r8'
Morten Krogh-Jespersen0981b722019-10-09 10:00:33 +0200475 or type != 'deploy'
Christoffer Quist Adamsena2a58772018-10-03 09:47:46 +0200476 or options.app == 'chrome'
Morten Krogh-Jespersen04c7c302019-10-01 15:04:33 +0200477 or options.app == 'nest'
Morten Krogh-Jespersencd6712c2019-10-09 13:09:47 +0200478 or options.app == 'r8'
479 or options.app == 'iosched'):
Mads Ager418d1ca2017-05-22 09:35:49 +0200480 inputs = values['inputs']
481
482 args.extend(['--output', outdir])
Ian Zerny877c1862017-07-06 11:12:26 +0200483 if 'min-api' in values:
484 args.extend(['--min-api', values['min-api']])
Søren Gjesse932881f2017-06-13 10:43:36 +0200485
Søren Gjesse8ae55eb2018-09-28 11:11:36 +0200486 if 'main-dex-list' in values:
487 args.extend(['--main-dex-list', values['main-dex-list']])
488
Søren Gjesse94793ca2019-11-08 13:53:08 +0100489 libraries = values['libraries'] if 'libraries' in values else []
Tamas Kenez63a51d02019-01-07 15:53:02 +0100490 if options.compiler == 'r8':
Søren Gjesse932881f2017-06-13 10:43:36 +0200491 if 'pgconf' in values and not options.k:
Søren Gjesse94793ca2019-11-08 13:53:08 +0100492 if has_injars_and_libraryjars(values['pgconf']):
493 sanitized_lib_path = os.path.join(
494 os.path.abspath(outdir), 'sanitized_lib.jar')
Søren Gjesse889e09d2019-11-07 16:33:51 +0100495 sanitized_pgconf_path = os.path.join(
496 os.path.abspath(outdir), 'sanitized.config')
497 SanitizeLibrariesInPgconf(
498 sanitized_lib_path, sanitized_pgconf_path, values['pgconf'])
Søren Gjesse94793ca2019-11-08 13:53:08 +0100499 libraries = [sanitized_lib_path]
Søren Gjesse889e09d2019-11-07 16:33:51 +0100500 args.extend(['--pg-conf', sanitized_pgconf_path])
Søren Gjesse94793ca2019-11-08 13:53:08 +0100501 else:
502 # -injars without -libraryjars or vice versa is not supported.
503 check_no_injars_and_no_libraryjars(values['pgconf'])
504 for pgconf in values['pgconf']:
505 args.extend(['--pg-conf', pgconf])
506 if 'sanitize_libraries' in values and values['sanitize_libraries']:
507 sanitized_lib_path = os.path.join(
508 os.path.abspath(outdir), 'sanitized_lib.jar')
509 SanitizeLibraries(
510 sanitized_lib_path, values['libraries'], values['inputs'])
511 libraries = [sanitized_lib_path]
512 inputs = values['inputs']
Søren Gjessecbeae782019-05-21 14:14:25 +0200513 app_provided_pg_conf = True
Søren Gjesse932881f2017-06-13 10:43:36 +0200514 if options.k:
515 args.extend(['--pg-conf', options.k])
Søren Gjessec801ecc2017-08-03 13:40:06 +0200516 if 'maindexrules' in values:
517 for rules in values['maindexrules']:
518 args.extend(['--main-dex-rules', rules])
Rico Wind79e4eb52018-12-13 13:00:49 +0100519 if 'allow-type-errors' in values:
520 extra_args.append('-Dcom.android.tools.r8.allowTypeErrors=1')
Søren Gjesse932881f2017-06-13 10:43:36 +0200521
Søren Gjesse94793ca2019-11-08 13:53:08 +0100522 if not options.no_libraries:
523 for lib in libraries:
Mads Ager418d1ca2017-05-22 09:35:49 +0200524 args.extend(['--lib', lib])
525
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200526 if not outdir.endswith('.zip') and not outdir.endswith('.jar') \
527 and not os.path.exists(outdir):
Mads Ager418d1ca2017-05-22 09:35:49 +0200528 os.makedirs(outdir)
529
Søren Gjesse8ae55eb2018-09-28 11:11:36 +0200530 # Additional flags for the compiler from the configuration file.
531 if 'flags' in values:
532 args.extend(values['flags'].split(' '))
Tamas Kenez63a51d02019-01-07 15:53:02 +0100533 if options.compiler == 'r8':
Søren Gjesse932881f2017-06-13 10:43:36 +0200534 if 'r8-flags' in values:
535 args.extend(values['r8-flags'].split(' '))
Tamas Kenez139acc12017-06-14 17:14:58 +0200536
Søren Gjesse8ae55eb2018-09-28 11:11:36 +0200537 # Additional flags for the compiler from the command line.
Tamas Kenez139acc12017-06-14 17:14:58 +0200538 if options.compiler_flags:
539 args.extend(options.compiler_flags.split(' '))
540 if options.r8_flags:
541 args.extend(options.r8_flags.split(' '))
Mads Ager418d1ca2017-05-22 09:35:49 +0200542
Søren Gjesse94793ca2019-11-08 13:53:08 +0100543 args.extend(inputs)
Mads Ager418d1ca2017-05-22 09:35:49 +0200544
Tamas Kenezf2ee2a32017-06-21 10:30:20 +0200545 t0 = time.time()
Mads Ager418d1ca2017-05-22 09:35:49 +0200546 if options.dump_args_file:
547 with open(options.dump_args_file, 'w') as args_file:
548 args_file.writelines([arg + os.linesep for arg in args])
549 else:
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200550 with utils.TempDir() as temp:
551 if options.print_memoryuse and not options.track_memory_to_file:
552 options.track_memory_to_file = os.path.join(temp,
553 utils.MEMORY_USE_TMP_FILE)
Tamas Kenez63a51d02019-01-07 15:53:02 +0100554 if options.compiler == 'r8' and app_provided_pg_conf:
Mathias Ravdd6a6de2018-05-18 10:18:33 +0200555 # Ensure that output of -printmapping and -printseeds go to the output
556 # location and not where the app Proguard configuration places them.
557 if outdir.endswith('.zip') or outdir.endswith('.jar'):
558 pg_outdir = os.path.dirname(outdir)
559 else:
560 pg_outdir = outdir
561 additional_pg_conf = GenerateAdditionalProguardConfiguration(
562 temp, os.path.abspath(pg_outdir))
563 args.extend(['--pg-conf', additional_pg_conf])
Rico Wind1f4172c2018-09-06 16:29:03 +0200564 build = not options.no_build and not options.golem
Rico Wind5fdec152018-12-17 09:16:14 +0100565 stderr_path = os.path.join(temp, 'stderr')
566 with open(stderr_path, 'w') as stderr:
Tamas Kenez63a51d02019-01-07 15:53:02 +0100567 if options.compiler_build == 'full':
568 tool = options.compiler
569 else:
570 assert(options.compiler_build == 'lib')
571 tool = 'r8lib-' + options.compiler
572 exit_code = toolhelper.run(tool, args,
Rico Wind5fdec152018-12-17 09:16:14 +0100573 build=build,
574 debug=not options.no_debug,
575 profile=options.profile,
576 track_memory_file=options.track_memory_to_file,
Jinseong Jeon158a3f12019-02-08 01:40:59 -0800577 extra_args=extra_args,
Morten Krogh-Jespersenae9557c2019-10-23 15:14:02 +0200578 stdout=stdout,
Jinseong Jeon158a3f12019-02-08 01:40:59 -0800579 stderr=stderr,
Morten Krogh-Jespersenae9557c2019-10-23 15:14:02 +0200580 timeout=options.timeout,
Søren Gjesse943389f2020-03-13 10:40:25 +0100581 quiet=quiet,
582 cmd_prefix=['taskset', '-c', options.cpu_list] if options.cpu_list else None)
Christoffer Quist Adamsen21c66602018-08-09 16:22:54 +0200583 if exit_code != 0:
Rico Wind5fdec152018-12-17 09:16:14 +0100584 with open(stderr_path) as stderr:
585 stderr_text = stderr.read()
Morten Krogh-Jespersenae9557c2019-10-23 15:14:02 +0200586 if not quiet:
587 print(stderr_text)
Rico Wind5fdec152018-12-17 09:16:14 +0100588 if 'java.lang.OutOfMemoryError' in stderr_text:
Morten Krogh-Jespersenae9557c2019-10-23 15:14:02 +0200589 if not quiet:
590 print('Failure was OOM')
Rico Wind5fdec152018-12-17 09:16:14 +0100591 return OOM_EXIT_CODE
592 return exit_code
Christoffer Quist Adamsen21c66602018-08-09 16:22:54 +0200593
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200594 if options.print_memoryuse:
595 print('{}(MemoryUse): {}'
596 .format(options.print_memoryuse,
597 utils.grep_memoryuse(options.track_memory_to_file)))
Mads Ager418d1ca2017-05-22 09:35:49 +0200598
Tamas Kenezf2ee2a32017-06-21 10:30:20 +0200599 if options.print_runtimeraw:
600 print('{}(RunTimeRaw): {} ms'
601 .format(options.print_runtimeraw, 1000.0 * (time.time() - t0)))
602
Tamas Kenez02bff032017-07-18 12:13:58 +0200603 if options.print_dexsegments:
604 dex_files = glob(os.path.join(outdir, '*.dex'))
605 utils.print_dexsegments(options.print_dexsegments, dex_files)
Rico Windb57bbc12018-09-20 19:23:32 +0200606 return 0
Tamas Kenez02bff032017-07-18 12:13:58 +0200607
Mads Ager418d1ca2017-05-22 09:35:49 +0200608if __name__ == '__main__':
Tamas Kenez5b1c5852017-07-21 13:38:33 +0200609 sys.exit(main(sys.argv[1:]))