| #!/usr/bin/env python | |
| # Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file | |
| # for details. All rights reserved. Use of this source code is governed by a | |
| # BSD-style license that can be found in the LICENSE file. | |
| ''' | |
| Build r8lib.jar with both R8 and ProGuard and print a size comparison. | |
| By default, inlining is disabled in both R8 and ProGuard to make | |
| method-by-method comparison much easier. Pass --inlining to enable inlining. | |
| By default, only shows methods where R8's DEX output is 5 or more instructions | |
| larger than ProGuard+D8's output. Pass --threshold 0 to display all methods. | |
| ''' | |
| import argparse | |
| import build_r8lib | |
| import os | |
| import subprocess | |
| import toolhelper | |
| import utils | |
| parser = argparse.ArgumentParser(description=__doc__.strip(), | |
| formatter_class=argparse.RawTextHelpFormatter) | |
| parser.add_argument('-t', '--tmpdir', | |
| help='Store auxiliary files in given directory') | |
| parser.add_argument('-i', '--inlining', action='store_true', | |
| help='Enable inlining') | |
| parser.add_argument('--threshold') | |
| R8_RELOCATIONS = [ | |
| ('com.google.common', 'com.android.tools.r8.com.google.common'), | |
| ('com.google.gson', 'com.android.tools.r8.com.google.gson'), | |
| ('com.google.thirdparty', 'com.android.tools.r8.com.google.thirdparty'), | |
| ('joptsimple', 'com.android.tools.r8.joptsimple'), | |
| ('org.apache.commons', 'com.android.tools.r8.org.apache.commons'), | |
| ('org.objectweb.asm', 'com.android.tools.r8.org.objectweb.asm'), | |
| ('it.unimi.dsi.fastutil', 'com.android.tools.r8.it.unimi.dsi.fastutil'), | |
| ] | |
| def is_output_newer(input, output): | |
| if not os.path.exists(output): | |
| return False | |
| return os.stat(input).st_mtime < os.stat(output).st_mtime | |
| def check_call(args, **kwargs): | |
| utils.PrintCmd(args) | |
| return subprocess.check_call(args, **kwargs) | |
| def main(tmpdir=None, inlining=True, | |
| run_jarsizecompare=True, threshold=None): | |
| if tmpdir is None: | |
| with utils.TempDir() as tmpdir: | |
| return main(tmpdir, inlining) | |
| inline_suffix = '-inline' if inlining else '-noinline' | |
| pg_config = utils.R8LIB_KEEP_RULES | |
| r8lib_jar = os.path.join(utils.LIBS, 'r8lib%s.jar' % inline_suffix) | |
| r8lib_map = os.path.join(utils.LIBS, 'r8lib%s-map.txt' % inline_suffix) | |
| r8lib_args = None | |
| if not inlining: | |
| r8lib_args = ['-Dcom.android.tools.r8.disableinlining=1'] | |
| pg_config = os.path.join(tmpdir, 'keep-noinline.txt') | |
| with open(pg_config, 'w') as new_config: | |
| with open(utils.R8LIB_KEEP_RULES) as old_config: | |
| new_config.write(old_config.read().rstrip('\n') + | |
| '\n-optimizations !method/inlining/*\n') | |
| if not is_output_newer(utils.R8_JAR, r8lib_jar): | |
| r8lib_memory = os.path.join(tmpdir, 'r8lib%s-memory.txt' % inline_suffix) | |
| build_r8lib.build_r8lib( | |
| output_path=r8lib_jar, output_map=r8lib_map, | |
| extra_args=r8lib_args, track_memory_file=r8lib_memory) | |
| pg_output = os.path.join(tmpdir, 'r8lib-pg%s.jar' % inline_suffix) | |
| pg_memory = os.path.join(tmpdir, 'r8lib-pg%s-memory.txt' % inline_suffix) | |
| pg_map = os.path.join(tmpdir, 'r8lib-pg%s-map.txt' % inline_suffix) | |
| pg_args = ['tools/track_memory.sh', pg_memory, | |
| 'third_party/proguard/proguard6.0.2/bin/proguard.sh', | |
| '@' + pg_config, | |
| '-lib', utils.RT_JAR, | |
| '-injar', utils.R8_JAR, | |
| '-printmapping', pg_map, | |
| '-outjar', pg_output] | |
| for library_name, relocated_package in R8_RELOCATIONS: | |
| pg_args.extend(['-dontwarn', relocated_package + '.**', | |
| '-dontnote', relocated_package + '.**']) | |
| check_call(pg_args) | |
| if threshold is None: | |
| threshold = 5 | |
| toolhelper.run('jarsizecompare', | |
| ['--threshold', str(threshold), | |
| '--lib', utils.RT_JAR, | |
| '--input', 'input', utils.R8_JAR, | |
| '--input', 'r8', r8lib_jar, r8lib_map, | |
| '--input', 'pg', pg_output, pg_map]) | |
| if __name__ == '__main__': | |
| main(**vars(parser.parse_args())) |