blob: 2379912c9a974a49061028220498049225910913 [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
Mathias Ravdd6a6de2018-05-18 10:18:33 +020017import toolhelper
Ian Zerny877c1862017-07-06 11:12:26 +020018import utils
19import youtube_data
Rico Wind86bfc832018-09-18 07:48:21 +020020import chrome_data
Mads Ager418d1ca2017-05-22 09:35:49 +020021
22TYPES = ['dex', 'deploy', 'proguarded']
Rico Wind86bfc832018-09-18 07:48:21 +020023APPS = ['gmscore', 'youtube', 'gmail', 'chrome']
Tamas Kenez5b1c5852017-07-21 13:38:33 +020024COMPILERS = ['d8', 'r8']
Mads Ager418d1ca2017-05-22 09:35:49 +020025
Tamas Kenez5b1c5852017-07-21 13:38:33 +020026def ParseOptions(argv):
Mads Ager418d1ca2017-05-22 09:35:49 +020027 result = optparse.OptionParser()
Søren Gjesse932881f2017-06-13 10:43:36 +020028 result.add_option('--compiler',
Rico Windb57bbc12018-09-20 19:23:32 +020029 help='The compiler to use',
Tamas Kenez5b1c5852017-07-21 13:38:33 +020030 choices=COMPILERS)
Mads Ager418d1ca2017-05-22 09:35:49 +020031 result.add_option('--app',
Rico Windb57bbc12018-09-20 19:23:32 +020032 help='What app to run on',
Mads Ager418d1ca2017-05-22 09:35:49 +020033 choices=APPS)
Rico Windb57bbc12018-09-20 19:23:32 +020034 result.add_option('--run-all',
35 help='Compile all possible combinations',
36 default=False,
37 action='store_true')
Mads Ager418d1ca2017-05-22 09:35:49 +020038 result.add_option('--type',
Tamas Kenez3fdaabd2017-06-15 13:05:12 +020039 help='Default for R8: deploy, for D8: proguarded',
Mads Ager418d1ca2017-05-22 09:35:49 +020040 choices=TYPES)
41 result.add_option('--out',
Rico Windb57bbc12018-09-20 19:23:32 +020042 help='Where to place the output',
Rico Winde9485ba2018-10-01 07:04:16 +020043 default=utils.BUILD)
Mads Ager418d1ca2017-05-22 09:35:49 +020044 result.add_option('--no-build',
Rico Windb57bbc12018-09-20 19:23:32 +020045 help='Run without building first',
Mads Ager418d1ca2017-05-22 09:35:49 +020046 default=False,
47 action='store_true')
Rico Wind1f4172c2018-09-06 16:29:03 +020048 result.add_option('--golem',
Rico Windb57bbc12018-09-20 19:23:32 +020049 help='Running on golem, do not build or download',
Rico Wind1f4172c2018-09-06 16:29:03 +020050 default=False,
51 action='store_true')
Rico Wind139eece2018-09-25 09:42:09 +020052 result.add_option('--ignore-java-version',
53 help='Do not check java version',
54 default=False,
55 action='store_true')
Mads Ager418d1ca2017-05-22 09:35:49 +020056 result.add_option('--no-libraries',
Rico Windb57bbc12018-09-20 19:23:32 +020057 help='Do not pass in libraries, even if they exist in conf',
Mads Ager418d1ca2017-05-22 09:35:49 +020058 default=False,
59 action='store_true')
60 result.add_option('--no-debug',
61 help='Run without debug asserts.',
62 default=False,
63 action='store_true')
64 result.add_option('--version',
Rico Windb57bbc12018-09-20 19:23:32 +020065 help='The version of the app to run')
Mads Ager418d1ca2017-05-22 09:35:49 +020066 result.add_option('-k',
67 help='Override the default ProGuard keep rules')
Tamas Kenez139acc12017-06-14 17:14:58 +020068 result.add_option('--compiler-flags',
69 help='Additional option(s) for the compiler. ' +
70 'If passing several options use a quoted string.')
Mads Ager418d1ca2017-05-22 09:35:49 +020071 result.add_option('--r8-flags',
Tamas Kenez139acc12017-06-14 17:14:58 +020072 help='Additional option(s) for the compiler. ' +
Tamas Kenezfc34cd82017-07-13 12:43:57 +020073 'Same as --compiler-flags, keeping it for backward'
74 ' compatibility. ' +
Mads Ager418d1ca2017-05-22 09:35:49 +020075 'If passing several options use a quoted string.')
Tamas Kenezfc34cd82017-07-13 12:43:57 +020076 # TODO(tamaskenez) remove track-memory-to-file as soon as we updated golem
77 # to use --print-memoryuse instead
Mads Ager418d1ca2017-05-22 09:35:49 +020078 result.add_option('--track-memory-to-file',
79 help='Track how much memory the jvm is using while ' +
80 ' compiling. Output to the specified file.')
81 result.add_option('--profile',
82 help='Profile R8 run.',
83 default=False,
84 action='store_true')
85 result.add_option('--dump-args-file',
86 help='Dump a file with the arguments for the specified ' +
87 'configuration. For use as a @<file> argument to perform ' +
88 'the run.')
Tamas Kenezf2ee2a32017-06-21 10:30:20 +020089 result.add_option('--print-runtimeraw',
90 metavar='BENCHMARKNAME',
Tamas Kenez02bff032017-07-18 12:13:58 +020091 help='Print the line \'<BENCHMARKNAME>(RunTimeRaw):' +
92 ' <elapsed> ms\' at the end where <elapsed> is' +
93 ' the elapsed time in milliseconds.')
Tamas Kenezfc34cd82017-07-13 12:43:57 +020094 result.add_option('--print-memoryuse',
95 metavar='BENCHMARKNAME',
Tamas Kenez02bff032017-07-18 12:13:58 +020096 help='Print the line \'<BENCHMARKNAME>(MemoryUse):' +
97 ' <mem>\' at the end where <mem> is the peak' +
98 ' peak resident set size (VmHWM) in bytes.')
99 result.add_option('--print-dexsegments',
100 metavar='BENCHMARKNAME',
101 help='Print the sizes of individual dex segments as ' +
102 '\'<BENCHMARKNAME>-<segment>(CodeSize): <bytes>\'')
Tamas Kenez5b1c5852017-07-21 13:38:33 +0200103 return result.parse_args(argv)
Mads Ager418d1ca2017-05-22 09:35:49 +0200104
Søren Gjesse59459582018-04-06 10:12:45 +0200105# Most apps have the -printmapping, -printseeds and -printusage in the
106# Proguard configuration. However we don't want to write these files
107# in the locations specified. Instead generate an auxiliary Proguard
108# configuration placing these two output files together with the dex
109# output.
Søren Gjesse3a5aed92017-06-14 15:36:02 +0200110def GenerateAdditionalProguardConfiguration(temp, outdir):
111 name = "output.config"
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200112 with open(os.path.join(temp, name), 'w') as f:
113 f.write('-printmapping ' + os.path.join(outdir, 'proguard.map') + "\n")
114 f.write('-printseeds ' + os.path.join(outdir, 'proguard.seeds') + "\n")
Søren Gjesse59459582018-04-06 10:12:45 +0200115 f.write('-printusage ' + os.path.join(outdir, 'proguard.usage') + "\n")
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200116 return os.path.abspath(f.name)
Søren Gjesse3a5aed92017-06-14 15:36:02 +0200117
Rico Wind3f9302b2018-09-21 08:53:09 +0200118# Please add bug number for disabled permutations and please explicitly
119# do Bug: #BUG in the commit message of disabling to ensure re-enabling
120DISABLED_PERMUTATIONS = [
121 ('youtube', '12.10', 'dex'), # b/116089492
Rico Wind2a19d932018-09-25 16:48:56 +0200122 ('youtube', '12.10', 'proguarded'), # b/116089492
Rico Windd5a36072018-09-25 14:38:01 +0200123 ('gmscore', 'latest', 'deploy') # b/116575775
Rico Wind3f9302b2018-09-21 08:53:09 +0200124]
125
Rico Windb57bbc12018-09-20 19:23:32 +0200126def get_permutations():
127 data_providers = {
128 'gmscore': gmscore_data,
129 'youtube': youtube_data,
130 'chrome': chrome_data,
131 'gmail': gmail_data
132 }
133 # Check to ensure that we add all variants here.
134 assert len(APPS) == len(data_providers)
135 for app, data in data_providers.iteritems():
136 for version in data.VERSIONS:
137 for type in data.VERSIONS[version]:
Rico Wind3f9302b2018-09-21 08:53:09 +0200138 if (app, version, type) not in DISABLED_PERMUTATIONS:
139 yield app, version, type
Rico Windb57bbc12018-09-20 19:23:32 +0200140
141def run_all(options, args):
142 # Args will be destroyed
143 assert len(args) == 0
144 for name, version, type in get_permutations():
145 print('Execution %s %s %s' % (name, version, type))
146 compiler = 'r8' if type == 'deploy' else 'd8'
147 fixed_options = copy.copy(options)
148 fixed_options.app = name
149 fixed_options.version = version
150 fixed_options.compiler = compiler
151 fixed_options.type = type
152 exit_code = run_with_options(fixed_options, [])
153 if exit_code != 0:
154 print('Failed %s %s %s with %s' % (name, version, type, compiler))
155 exit(exit_code)
156
Tamas Kenez5b1c5852017-07-21 13:38:33 +0200157def main(argv):
Tamas Kenez5b1c5852017-07-21 13:38:33 +0200158 (options, args) = ParseOptions(argv)
Rico Wind139eece2018-09-25 09:42:09 +0200159 if not options.ignore_java_version:
160 utils.check_java_version()
161
Rico Windb57bbc12018-09-20 19:23:32 +0200162 if options.run_all:
163 return run_all(options, args)
164 return run_with_options(options, args)
165
166def run_with_options(options, args):
167 app_provided_pg_conf = False;
Rico Wind1f4172c2018-09-06 16:29:03 +0200168 if options.golem:
169 golem.link_third_party()
Mads Ager418d1ca2017-05-22 09:35:49 +0200170 outdir = options.out
171 data = None
172 if options.app == 'gmscore':
173 options.version = options.version or 'v9'
174 data = gmscore_data
175 elif options.app == 'youtube':
Søren Gjessecc33fb42017-06-09 10:25:08 +0200176 options.version = options.version or '12.22'
Mads Ager418d1ca2017-05-22 09:35:49 +0200177 data = youtube_data
Rico Wind86bfc832018-09-18 07:48:21 +0200178 elif options.app == 'chrome':
179 options.version = options.version or 'default'
180 data = chrome_data
Søren Gjesse5ecb04a2017-06-13 09:44:32 +0200181 elif options.app == 'gmail':
182 options.version = options.version or '170604.16'
183 data = gmail_data
Mads Ager418d1ca2017-05-22 09:35:49 +0200184 else:
Tamas Kenez5b1c5852017-07-21 13:38:33 +0200185 raise Exception("You need to specify '--app={}'".format('|'.join(APPS)))
186
187 if options.compiler not in COMPILERS:
188 raise Exception("You need to specify '--compiler={}'"
189 .format('|'.join(COMPILERS)))
Mads Ager418d1ca2017-05-22 09:35:49 +0200190
191 if not options.version in data.VERSIONS.keys():
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200192 print('No version {} for application {}'
193 .format(options.version, options.app))
194 print('Valid versions are {}'.format(data.VERSIONS.keys()))
Mads Ager418d1ca2017-05-22 09:35:49 +0200195 return 1
196
197 version = data.VERSIONS[options.version]
198
Tamas Kenez3fdaabd2017-06-15 13:05:12 +0200199 if not options.type:
200 options.type = 'deploy' if options.compiler == 'r8' \
201 else 'proguarded'
202
Mads Ager418d1ca2017-05-22 09:35:49 +0200203 if options.type not in version:
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200204 print('No type {} for version {}'.format(options.type, options.version))
205 print('Valid types are {}'.format(version.keys()))
Mads Ager418d1ca2017-05-22 09:35:49 +0200206 return 1
207 values = version[options.type]
208 inputs = None
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200209 # For R8 'deploy' the JAR is located using the Proguard configuration
Rico Wind86bfc832018-09-18 07:48:21 +0200210 # -injars option. For chrome we don't have the injars in the proguard files.
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200211 if 'inputs' in values and (options.compiler != 'r8'
Rico Wind86bfc832018-09-18 07:48:21 +0200212 or options.type != 'deploy'
213 or options.app == 'chrome'):
Mads Ager418d1ca2017-05-22 09:35:49 +0200214 inputs = values['inputs']
215
216 args.extend(['--output', outdir])
Ian Zerny877c1862017-07-06 11:12:26 +0200217 if 'min-api' in values:
218 args.extend(['--min-api', values['min-api']])
Søren Gjesse932881f2017-06-13 10:43:36 +0200219
220 if options.compiler == 'r8':
Søren Gjesse932881f2017-06-13 10:43:36 +0200221 if 'pgconf' in values and not options.k:
222 for pgconf in values['pgconf']:
223 args.extend(['--pg-conf', pgconf])
Søren Gjesseda2ac8d2017-06-22 14:14:36 +0200224 app_provided_pg_conf = True
Søren Gjesse932881f2017-06-13 10:43:36 +0200225 if options.k:
226 args.extend(['--pg-conf', options.k])
Søren Gjessec801ecc2017-08-03 13:40:06 +0200227 if 'maindexrules' in values:
228 for rules in values['maindexrules']:
229 args.extend(['--main-dex-rules', rules])
Søren Gjesse932881f2017-06-13 10:43:36 +0200230
Mads Ager418d1ca2017-05-22 09:35:49 +0200231 if not options.no_libraries and 'libraries' in values:
232 for lib in values['libraries']:
233 args.extend(['--lib', lib])
234
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200235 if not outdir.endswith('.zip') and not outdir.endswith('.jar') \
236 and not os.path.exists(outdir):
Mads Ager418d1ca2017-05-22 09:35:49 +0200237 os.makedirs(outdir)
238
Søren Gjesse932881f2017-06-13 10:43:36 +0200239 if options.compiler == 'r8':
240 if 'r8-flags' in values:
241 args.extend(values['r8-flags'].split(' '))
Tamas Kenez139acc12017-06-14 17:14:58 +0200242
243 if options.compiler_flags:
244 args.extend(options.compiler_flags.split(' '))
245 if options.r8_flags:
246 args.extend(options.r8_flags.split(' '))
Mads Ager418d1ca2017-05-22 09:35:49 +0200247
248 if inputs:
249 args.extend(inputs)
250
Tamas Kenezf2ee2a32017-06-21 10:30:20 +0200251 t0 = time.time()
Mads Ager418d1ca2017-05-22 09:35:49 +0200252 if options.dump_args_file:
253 with open(options.dump_args_file, 'w') as args_file:
254 args_file.writelines([arg + os.linesep for arg in args])
255 else:
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200256 with utils.TempDir() as temp:
257 if options.print_memoryuse and not options.track_memory_to_file:
258 options.track_memory_to_file = os.path.join(temp,
259 utils.MEMORY_USE_TMP_FILE)
Mathias Ravdd6a6de2018-05-18 10:18:33 +0200260 if options.compiler == 'r8' and app_provided_pg_conf:
261 # Ensure that output of -printmapping and -printseeds go to the output
262 # location and not where the app Proguard configuration places them.
263 if outdir.endswith('.zip') or outdir.endswith('.jar'):
264 pg_outdir = os.path.dirname(outdir)
265 else:
266 pg_outdir = outdir
267 additional_pg_conf = GenerateAdditionalProguardConfiguration(
268 temp, os.path.abspath(pg_outdir))
269 args.extend(['--pg-conf', additional_pg_conf])
Rico Wind1f4172c2018-09-06 16:29:03 +0200270 build = not options.no_build and not options.golem
Christoffer Quist Adamsen21c66602018-08-09 16:22:54 +0200271 exit_code = toolhelper.run(options.compiler, args,
Rico Wind1f4172c2018-09-06 16:29:03 +0200272 build=build,
Mathias Ravdd6a6de2018-05-18 10:18:33 +0200273 debug=not options.no_debug,
274 profile=options.profile,
Mathias Rava4042f52018-05-23 09:58:58 +0200275 track_memory_file=options.track_memory_to_file)
Christoffer Quist Adamsen21c66602018-08-09 16:22:54 +0200276 if exit_code != 0:
277 return exit_code
278
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200279 if options.print_memoryuse:
280 print('{}(MemoryUse): {}'
281 .format(options.print_memoryuse,
282 utils.grep_memoryuse(options.track_memory_to_file)))
Mads Ager418d1ca2017-05-22 09:35:49 +0200283
Tamas Kenezf2ee2a32017-06-21 10:30:20 +0200284 if options.print_runtimeraw:
285 print('{}(RunTimeRaw): {} ms'
286 .format(options.print_runtimeraw, 1000.0 * (time.time() - t0)))
287
Tamas Kenez02bff032017-07-18 12:13:58 +0200288 if options.print_dexsegments:
289 dex_files = glob(os.path.join(outdir, '*.dex'))
290 utils.print_dexsegments(options.print_dexsegments, dex_files)
Rico Windb57bbc12018-09-20 19:23:32 +0200291 return 0
Tamas Kenez02bff032017-07-18 12:13:58 +0200292
Mads Ager418d1ca2017-05-22 09:35:49 +0200293if __name__ == '__main__':
Tamas Kenez5b1c5852017-07-21 13:38:33 +0200294 sys.exit(main(sys.argv[1:]))