Add run_proguard_dx_on_app.py
Extends run_proguard_dx_on_gmscore.py to to youtube.
Gmail does not work yet, the same proguard command line fails
on gmail_android_170604.16.tar.gz.
Bug:
Change-Id: If342a7c3c482f3f9e49a0734a99730c3cb34c514
diff --git a/tools/run_proguard_dx_on_app.py b/tools/run_proguard_dx_on_app.py
new file mode 100755
index 0000000..8578d1e
--- /dev/null
+++ b/tools/run_proguard_dx_on_app.py
@@ -0,0 +1,156 @@
+#!/usr/bin/env python
+# Copyright (c) 2017, 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.
+
+# Run ProGuard and the DX or CompatDX (= D8) tool on GmsCore V10.
+
+from __future__ import print_function
+from glob import glob
+from os import makedirs
+from os.path import exists, join, splitext
+from subprocess import check_call
+import argparse
+import fnmatch
+import gmscore_data
+import os
+import stat
+import sys
+import time
+
+import gmail_data
+import gmscore_data
+import proguard
+import utils
+import youtube_data
+
+APPS = ['gmscore', 'youtube']
+DX_JAR = join(utils.REPO_ROOT, 'tools', 'linux', 'dx', 'framework', 'dx.jar')
+COMPATDX_JAR = join(utils.REPO_ROOT, 'build', 'libs', 'compatdx.jar')
+
+def parse_arguments(argv):
+ parser = argparse.ArgumentParser(
+ description = 'Run ProGuard and the DX tool on GmsCore V10.')
+ parser.add_argument('--app', required = True, choices = APPS)
+ parser.add_argument('--out',
+ help = 'Output directory for the DX tool.',
+ default = os.getcwd())
+ parser.add_argument('--compatdx',
+ help = 'Use CompatDx (D8) instead of DX.',
+ default = False,
+ action = 'store_true')
+ parser.add_argument('--print-runtimeraw',
+ metavar = 'BENCHMARKNAME',
+ help = 'Print the line \'<BENCHMARKNAME>(RunTimeRaw): <elapsed>' +
+ ' ms\' at the end where <elapsed> is the elapsed time in' +
+ ' milliseconds.')
+ parser.add_argument('--print-memoryuse',
+ metavar='BENCHMARKNAME',
+ help='Print the line \'<BENCHMARKNAME>(MemoryUse):' +
+ ' <mem>\' at the end where <mem> is the peak' +
+ ' peak resident set size (VmHWM) in bytes.')
+ parser.add_argument('--print-dexsegments',
+ metavar = 'BENCHMARKNAME',
+ help = 'Print the sizes of individual dex segments as ' +
+ '\'<BENCHMARKNAME>-<segment>(CodeSize): <bytes>\'')
+ return parser.parse_args(argv)
+
+def Main(argv):
+ options = parse_arguments(argv)
+
+ outdir = options.out
+
+ if options.app == 'gmscore':
+ version = 'v10'
+ data = gmscore_data
+ base = data.V10_BASE
+ elif options.app == 'youtube':
+ version = '12.22'
+ data = youtube_data
+ base = data.V12_22_BASE
+ else:
+ raise Exception('Unexpected')
+
+
+ args = ['-forceprocessing']
+
+ if not outdir.endswith('.zip') and not outdir.endswith('.jar') \
+ and not exists(outdir):
+ makedirs(outdir)
+
+
+ values_deploy = data.VERSIONS[version]['deploy']
+ values_proguarded = data.VERSIONS[version]['proguarded']
+ assert 'pgconf' in values_deploy
+
+ for pgconf in values_deploy['pgconf']:
+ args.extend(['@' + pgconf])
+
+ # find seeds file
+ inputs = data.VERSIONS[version]['proguarded']['inputs']
+ assert len(inputs) == 1
+ basename_wo_ext = splitext(os.path.basename(inputs[0]))[0]
+ seeds_filename = basename_wo_ext + '.seeds'
+
+ seeds_files = []
+ for root, dirnames, filenames in os.walk(join(base, 'blaze-out')):
+ for filename in fnmatch.filter(filenames, seeds_filename):
+ seeds_files.append(os.path.join(root, filename))
+ assert len(seeds_files) == 1
+
+ seeds_path = seeds_files[0]
+ proguarded_jar_path = splitext(seeds_path)[0] + '.jar'
+
+ # Remove write-protection from seeds file. The seeds file is an output of
+ # ProGuard so it aborts if this is not writeable.
+ st = os.stat(seeds_path)
+ os.chmod(seeds_path,
+ st.st_mode | stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH)
+
+ t0 = time.time()
+
+ proguard_memoryuse = None
+
+ with utils.TempDir() as temp:
+ track_memory_file = None
+ if options.print_memoryuse:
+ track_memory_file = join(temp, utils.MEMORY_USE_TMP_FILE)
+ proguard.run(args, track_memory_file = track_memory_file)
+ if options.print_memoryuse:
+ proguard_memoryuse = utils.grep_memoryuse(track_memory_file)
+
+ # run dex on the result
+ if options.compatdx:
+ jar = COMPATDX_JAR
+ else:
+ jar = DX_JAR
+
+ with utils.TempDir() as temp:
+ track_memory_file = None
+ cmd = []
+ if options.print_memoryuse:
+ track_memory_file = join(temp, utils.MEMORY_USE_TMP_FILE)
+ cmd.extend(['tools/track_memory.sh', track_memory_file])
+ cmd.extend(['java', '-jar', jar, '--multi-dex',
+ '--output=' + outdir])
+ if 'min-api' in values_proguarded:
+ cmd.append('--min-sdk-version=' + values_proguarded['min-api'])
+ cmd.extend(['--dex', proguarded_jar_path])
+ utils.PrintCmd(cmd);
+ check_call(cmd)
+ if options.print_memoryuse:
+ dx_memoryuse = utils.grep_memoryuse(track_memory_file)
+ print('{}(MemoryUse): {}'
+ .format(options.print_memoryuse,
+ max(proguard_memoryuse, dx_memoryuse)))
+
+ if options.print_runtimeraw:
+ print('{}(RunTimeRaw): {} ms'
+ .format(options.print_runtimeraw, 1000.0 * (time.time() - t0)))
+
+ if options.print_dexsegments:
+ dex_files = glob(os.path.join(outdir, '*.dex'))
+ utils.print_dexsegments(options.print_dexsegments, dex_files)
+
+if __name__ == '__main__':
+ sys.exit(Main(sys.argv[1:]))