blob: e78d5d18257d6df3783ff636e0b4c4ae2664989f [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
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, splitext
12from subprocess import check_call
13import argparse
14import fnmatch
15import gmscore_data
16import os
17import stat
18import sys
19import time
20
21import gmail_data
22import gmscore_data
Rico Wind1f4172c2018-09-06 16:29:03 +020023import golem
Tamas Keneze4d79c42017-07-21 12:31:50 +020024import proguard
25import utils
26import youtube_data
27
28APPS = ['gmscore', 'youtube']
29DX_JAR = join(utils.REPO_ROOT, 'tools', 'linux', 'dx', 'framework', 'dx.jar')
Tamas Keneze4d79c42017-07-21 12:31:50 +020030
31def parse_arguments(argv):
32 parser = argparse.ArgumentParser(
33 description = 'Run ProGuard and the DX tool on GmsCore V10.')
34 parser.add_argument('--app', required = True, choices = APPS)
35 parser.add_argument('--out',
36 help = 'Output directory for the DX tool.',
37 default = os.getcwd())
38 parser.add_argument('--compatdx',
39 help = 'Use CompatDx (D8) instead of DX.',
40 default = False,
41 action = 'store_true')
Rico Wind1f4172c2018-09-06 16:29:03 +020042 parser.add_argument('--golem',
43 help = 'Link in third party dependencies.',
44 default = False,
45 action = 'store_true')
Tamas Keneze4d79c42017-07-21 12:31:50 +020046 parser.add_argument('--print-runtimeraw',
47 metavar = 'BENCHMARKNAME',
48 help = 'Print the line \'<BENCHMARKNAME>(RunTimeRaw): <elapsed>' +
49 ' ms\' at the end where <elapsed> is the elapsed time in' +
50 ' milliseconds.')
51 parser.add_argument('--print-memoryuse',
52 metavar='BENCHMARKNAME',
53 help='Print the line \'<BENCHMARKNAME>(MemoryUse):' +
54 ' <mem>\' at the end where <mem> is the peak' +
55 ' peak resident set size (VmHWM) in bytes.')
56 parser.add_argument('--print-dexsegments',
57 metavar = 'BENCHMARKNAME',
58 help = 'Print the sizes of individual dex segments as ' +
59 '\'<BENCHMARKNAME>-<segment>(CodeSize): <bytes>\'')
60 return parser.parse_args(argv)
61
62def Main(argv):
Tamas Kenez2cf47cf2017-07-25 10:22:52 +020063 utils.check_java_version()
Tamas Keneze4d79c42017-07-21 12:31:50 +020064 options = parse_arguments(argv)
Rico Wind1f4172c2018-09-06 16:29:03 +020065 if options.golem:
66 golem.link_third_party()
Tamas Keneze4d79c42017-07-21 12:31:50 +020067 outdir = options.out
68
69 if options.app == 'gmscore':
70 version = 'v10'
71 data = gmscore_data
72 base = data.V10_BASE
73 elif options.app == 'youtube':
74 version = '12.22'
75 data = youtube_data
76 base = data.V12_22_BASE
77 else:
78 raise Exception('Unexpected')
79
80
81 args = ['-forceprocessing']
82
83 if not outdir.endswith('.zip') and not outdir.endswith('.jar') \
84 and not exists(outdir):
85 makedirs(outdir)
86
87
88 values_deploy = data.VERSIONS[version]['deploy']
89 values_proguarded = data.VERSIONS[version]['proguarded']
90 assert 'pgconf' in values_deploy
91
92 for pgconf in values_deploy['pgconf']:
93 args.extend(['@' + pgconf])
94
95 # find seeds file
96 inputs = data.VERSIONS[version]['proguarded']['inputs']
97 assert len(inputs) == 1
98 basename_wo_ext = splitext(os.path.basename(inputs[0]))[0]
99 seeds_filename = basename_wo_ext + '.seeds'
100
101 seeds_files = []
102 for root, dirnames, filenames in os.walk(join(base, 'blaze-out')):
103 for filename in fnmatch.filter(filenames, seeds_filename):
104 seeds_files.append(os.path.join(root, filename))
105 assert len(seeds_files) == 1
106
107 seeds_path = seeds_files[0]
108 proguarded_jar_path = splitext(seeds_path)[0] + '.jar'
109
110 # Remove write-protection from seeds file. The seeds file is an output of
111 # ProGuard so it aborts if this is not writeable.
112 st = os.stat(seeds_path)
113 os.chmod(seeds_path,
114 st.st_mode | stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH)
115
116 t0 = time.time()
117
118 proguard_memoryuse = None
119
120 with utils.TempDir() as temp:
121 track_memory_file = None
122 if options.print_memoryuse:
123 track_memory_file = join(temp, utils.MEMORY_USE_TMP_FILE)
Ian Zerny517c7662018-07-11 15:22:29 +0200124 proguard.run(
125 args,
126 track_memory_file = track_memory_file,
127 stdout=open(os.devnull, 'w'))
Tamas Keneze4d79c42017-07-21 12:31:50 +0200128 if options.print_memoryuse:
129 proguard_memoryuse = utils.grep_memoryuse(track_memory_file)
130
131 # run dex on the result
132 if options.compatdx:
Tamas Kenez0cad51c2017-08-21 14:42:01 +0200133 jar = utils.COMPATDX_JAR
Tamas Keneze4d79c42017-07-21 12:31:50 +0200134 else:
135 jar = DX_JAR
136
137 with utils.TempDir() as temp:
138 track_memory_file = None
139 cmd = []
140 if options.print_memoryuse:
141 track_memory_file = join(temp, utils.MEMORY_USE_TMP_FILE)
142 cmd.extend(['tools/track_memory.sh', track_memory_file])
143 cmd.extend(['java', '-jar', jar, '--multi-dex',
144 '--output=' + outdir])
145 if 'min-api' in values_proguarded:
146 cmd.append('--min-sdk-version=' + values_proguarded['min-api'])
147 cmd.extend(['--dex', proguarded_jar_path])
148 utils.PrintCmd(cmd);
149 check_call(cmd)
150 if options.print_memoryuse:
151 dx_memoryuse = utils.grep_memoryuse(track_memory_file)
152 print('{}(MemoryUse): {}'
153 .format(options.print_memoryuse,
154 max(proguard_memoryuse, dx_memoryuse)))
155
156 if options.print_runtimeraw:
157 print('{}(RunTimeRaw): {} ms'
158 .format(options.print_runtimeraw, 1000.0 * (time.time() - t0)))
159
160 if options.print_dexsegments:
161 dex_files = glob(os.path.join(outdir, '*.dex'))
162 utils.print_dexsegments(options.print_dexsegments, dex_files)
163
164if __name__ == '__main__':
165 sys.exit(Main(sys.argv[1:]))