blob: d8fac83ed24169ba41b744d0d5fdb5957bf1740c [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
Mads Ager418d1ca2017-05-22 09:35:49 +02008import optparse
9import os
Mads Ager418d1ca2017-05-22 09:35:49 +020010import sys
Tamas Kenezf2ee2a32017-06-21 10:30:20 +020011import time
Mads Ager418d1ca2017-05-22 09:35:49 +020012
Ian Zerny877c1862017-07-06 11:12:26 +020013import d8
Søren Gjesse5ecb04a2017-06-13 09:44:32 +020014import gmail_data
Ian Zerny877c1862017-07-06 11:12:26 +020015import gmscore_data
16import r8
17import utils
18import youtube_data
Mads Ager418d1ca2017-05-22 09:35:49 +020019
20TYPES = ['dex', 'deploy', 'proguarded']
Søren Gjesse5ecb04a2017-06-13 09:44:32 +020021APPS = ['gmscore', 'youtube', 'gmail']
Tamas Kenez5b1c5852017-07-21 13:38:33 +020022COMPILERS = ['d8', 'r8']
Mads Ager418d1ca2017-05-22 09:35:49 +020023
Tamas Kenez5b1c5852017-07-21 13:38:33 +020024def ParseOptions(argv):
Mads Ager418d1ca2017-05-22 09:35:49 +020025 result = optparse.OptionParser()
Søren Gjesse932881f2017-06-13 10:43:36 +020026 result.add_option('--compiler',
27 help='',
Tamas Kenez5b1c5852017-07-21 13:38:33 +020028 choices=COMPILERS)
Mads Ager418d1ca2017-05-22 09:35:49 +020029 result.add_option('--app',
30 help='',
Mads Ager418d1ca2017-05-22 09:35:49 +020031 choices=APPS)
32 result.add_option('--type',
Tamas Kenez3fdaabd2017-06-15 13:05:12 +020033 help='Default for R8: deploy, for D8: proguarded',
Mads Ager418d1ca2017-05-22 09:35:49 +020034 choices=TYPES)
35 result.add_option('--out',
36 help='',
37 default=os.getcwd())
38 result.add_option('--no-build',
39 help='',
40 default=False,
41 action='store_true')
42 result.add_option('--no-libraries',
43 help='',
44 default=False,
45 action='store_true')
46 result.add_option('--no-debug',
47 help='Run without debug asserts.',
48 default=False,
49 action='store_true')
50 result.add_option('--version',
51 help='')
52 result.add_option('-k',
53 help='Override the default ProGuard keep rules')
Tamas Kenez139acc12017-06-14 17:14:58 +020054 result.add_option('--compiler-flags',
55 help='Additional option(s) for the compiler. ' +
56 'If passing several options use a quoted string.')
Mads Ager418d1ca2017-05-22 09:35:49 +020057 result.add_option('--r8-flags',
Tamas Kenez139acc12017-06-14 17:14:58 +020058 help='Additional option(s) for the compiler. ' +
Tamas Kenezfc34cd82017-07-13 12:43:57 +020059 'Same as --compiler-flags, keeping it for backward'
60 ' compatibility. ' +
Mads Ager418d1ca2017-05-22 09:35:49 +020061 'If passing several options use a quoted string.')
Tamas Kenezfc34cd82017-07-13 12:43:57 +020062 # TODO(tamaskenez) remove track-memory-to-file as soon as we updated golem
63 # to use --print-memoryuse instead
Mads Ager418d1ca2017-05-22 09:35:49 +020064 result.add_option('--track-memory-to-file',
65 help='Track how much memory the jvm is using while ' +
66 ' compiling. Output to the specified file.')
67 result.add_option('--profile',
68 help='Profile R8 run.',
69 default=False,
70 action='store_true')
71 result.add_option('--dump-args-file',
72 help='Dump a file with the arguments for the specified ' +
73 'configuration. For use as a @<file> argument to perform ' +
74 'the run.')
Tamas Kenezf2ee2a32017-06-21 10:30:20 +020075 result.add_option('--print-runtimeraw',
76 metavar='BENCHMARKNAME',
Tamas Kenez02bff032017-07-18 12:13:58 +020077 help='Print the line \'<BENCHMARKNAME>(RunTimeRaw):' +
78 ' <elapsed> ms\' at the end where <elapsed> is' +
79 ' the elapsed time in milliseconds.')
Tamas Kenezfc34cd82017-07-13 12:43:57 +020080 result.add_option('--print-memoryuse',
81 metavar='BENCHMARKNAME',
Tamas Kenez02bff032017-07-18 12:13:58 +020082 help='Print the line \'<BENCHMARKNAME>(MemoryUse):' +
83 ' <mem>\' at the end where <mem> is the peak' +
84 ' peak resident set size (VmHWM) in bytes.')
85 result.add_option('--print-dexsegments',
86 metavar='BENCHMARKNAME',
87 help='Print the sizes of individual dex segments as ' +
88 '\'<BENCHMARKNAME>-<segment>(CodeSize): <bytes>\'')
Tamas Kenez5b1c5852017-07-21 13:38:33 +020089 return result.parse_args(argv)
Mads Ager418d1ca2017-05-22 09:35:49 +020090
Søren Gjesse3a5aed92017-06-14 15:36:02 +020091# Most apps have the -printmapping and -printseeds in the Proguard
92# configuration. However we don't want to write these files in these
93# locations. Instead generate an auxiliary Proguard configuration
94# placing these two output files together with the dex output.
95def GenerateAdditionalProguardConfiguration(temp, outdir):
96 name = "output.config"
Tamas Kenezfc34cd82017-07-13 12:43:57 +020097 with open(os.path.join(temp, name), 'w') as f:
98 f.write('-printmapping ' + os.path.join(outdir, 'proguard.map') + "\n")
99 f.write('-printseeds ' + os.path.join(outdir, 'proguard.seeds') + "\n")
100 return os.path.abspath(f.name)
Søren Gjesse3a5aed92017-06-14 15:36:02 +0200101
Tamas Kenez5b1c5852017-07-21 13:38:33 +0200102def main(argv):
Tamas Kenez2cf47cf2017-07-25 10:22:52 +0200103 utils.check_java_version()
Søren Gjesseda2ac8d2017-06-22 14:14:36 +0200104 app_provided_pg_conf = False;
Tamas Kenez5b1c5852017-07-21 13:38:33 +0200105 (options, args) = ParseOptions(argv)
Mads Ager418d1ca2017-05-22 09:35:49 +0200106 outdir = options.out
107 data = None
108 if options.app == 'gmscore':
109 options.version = options.version or 'v9'
110 data = gmscore_data
111 elif options.app == 'youtube':
Søren Gjessecc33fb42017-06-09 10:25:08 +0200112 options.version = options.version or '12.22'
Mads Ager418d1ca2017-05-22 09:35:49 +0200113 data = youtube_data
Søren Gjesse5ecb04a2017-06-13 09:44:32 +0200114 elif options.app == 'gmail':
115 options.version = options.version or '170604.16'
116 data = gmail_data
Mads Ager418d1ca2017-05-22 09:35:49 +0200117 else:
Tamas Kenez5b1c5852017-07-21 13:38:33 +0200118 raise Exception("You need to specify '--app={}'".format('|'.join(APPS)))
119
120 if options.compiler not in COMPILERS:
121 raise Exception("You need to specify '--compiler={}'"
122 .format('|'.join(COMPILERS)))
Mads Ager418d1ca2017-05-22 09:35:49 +0200123
124 if not options.version in data.VERSIONS.keys():
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200125 print('No version {} for application {}'
126 .format(options.version, options.app))
127 print('Valid versions are {}'.format(data.VERSIONS.keys()))
Mads Ager418d1ca2017-05-22 09:35:49 +0200128 return 1
129
130 version = data.VERSIONS[options.version]
131
Tamas Kenez3fdaabd2017-06-15 13:05:12 +0200132 if not options.type:
133 options.type = 'deploy' if options.compiler == 'r8' \
134 else 'proguarded'
135
Mads Ager418d1ca2017-05-22 09:35:49 +0200136 if options.type not in version:
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200137 print('No type {} for version {}'.format(options.type, options.version))
138 print('Valid types are {}'.format(version.keys()))
Mads Ager418d1ca2017-05-22 09:35:49 +0200139 return 1
140 values = version[options.type]
141 inputs = None
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200142 # For R8 'deploy' the JAR is located using the Proguard configuration
143 # -injars option.
144 if 'inputs' in values and (options.compiler != 'r8'
145 or options.type != 'deploy'):
Mads Ager418d1ca2017-05-22 09:35:49 +0200146 inputs = values['inputs']
147
148 args.extend(['--output', outdir])
Ian Zerny877c1862017-07-06 11:12:26 +0200149 if 'min-api' in values:
150 args.extend(['--min-api', values['min-api']])
Søren Gjesse932881f2017-06-13 10:43:36 +0200151
152 if options.compiler == 'r8':
Søren Gjesse932881f2017-06-13 10:43:36 +0200153 if 'pgconf' in values and not options.k:
154 for pgconf in values['pgconf']:
155 args.extend(['--pg-conf', pgconf])
Søren Gjesseda2ac8d2017-06-22 14:14:36 +0200156 app_provided_pg_conf = True
Søren Gjesse932881f2017-06-13 10:43:36 +0200157 if options.k:
158 args.extend(['--pg-conf', options.k])
Søren Gjessec801ecc2017-08-03 13:40:06 +0200159 if 'maindexrules' in values:
160 for rules in values['maindexrules']:
161 args.extend(['--main-dex-rules', rules])
Søren Gjesse932881f2017-06-13 10:43:36 +0200162
Mads Ager418d1ca2017-05-22 09:35:49 +0200163 if not options.no_libraries and 'libraries' in values:
164 for lib in values['libraries']:
165 args.extend(['--lib', lib])
166
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200167 if not outdir.endswith('.zip') and not outdir.endswith('.jar') \
168 and not os.path.exists(outdir):
Mads Ager418d1ca2017-05-22 09:35:49 +0200169 os.makedirs(outdir)
170
Søren Gjesse932881f2017-06-13 10:43:36 +0200171 if options.compiler == 'r8':
172 if 'r8-flags' in values:
173 args.extend(values['r8-flags'].split(' '))
Tamas Kenez139acc12017-06-14 17:14:58 +0200174
175 if options.compiler_flags:
176 args.extend(options.compiler_flags.split(' '))
177 if options.r8_flags:
178 args.extend(options.r8_flags.split(' '))
Mads Ager418d1ca2017-05-22 09:35:49 +0200179
180 if inputs:
181 args.extend(inputs)
182
Tamas Kenezf2ee2a32017-06-21 10:30:20 +0200183 t0 = time.time()
Mads Ager418d1ca2017-05-22 09:35:49 +0200184 if options.dump_args_file:
185 with open(options.dump_args_file, 'w') as args_file:
186 args_file.writelines([arg + os.linesep for arg in args])
187 else:
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200188 with utils.TempDir() as temp:
189 if options.print_memoryuse and not options.track_memory_to_file:
190 options.track_memory_to_file = os.path.join(temp,
191 utils.MEMORY_USE_TMP_FILE)
192 if options.compiler == 'd8':
193 d8.run(args, not options.no_build, not options.no_debug,
194 options.profile, options.track_memory_to_file)
195 else:
Søren Gjesseda2ac8d2017-06-22 14:14:36 +0200196 if app_provided_pg_conf:
197 # Ensure that output of -printmapping and -printseeds go to the output
198 # location and not where the app Proguard configuration places them.
199 if outdir.endswith('.zip') or outdir.endswith('.jar'):
200 pg_outdir = os.path.dirname(outdir)
201 else:
202 pg_outdir = outdir
203 additional_pg_conf = GenerateAdditionalProguardConfiguration(
204 temp, os.path.abspath(pg_outdir))
205 args.extend(['--pg-conf', additional_pg_conf])
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200206 r8.run(args, not options.no_build, not options.no_debug,
207 options.profile, options.track_memory_to_file)
208 if options.print_memoryuse:
209 print('{}(MemoryUse): {}'
210 .format(options.print_memoryuse,
211 utils.grep_memoryuse(options.track_memory_to_file)))
Mads Ager418d1ca2017-05-22 09:35:49 +0200212
Tamas Kenezf2ee2a32017-06-21 10:30:20 +0200213 if options.print_runtimeraw:
214 print('{}(RunTimeRaw): {} ms'
215 .format(options.print_runtimeraw, 1000.0 * (time.time() - t0)))
216
Tamas Kenez02bff032017-07-18 12:13:58 +0200217 if options.print_dexsegments:
218 dex_files = glob(os.path.join(outdir, '*.dex'))
219 utils.print_dexsegments(options.print_dexsegments, dex_files)
220
Mads Ager418d1ca2017-05-22 09:35:49 +0200221if __name__ == '__main__':
Tamas Kenez5b1c5852017-07-21 13:38:33 +0200222 sys.exit(main(sys.argv[1:]))