1#!/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 6# Run ProGuard and the DX or CompatDX (= D8) tool on GmsCore V10. 7 8from __future__ import print_function 9from glob import glob 10from os import makedirs 11from os.path import exists, join 12from subprocess import check_call 13import argparse 14import gmscore_data 15import os 16import stat 17import sys 18import time 19 20import proguard 21import utils 22 23BLAZE_BUILD_DIR = join(gmscore_data.V10_BASE, 24 'blaze-out', 'intel-linux-android-4.8-libcxx-x86-opt', 'bin', 'java', 25 'com', 'google', 'android', 'gmscore', 'integ') 26PROGUARDED_OUTPUT = join(BLAZE_BUILD_DIR, 27 'GmsCore_prod_alldpi_release_all_locales_proguard.jar') 28GMSCORE_SEEDS_FILE = join(BLAZE_BUILD_DIR, 29 'GmsCore_prod_alldpi_release_all_locales_proguard.seeds') 30DX_JAR = join(utils.REPO_ROOT, 'tools', 'linux', 'dx', 'framework', 'dx.jar') 31COMPATDX_JAR = join(utils.REPO_ROOT, 'build', 'libs', 'compatdx.jar') 32 33def parse_arguments(): 34 parser = argparse.ArgumentParser( 35 description = 'Run ProGuard and the DX tool on GmsCore V10.') 36 parser.add_argument('--out', 37 help = 'Output directory for the DX tool.', 38 default = os.getcwd()) 39 parser.add_argument('--print-runtimeraw', 40 metavar = 'BENCHMARKNAME', 41 help = 'Print the line \'<BENCHMARKNAME>(RunTimeRaw): <elapsed>' + 42 ' ms\' at the end where <elapsed> is the elapsed time in' + 43 ' milliseconds.') 44 parser.add_argument('--print-memoryuse', 45 metavar='BENCHMARKNAME', 46 help='Print the line \'<BENCHMARKNAME>(MemoryUse):' + 47 ' <mem>\' at the end where <mem> is the peak' + 48 ' peak resident set size (VmHWM) in bytes.') 49 parser.add_argument('--compatdx', 50 help = 'Use CompatDx (D8) instead of DX.', 51 default = False, 52 action = 'store_true') 53 parser.add_argument('--print-dexsegments', 54 metavar = 'BENCHMARKNAME', 55 help = 'Print the sizes of individual dex segments as ' + 56 '\'<BENCHMARKNAME>-<segment>(CodeSize): <bytes>\'') 57 return parser.parse_args() 58 59def Main(): 60 options = parse_arguments() 61 62 outdir = options.out 63 64 args = ['-forceprocessing'] 65 66 if not outdir.endswith('.zip') and not outdir.endswith('.jar') \ 67 and not exists(outdir): 68 makedirs(outdir) 69 70 version = gmscore_data.VERSIONS['v10'] 71 values = version['deploy'] 72 assert 'pgconf' in values 73 74 for pgconf in values['pgconf']: 75 args.extend(['@' + pgconf]) 76 77 # Remove write-protection from seeds file. The seeds file is an output of 78 # ProGuard so it aborts if this is not writeable. 79 st = os.stat(GMSCORE_SEEDS_FILE) 80 os.chmod(GMSCORE_SEEDS_FILE, 81 st.st_mode | stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH) 82 83 t0 = time.time() 84 85 proguard_memoryuse = None 86 87 with utils.TempDir() as temp: 88 track_memory_file = None 89 if options.print_memoryuse: 90 track_memory_file = join(temp, utils.MEMORY_USE_TMP_FILE) 91 proguard.run(args, track_memory_file = track_memory_file) 92 if options.print_memoryuse: 93 proguard_memoryuse = utils.grep_memoryuse(track_memory_file) 94 95 # run dex on the result 96 if options.compatdx: 97 jar = COMPATDX_JAR 98 else: 99 jar = DX_JAR 100 101 with utils.TempDir() as temp: 102 track_memory_file = None 103 cmd = [] 104 if options.print_memoryuse: 105 track_memory_file = join(temp, utils.MEMORY_USE_TMP_FILE) 106 cmd.extend(['tools/track_memory.sh', track_memory_file]) 107 cmd.extend(['java', '-jar', jar, '--min-sdk-version=26', '--multi-dex', 108 '--output=' + outdir, '--dex', PROGUARDED_OUTPUT]); 109 utils.PrintCmd(cmd); 110 check_call(cmd) 111 if options.print_memoryuse: 112 dx_memoryuse = utils.grep_memoryuse(track_memory_file) 113 print('{}(MemoryUse): {}' 114 .format(options.print_memoryuse, 115 max(proguard_memoryuse, dx_memoryuse))) 116 117 if options.print_runtimeraw: 118 print('{}(RunTimeRaw): {} ms' 119 .format(options.print_runtimeraw, 1000.0 * (time.time() - t0))) 120 121 if options.print_dexsegments: 122 dex_files = glob(os.path.join(outdir, '*.dex')) 123 utils.print_dexsegments(options.print_dexsegments, dex_files) 124 125if __name__ == '__main__': 126 sys.exit(Main()) 127