blob: 9e30644bb1db4aaddfa5371452eae65b8f261218 [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
Søren Gjesse5ecb04a2017-06-13 09:44:32 +020013import gmail_data
Ian Zerny877c1862017-07-06 11:12:26 +020014import gmscore_data
Mathias Ravdd6a6de2018-05-18 10:18:33 +020015import toolhelper
Ian Zerny877c1862017-07-06 11:12:26 +020016import utils
17import youtube_data
Mads Ager418d1ca2017-05-22 09:35:49 +020018
19TYPES = ['dex', 'deploy', 'proguarded']
Søren Gjesse5ecb04a2017-06-13 09:44:32 +020020APPS = ['gmscore', 'youtube', 'gmail']
Tamas Kenez5b1c5852017-07-21 13:38:33 +020021COMPILERS = ['d8', 'r8']
Mads Ager418d1ca2017-05-22 09:35:49 +020022
Tamas Kenez5b1c5852017-07-21 13:38:33 +020023def ParseOptions(argv):
Mads Ager418d1ca2017-05-22 09:35:49 +020024 result = optparse.OptionParser()
Søren Gjesse932881f2017-06-13 10:43:36 +020025 result.add_option('--compiler',
26 help='',
Tamas Kenez5b1c5852017-07-21 13:38:33 +020027 choices=COMPILERS)
Mads Ager418d1ca2017-05-22 09:35:49 +020028 result.add_option('--app',
29 help='',
Mads Ager418d1ca2017-05-22 09:35:49 +020030 choices=APPS)
31 result.add_option('--type',
Tamas Kenez3fdaabd2017-06-15 13:05:12 +020032 help='Default for R8: deploy, for D8: proguarded',
Mads Ager418d1ca2017-05-22 09:35:49 +020033 choices=TYPES)
34 result.add_option('--out',
35 help='',
36 default=os.getcwd())
37 result.add_option('--no-build',
38 help='',
39 default=False,
40 action='store_true')
41 result.add_option('--no-libraries',
42 help='',
43 default=False,
44 action='store_true')
45 result.add_option('--no-debug',
46 help='Run without debug asserts.',
47 default=False,
48 action='store_true')
49 result.add_option('--version',
50 help='')
51 result.add_option('-k',
52 help='Override the default ProGuard keep rules')
Tamas Kenez139acc12017-06-14 17:14:58 +020053 result.add_option('--compiler-flags',
54 help='Additional option(s) for the compiler. ' +
55 'If passing several options use a quoted string.')
Mads Ager418d1ca2017-05-22 09:35:49 +020056 result.add_option('--r8-flags',
Tamas Kenez139acc12017-06-14 17:14:58 +020057 help='Additional option(s) for the compiler. ' +
Tamas Kenezfc34cd82017-07-13 12:43:57 +020058 'Same as --compiler-flags, keeping it for backward'
59 ' compatibility. ' +
Mads Ager418d1ca2017-05-22 09:35:49 +020060 'If passing several options use a quoted string.')
Tamas Kenezfc34cd82017-07-13 12:43:57 +020061 # TODO(tamaskenez) remove track-memory-to-file as soon as we updated golem
62 # to use --print-memoryuse instead
Mads Ager418d1ca2017-05-22 09:35:49 +020063 result.add_option('--track-memory-to-file',
64 help='Track how much memory the jvm is using while ' +
65 ' compiling. Output to the specified file.')
66 result.add_option('--profile',
67 help='Profile R8 run.',
68 default=False,
69 action='store_true')
70 result.add_option('--dump-args-file',
71 help='Dump a file with the arguments for the specified ' +
72 'configuration. For use as a @<file> argument to perform ' +
73 'the run.')
Tamas Kenezf2ee2a32017-06-21 10:30:20 +020074 result.add_option('--print-runtimeraw',
75 metavar='BENCHMARKNAME',
Tamas Kenez02bff032017-07-18 12:13:58 +020076 help='Print the line \'<BENCHMARKNAME>(RunTimeRaw):' +
77 ' <elapsed> ms\' at the end where <elapsed> is' +
78 ' the elapsed time in milliseconds.')
Tamas Kenezfc34cd82017-07-13 12:43:57 +020079 result.add_option('--print-memoryuse',
80 metavar='BENCHMARKNAME',
Tamas Kenez02bff032017-07-18 12:13:58 +020081 help='Print the line \'<BENCHMARKNAME>(MemoryUse):' +
82 ' <mem>\' at the end where <mem> is the peak' +
83 ' peak resident set size (VmHWM) in bytes.')
84 result.add_option('--print-dexsegments',
85 metavar='BENCHMARKNAME',
86 help='Print the sizes of individual dex segments as ' +
87 '\'<BENCHMARKNAME>-<segment>(CodeSize): <bytes>\'')
Tamas Kenez5b1c5852017-07-21 13:38:33 +020088 return result.parse_args(argv)
Mads Ager418d1ca2017-05-22 09:35:49 +020089
Søren Gjesse59459582018-04-06 10:12:45 +020090# Most apps have the -printmapping, -printseeds and -printusage in the
91# Proguard configuration. However we don't want to write these files
92# in the locations specified. Instead generate an auxiliary Proguard
93# configuration placing these two output files together with the dex
94# output.
Søren Gjesse3a5aed92017-06-14 15:36:02 +020095def 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")
Søren Gjesse59459582018-04-06 10:12:45 +0200100 f.write('-printusage ' + os.path.join(outdir, 'proguard.usage') + "\n")
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200101 return os.path.abspath(f.name)
Søren Gjesse3a5aed92017-06-14 15:36:02 +0200102
Tamas Kenez5b1c5852017-07-21 13:38:33 +0200103def main(argv):
Tamas Kenez2cf47cf2017-07-25 10:22:52 +0200104 utils.check_java_version()
Søren Gjesseda2ac8d2017-06-22 14:14:36 +0200105 app_provided_pg_conf = False;
Tamas Kenez5b1c5852017-07-21 13:38:33 +0200106 (options, args) = ParseOptions(argv)
Mads Ager418d1ca2017-05-22 09:35:49 +0200107 outdir = options.out
108 data = None
109 if options.app == 'gmscore':
110 options.version = options.version or 'v9'
111 data = gmscore_data
112 elif options.app == 'youtube':
Søren Gjessecc33fb42017-06-09 10:25:08 +0200113 options.version = options.version or '12.22'
Mads Ager418d1ca2017-05-22 09:35:49 +0200114 data = youtube_data
Søren Gjesse5ecb04a2017-06-13 09:44:32 +0200115 elif options.app == 'gmail':
116 options.version = options.version or '170604.16'
117 data = gmail_data
Mads Ager418d1ca2017-05-22 09:35:49 +0200118 else:
Tamas Kenez5b1c5852017-07-21 13:38:33 +0200119 raise Exception("You need to specify '--app={}'".format('|'.join(APPS)))
120
121 if options.compiler not in COMPILERS:
122 raise Exception("You need to specify '--compiler={}'"
123 .format('|'.join(COMPILERS)))
Mads Ager418d1ca2017-05-22 09:35:49 +0200124
125 if not options.version in data.VERSIONS.keys():
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200126 print('No version {} for application {}'
127 .format(options.version, options.app))
128 print('Valid versions are {}'.format(data.VERSIONS.keys()))
Mads Ager418d1ca2017-05-22 09:35:49 +0200129 return 1
130
131 version = data.VERSIONS[options.version]
132
Tamas Kenez3fdaabd2017-06-15 13:05:12 +0200133 if not options.type:
134 options.type = 'deploy' if options.compiler == 'r8' \
135 else 'proguarded'
136
Mads Ager418d1ca2017-05-22 09:35:49 +0200137 if options.type not in version:
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200138 print('No type {} for version {}'.format(options.type, options.version))
139 print('Valid types are {}'.format(version.keys()))
Mads Ager418d1ca2017-05-22 09:35:49 +0200140 return 1
141 values = version[options.type]
142 inputs = None
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200143 # For R8 'deploy' the JAR is located using the Proguard configuration
144 # -injars option.
145 if 'inputs' in values and (options.compiler != 'r8'
146 or options.type != 'deploy'):
Mads Ager418d1ca2017-05-22 09:35:49 +0200147 inputs = values['inputs']
148
149 args.extend(['--output', outdir])
Ian Zerny877c1862017-07-06 11:12:26 +0200150 if 'min-api' in values:
151 args.extend(['--min-api', values['min-api']])
Søren Gjesse932881f2017-06-13 10:43:36 +0200152
153 if options.compiler == 'r8':
Søren Gjesse932881f2017-06-13 10:43:36 +0200154 if 'pgconf' in values and not options.k:
155 for pgconf in values['pgconf']:
156 args.extend(['--pg-conf', pgconf])
Søren Gjesseda2ac8d2017-06-22 14:14:36 +0200157 app_provided_pg_conf = True
Søren Gjesse932881f2017-06-13 10:43:36 +0200158 if options.k:
159 args.extend(['--pg-conf', options.k])
Søren Gjessec801ecc2017-08-03 13:40:06 +0200160 if 'maindexrules' in values:
161 for rules in values['maindexrules']:
162 args.extend(['--main-dex-rules', rules])
Søren Gjesse932881f2017-06-13 10:43:36 +0200163
Mads Ager418d1ca2017-05-22 09:35:49 +0200164 if not options.no_libraries and 'libraries' in values:
165 for lib in values['libraries']:
166 args.extend(['--lib', lib])
167
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200168 if not outdir.endswith('.zip') and not outdir.endswith('.jar') \
169 and not os.path.exists(outdir):
Mads Ager418d1ca2017-05-22 09:35:49 +0200170 os.makedirs(outdir)
171
Søren Gjesse932881f2017-06-13 10:43:36 +0200172 if options.compiler == 'r8':
173 if 'r8-flags' in values:
174 args.extend(values['r8-flags'].split(' '))
Tamas Kenez139acc12017-06-14 17:14:58 +0200175
176 if options.compiler_flags:
177 args.extend(options.compiler_flags.split(' '))
178 if options.r8_flags:
179 args.extend(options.r8_flags.split(' '))
Mads Ager418d1ca2017-05-22 09:35:49 +0200180
181 if inputs:
182 args.extend(inputs)
183
Tamas Kenezf2ee2a32017-06-21 10:30:20 +0200184 t0 = time.time()
Mads Ager418d1ca2017-05-22 09:35:49 +0200185 if options.dump_args_file:
186 with open(options.dump_args_file, 'w') as args_file:
187 args_file.writelines([arg + os.linesep for arg in args])
188 else:
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200189 with utils.TempDir() as temp:
190 if options.print_memoryuse and not options.track_memory_to_file:
191 options.track_memory_to_file = os.path.join(temp,
192 utils.MEMORY_USE_TMP_FILE)
Mathias Ravdd6a6de2018-05-18 10:18:33 +0200193 if options.compiler == 'r8' and app_provided_pg_conf:
194 # Ensure that output of -printmapping and -printseeds go to the output
195 # location and not where the app Proguard configuration places them.
196 if outdir.endswith('.zip') or outdir.endswith('.jar'):
197 pg_outdir = os.path.dirname(outdir)
198 else:
199 pg_outdir = outdir
200 additional_pg_conf = GenerateAdditionalProguardConfiguration(
201 temp, os.path.abspath(pg_outdir))
202 args.extend(['--pg-conf', additional_pg_conf])
Christoffer Quist Adamsen21c66602018-08-09 16:22:54 +0200203 exit_code = toolhelper.run(options.compiler, args,
204 build=not options.no_build,
Mathias Ravdd6a6de2018-05-18 10:18:33 +0200205 debug=not options.no_debug,
206 profile=options.profile,
Mathias Rava4042f52018-05-23 09:58:58 +0200207 track_memory_file=options.track_memory_to_file)
Christoffer Quist Adamsen21c66602018-08-09 16:22:54 +0200208 if exit_code != 0:
209 return exit_code
210
Tamas Kenezfc34cd82017-07-13 12:43:57 +0200211 if options.print_memoryuse:
212 print('{}(MemoryUse): {}'
213 .format(options.print_memoryuse,
214 utils.grep_memoryuse(options.track_memory_to_file)))
Mads Ager418d1ca2017-05-22 09:35:49 +0200215
Tamas Kenezf2ee2a32017-06-21 10:30:20 +0200216 if options.print_runtimeraw:
217 print('{}(RunTimeRaw): {} ms'
218 .format(options.print_runtimeraw, 1000.0 * (time.time() - t0)))
219
Tamas Kenez02bff032017-07-18 12:13:58 +0200220 if options.print_dexsegments:
221 dex_files = glob(os.path.join(outdir, '*.dex'))
222 utils.print_dexsegments(options.print_dexsegments, dex_files)
223
Mads Ager418d1ca2017-05-22 09:35:49 +0200224if __name__ == '__main__':
Tamas Kenez5b1c5852017-07-21 13:38:33 +0200225 sys.exit(main(sys.argv[1:]))