blob: 0079554b972cbedd9d4f31956f4be1b7f9e58edc [file] [log] [blame]
Søren Gjesse6d9e1552017-09-13 12:41:45 +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
6from os.path import join
7from glob import glob
8from itertools import chain
Søren Gjesse370526a2017-09-14 10:39:04 +02009from stat import S_IRWXU
Søren Gjesse6d9e1552017-09-13 12:41:45 +020010import argparse
11import multiprocessing
12import os
Søren Gjesse370526a2017-09-14 10:39:04 +020013import re
Søren Gjesse6d9e1552017-09-13 12:41:45 +020014import sys
15
16import gradle
17import utils
Søren Gjesse3330db22017-09-13 13:53:11 +020018import utils_aosp
Søren Gjesse6d9e1552017-09-13 12:41:45 +020019
20J_DEFAULT = multiprocessing.cpu_count() - 2
21
22EXIT_FAILURE = 1
23
24def parse_arguments():
25 parser = argparse.ArgumentParser(
26 description = 'Checkout the AOSP source tree.')
Søren Gjesse3330db22017-09-13 13:53:11 +020027 utils_aosp.add_common_arguments(parser)
Søren Gjesse6d9e1552017-09-13 12:41:45 +020028 parser.add_argument('--tool',
Søren Gjesse370526a2017-09-14 10:39:04 +020029 choices = ['jack', 'd8', 'r8', 'default'],
Søren Gjesse3330db22017-09-13 13:53:11 +020030 default = 'd8',
31 help='Compiler tool to use. Defaults to d8.')
Søren Gjesseedd097d2017-09-18 17:10:15 +020032 parser.add_argument('--mmm',
33 action = 'store_true',
34 help='Use mmm instead of make')
35 parser.add_argument('--mmma',
36 action = 'store_true',
37 help='Use mmma instead of make')
38 parser.add_argument('--rebuild-system-image-after-mmm',
39 action = 'store_true',
40 help='Build the system image after building a package with mmm or mmma')
Søren Gjesse6d9e1552017-09-13 12:41:45 +020041 parser.add_argument('--clean-dex',
42 action = 'store_true',
43 help = 'Remove all dex files before the build. By default they'
44 " are removed only if '--tool=d8' and if they are older than the D8 tool")
45 parser.add_argument('-j',
Søren Gjesse3330db22017-09-13 13:53:11 +020046 help='Projects to fetch simultaneously. ' +
47 'Defaults to ' + str(J_DEFAULT) + '.',
48 type=int,
49 default=J_DEFAULT)
Søren Gjessec7275422017-09-14 18:28:44 +020050 parser.add_argument('target', nargs='?')
Søren Gjesse6d9e1552017-09-13 12:41:45 +020051 return parser.parse_args()
52
53def setup_and_clean_dex(aosp_root, tool, clean_dex):
Søren Gjesse3330db22017-09-13 13:53:11 +020054 print "Running AOSP build in " + aosp_root
55
Søren Gjesse6d9e1552017-09-13 12:41:45 +020056 out = join(aosp_root, 'out')
57 utils.makedirs_if_needed(out)
58
59 # remove dex files older than the current d8 tool
60 counter = 0
61 if tool == 'd8' or clean_dex:
62 if not clean_dex:
63 d8jar_mtime = os.path.getmtime(utils.D8_JAR)
64 dex_files = (chain.from_iterable(glob(join(x[0], '*.dex'))
65 for x in os.walk(out)))
66 for f in dex_files:
67 if clean_dex or os.path.getmtime(f) <= d8jar_mtime:
68 os.remove(f)
69 counter += 1
70 if counter > 0:
71 print('Removed {} dex files.'.format(counter))
72
Søren Gjesse370526a2017-09-14 10:39:04 +020073PROGUARD_SCRIPT = """#!/bin/sh
74#
75# Start-up script for ProGuard -- free class file shrinker, optimizer,
76# obfuscator, and preverifier for Java bytecode.
77#
78# Note: when passing file names containing spaces to this script,
79# you\'ll have to add escaped quotes around them, e.g.
80# "\"/My Directory/My File.txt\""
81
82# Account for possibly missing/basic readlink.
83# POSIX conformant (dash/ksh/zsh/bash).
84PROGUARD=`readlink -f "$0" 2>/dev/null`
85if test "$PROGUARD" = \'\'
86then
87 PROGUARD=`readlink "$0" 2>/dev/null`
88 if test "$PROGUARD" = \'\'
89 then
90 PROGUARD="$0"
91 fi
92fi
93
94PROGUARD_HOME=`dirname "$PROGUARD"`/..
95
96# BEGIN android-changed Added -Xmx2G for Mac builds
97java -Xmx2G -jar "$PROGUARD_HOME/lib/proguard.jar" "$@"
98# END android-changed
99"""
100
101def prepare_for_proguard(aosp_root):
102 # Write the default proguard.sh script.
103 proguard_script = join(aosp_root, 'external', 'proguard', 'bin', 'proguard.sh')
104 with open(proguard_script, 'w') as f:
105 f.write(PROGUARD_SCRIPT)
106
107 os.chmod(proguard_script, S_IRWXU)
108
109def prepare_for_r8(aosp_root):
110 # Write the proguard.sh script invoking R8.
111 compat_proguard_jar = join(
112 utils.REPO_ROOT, 'build', 'libs', 'compatproguard.jar')
113 proguard_script = join(aosp_root, 'external', 'proguard', 'bin', 'proguard.sh')
114 with open(proguard_script, 'w') as f:
Søren Gjesse887b8742017-09-14 15:43:25 +0200115 f.write('java -jar ' + compat_proguard_jar + ' "$@" --min-api 10000')
Søren Gjesse370526a2017-09-14 10:39:04 +0200116 os.chmod(proguard_script, S_IRWXU)
117
Søren Gjesseedd097d2017-09-18 17:10:15 +0200118def build_aosp(aosp_root, lunch, make, tool, concurrency, target):
Søren Gjesse6d9e1552017-09-13 12:41:45 +0200119 jack_option = 'ANDROID_COMPILE_WITH_JACK=' \
120 + ('true' if tool == 'jack' else 'false')
121
122 # DX_ALT_JAR need to be cleared if not set, for 'make' to work properly
123 alt_jar_option = 'DX_ALT_JAR='
124 if tool == 'd8':
125 alt_jar_option += utils.COMPATDX_JAR
126
Søren Gjesse370526a2017-09-14 10:39:04 +0200127 if tool == 'r8':
128 prepare_for_r8(aosp_root)
129 # Use D8 compatdx dexer with hack for forwarding the R8 dex file.
130 alt_jar_option += utils.COMPATDX_JAR
131 else:
132 prepare_for_proguard(aosp_root)
133
Søren Gjesse6d9e1552017-09-13 12:41:45 +0200134 j_option = '-j' + str(concurrency);
Søren Gjesseedd097d2017-09-18 17:10:15 +0200135 print("-- Building Android image with '{} {} {} {}'." \
136 .format(make, j_option, jack_option, alt_jar_option))
Søren Gjesse370526a2017-09-14 10:39:04 +0200137
Søren Gjesseedd097d2017-09-18 17:10:15 +0200138 command = [make, j_option, jack_option, alt_jar_option]
Søren Gjessec7275422017-09-14 18:28:44 +0200139 if target:
140 command.append(target)
141
142 utils_aosp.run_through_aosp_helper(lunch, command, aosp_root)
Søren Gjesse6d9e1552017-09-13 12:41:45 +0200143
144def Main():
145 args = parse_arguments()
146
147 # Build the required tools.
Søren Gjesse370526a2017-09-14 10:39:04 +0200148 if args.tool == 'd8' or args.tool == 'r8':
Søren Gjesse3330db22017-09-13 13:53:11 +0200149 gradle.RunGradle(['d8', 'r8', 'compatdx', 'compatproguard'])
Søren Gjesse6d9e1552017-09-13 12:41:45 +0200150
151 setup_and_clean_dex(args.aosp_root, args.tool, args.clean_dex)
152
Søren Gjesseedd097d2017-09-18 17:10:15 +0200153 make = 'make'
154 if args.mmm:
155 make = 'mmm'
156 if args.mmma:
157 make = 'mmma'
158 build_aosp(args.aosp_root, args.lunch, make, args.tool, args.j, args.target)
159 # Call make to re-build the system image if requested.
160 if args.rebuild_system_image_after_mmm and (args.mmm or args.mmma):
161 build_aosp(args.aosp_root, args.lunch, 'make', 'd8', args.j, None)
Søren Gjesse6d9e1552017-09-13 12:41:45 +0200162
163if __name__ == '__main__':
164 sys.exit(Main())