blob: bb1d72a2f9f51c13b5ede02b051ea115d343ac8a [file] [log] [blame]
Tamas Keneze4d79c42017-07-21 12:31:50 +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
Søren Gjessea99636c2019-11-28 14:00:26 +01006# Run ProGuard and the DX (= D8) tool on GmsCore V10.
Tamas Keneze4d79c42017-07-21 12:31:50 +02007
8from __future__ import print_function
9from glob import glob
10from os import makedirs
11from os.path import exists, join, splitext
12from subprocess import check_call
13import argparse
14import fnmatch
15import gmscore_data
Ian Zerny3f54e222019-02-12 10:51:17 +010016import jdk
Tamas Keneze4d79c42017-07-21 12:31:50 +020017import os
18import stat
19import sys
20import time
21
22import gmail_data
23import gmscore_data
Rico Wind1f4172c2018-09-06 16:29:03 +020024import golem
Tamas Keneze4d79c42017-07-21 12:31:50 +020025import proguard
26import utils
27import youtube_data
28
29APPS = ['gmscore', 'youtube']
30DX_JAR = join(utils.REPO_ROOT, 'tools', 'linux', 'dx', 'framework', 'dx.jar')
Tamas Keneze4d79c42017-07-21 12:31:50 +020031
32def parse_arguments(argv):
33 parser = argparse.ArgumentParser(
34 description = 'Run ProGuard and the DX tool on GmsCore V10.')
35 parser.add_argument('--app', required = True, choices = APPS)
36 parser.add_argument('--out',
37 help = 'Output directory for the DX tool.',
38 default = os.getcwd())
Rico Wind1f4172c2018-09-06 16:29:03 +020039 parser.add_argument('--golem',
40 help = 'Link in third party dependencies.',
41 default = False,
42 action = 'store_true')
Tamas Keneze4d79c42017-07-21 12:31:50 +020043 parser.add_argument('--print-runtimeraw',
44 metavar = 'BENCHMARKNAME',
45 help = 'Print the line \'<BENCHMARKNAME>(RunTimeRaw): <elapsed>' +
46 ' ms\' at the end where <elapsed> is the elapsed time in' +
47 ' milliseconds.')
48 parser.add_argument('--print-memoryuse',
49 metavar='BENCHMARKNAME',
50 help='Print the line \'<BENCHMARKNAME>(MemoryUse):' +
51 ' <mem>\' at the end where <mem> is the peak' +
52 ' peak resident set size (VmHWM) in bytes.')
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(argv)
58
59def Main(argv):
Tamas Keneze4d79c42017-07-21 12:31:50 +020060 options = parse_arguments(argv)
Rico Wind1f4172c2018-09-06 16:29:03 +020061 if options.golem:
62 golem.link_third_party()
Ian Zerny09e8a462019-03-26 08:59:32 +010063 utils.check_java_version()
Tamas Keneze4d79c42017-07-21 12:31:50 +020064 outdir = options.out
65
66 if options.app == 'gmscore':
67 version = 'v10'
68 data = gmscore_data
69 base = data.V10_BASE
70 elif options.app == 'youtube':
71 version = '12.22'
72 data = youtube_data
73 base = data.V12_22_BASE
74 else:
75 raise Exception('Unexpected')
76
77
78 args = ['-forceprocessing']
79
80 if not outdir.endswith('.zip') and not outdir.endswith('.jar') \
81 and not exists(outdir):
82 makedirs(outdir)
83
84
85 values_deploy = data.VERSIONS[version]['deploy']
86 values_proguarded = data.VERSIONS[version]['proguarded']
87 assert 'pgconf' in values_deploy
88
89 for pgconf in values_deploy['pgconf']:
90 args.extend(['@' + pgconf])
91
92 # find seeds file
93 inputs = data.VERSIONS[version]['proguarded']['inputs']
94 assert len(inputs) == 1
95 basename_wo_ext = splitext(os.path.basename(inputs[0]))[0]
96 seeds_filename = basename_wo_ext + '.seeds'
97
98 seeds_files = []
99 for root, dirnames, filenames in os.walk(join(base, 'blaze-out')):
100 for filename in fnmatch.filter(filenames, seeds_filename):
101 seeds_files.append(os.path.join(root, filename))
102 assert len(seeds_files) == 1
103
104 seeds_path = seeds_files[0]
105 proguarded_jar_path = splitext(seeds_path)[0] + '.jar'
106
107 # Remove write-protection from seeds file. The seeds file is an output of
108 # ProGuard so it aborts if this is not writeable.
109 st = os.stat(seeds_path)
110 os.chmod(seeds_path,
111 st.st_mode | stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH)
112
113 t0 = time.time()
114
115 proguard_memoryuse = None
116
117 with utils.TempDir() as temp:
118 track_memory_file = None
119 if options.print_memoryuse:
120 track_memory_file = join(temp, utils.MEMORY_USE_TMP_FILE)
Ian Zerny517c7662018-07-11 15:22:29 +0200121 proguard.run(
122 args,
Ian Zerny859dd892020-07-03 11:19:03 +0200123 version='pg_internal',
Ian Zerny517c7662018-07-11 15:22:29 +0200124 track_memory_file = track_memory_file,
125 stdout=open(os.devnull, 'w'))
Tamas Keneze4d79c42017-07-21 12:31:50 +0200126 if options.print_memoryuse:
127 proguard_memoryuse = utils.grep_memoryuse(track_memory_file)
128
129 # run dex on the result
Søren Gjessea99636c2019-11-28 14:00:26 +0100130 jar = DX_JAR
Tamas Keneze4d79c42017-07-21 12:31:50 +0200131
132 with utils.TempDir() as temp:
133 track_memory_file = None
134 cmd = []
135 if options.print_memoryuse:
136 track_memory_file = join(temp, utils.MEMORY_USE_TMP_FILE)
137 cmd.extend(['tools/track_memory.sh', track_memory_file])
Ian Zerny3f54e222019-02-12 10:51:17 +0100138 cmd.extend([jdk.GetJavaExecutable(), '-jar', jar, '--multi-dex',
Tamas Keneze4d79c42017-07-21 12:31:50 +0200139 '--output=' + outdir])
140 if 'min-api' in values_proguarded:
141 cmd.append('--min-sdk-version=' + values_proguarded['min-api'])
142 cmd.extend(['--dex', proguarded_jar_path])
143 utils.PrintCmd(cmd);
144 check_call(cmd)
145 if options.print_memoryuse:
146 dx_memoryuse = utils.grep_memoryuse(track_memory_file)
147 print('{}(MemoryUse): {}'
148 .format(options.print_memoryuse,
149 max(proguard_memoryuse, dx_memoryuse)))
150
151 if options.print_runtimeraw:
152 print('{}(RunTimeRaw): {} ms'
153 .format(options.print_runtimeraw, 1000.0 * (time.time() - t0)))
154
155 if options.print_dexsegments:
156 dex_files = glob(os.path.join(outdir, '*.dex'))
157 utils.print_dexsegments(options.print_dexsegments, dex_files)
158
159if __name__ == '__main__':
160 sys.exit(Main(sys.argv[1:]))