Søren Gjesse | 6d9e155 | 2017-09-13 12:41:45 +0200 | [diff] [blame] | 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 | from os.path import join |
| 7 | from glob import glob |
| 8 | from itertools import chain |
Søren Gjesse | 370526a | 2017-09-14 10:39:04 +0200 | [diff] [blame] | 9 | from stat import S_IRWXU |
Søren Gjesse | 6d9e155 | 2017-09-13 12:41:45 +0200 | [diff] [blame] | 10 | import argparse |
| 11 | import multiprocessing |
| 12 | import os |
Søren Gjesse | 370526a | 2017-09-14 10:39:04 +0200 | [diff] [blame] | 13 | import re |
Søren Gjesse | 6d9e155 | 2017-09-13 12:41:45 +0200 | [diff] [blame] | 14 | import sys |
| 15 | |
| 16 | import gradle |
| 17 | import utils |
Søren Gjesse | 3330db2 | 2017-09-13 13:53:11 +0200 | [diff] [blame] | 18 | import utils_aosp |
Søren Gjesse | 6d9e155 | 2017-09-13 12:41:45 +0200 | [diff] [blame] | 19 | |
| 20 | J_DEFAULT = multiprocessing.cpu_count() - 2 |
| 21 | |
| 22 | EXIT_FAILURE = 1 |
| 23 | |
| 24 | def parse_arguments(): |
| 25 | parser = argparse.ArgumentParser( |
| 26 | description = 'Checkout the AOSP source tree.') |
Søren Gjesse | 3330db2 | 2017-09-13 13:53:11 +0200 | [diff] [blame] | 27 | utils_aosp.add_common_arguments(parser) |
Søren Gjesse | 6d9e155 | 2017-09-13 12:41:45 +0200 | [diff] [blame] | 28 | parser.add_argument('--tool', |
Søren Gjesse | 370526a | 2017-09-14 10:39:04 +0200 | [diff] [blame] | 29 | choices = ['jack', 'd8', 'r8', 'default'], |
Søren Gjesse | 3330db2 | 2017-09-13 13:53:11 +0200 | [diff] [blame] | 30 | default = 'd8', |
| 31 | help='Compiler tool to use. Defaults to d8.') |
Søren Gjesse | edd097d | 2017-09-18 17:10:15 +0200 | [diff] [blame] | 32 | 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 Gjesse | 6d9e155 | 2017-09-13 12:41:45 +0200 | [diff] [blame] | 41 | 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 Gjesse | 3330db2 | 2017-09-13 13:53:11 +0200 | [diff] [blame] | 46 | help='Projects to fetch simultaneously. ' + |
| 47 | 'Defaults to ' + str(J_DEFAULT) + '.', |
| 48 | type=int, |
| 49 | default=J_DEFAULT) |
Søren Gjesse | c727542 | 2017-09-14 18:28:44 +0200 | [diff] [blame] | 50 | parser.add_argument('target', nargs='?') |
Søren Gjesse | 6d9e155 | 2017-09-13 12:41:45 +0200 | [diff] [blame] | 51 | return parser.parse_args() |
| 52 | |
| 53 | def setup_and_clean_dex(aosp_root, tool, clean_dex): |
Søren Gjesse | 3330db2 | 2017-09-13 13:53:11 +0200 | [diff] [blame] | 54 | print "Running AOSP build in " + aosp_root |
| 55 | |
Søren Gjesse | 6d9e155 | 2017-09-13 12:41:45 +0200 | [diff] [blame] | 56 | 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 Gjesse | 370526a | 2017-09-14 10:39:04 +0200 | [diff] [blame] | 73 | PROGUARD_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). |
| 84 | PROGUARD=`readlink -f "$0" 2>/dev/null` |
| 85 | if test "$PROGUARD" = \'\' |
| 86 | then |
| 87 | PROGUARD=`readlink "$0" 2>/dev/null` |
| 88 | if test "$PROGUARD" = \'\' |
| 89 | then |
| 90 | PROGUARD="$0" |
| 91 | fi |
| 92 | fi |
| 93 | |
| 94 | PROGUARD_HOME=`dirname "$PROGUARD"`/.. |
| 95 | |
| 96 | # BEGIN android-changed Added -Xmx2G for Mac builds |
| 97 | java -Xmx2G -jar "$PROGUARD_HOME/lib/proguard.jar" "$@" |
| 98 | # END android-changed |
| 99 | """ |
| 100 | |
| 101 | def 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 | |
| 109 | def 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 Gjesse | 887b874 | 2017-09-14 15:43:25 +0200 | [diff] [blame] | 115 | f.write('java -jar ' + compat_proguard_jar + ' "$@" --min-api 10000') |
Søren Gjesse | 370526a | 2017-09-14 10:39:04 +0200 | [diff] [blame] | 116 | os.chmod(proguard_script, S_IRWXU) |
| 117 | |
Søren Gjesse | edd097d | 2017-09-18 17:10:15 +0200 | [diff] [blame] | 118 | def build_aosp(aosp_root, lunch, make, tool, concurrency, target): |
Søren Gjesse | 6d9e155 | 2017-09-13 12:41:45 +0200 | [diff] [blame] | 119 | 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 Gjesse | 370526a | 2017-09-14 10:39:04 +0200 | [diff] [blame] | 127 | 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 Gjesse | 6d9e155 | 2017-09-13 12:41:45 +0200 | [diff] [blame] | 134 | j_option = '-j' + str(concurrency); |
Søren Gjesse | edd097d | 2017-09-18 17:10:15 +0200 | [diff] [blame] | 135 | print("-- Building Android image with '{} {} {} {}'." \ |
| 136 | .format(make, j_option, jack_option, alt_jar_option)) |
Søren Gjesse | 370526a | 2017-09-14 10:39:04 +0200 | [diff] [blame] | 137 | |
Søren Gjesse | edd097d | 2017-09-18 17:10:15 +0200 | [diff] [blame] | 138 | command = [make, j_option, jack_option, alt_jar_option] |
Søren Gjesse | c727542 | 2017-09-14 18:28:44 +0200 | [diff] [blame] | 139 | if target: |
| 140 | command.append(target) |
| 141 | |
| 142 | utils_aosp.run_through_aosp_helper(lunch, command, aosp_root) |
Søren Gjesse | 6d9e155 | 2017-09-13 12:41:45 +0200 | [diff] [blame] | 143 | |
| 144 | def Main(): |
| 145 | args = parse_arguments() |
| 146 | |
| 147 | # Build the required tools. |
Søren Gjesse | 370526a | 2017-09-14 10:39:04 +0200 | [diff] [blame] | 148 | if args.tool == 'd8' or args.tool == 'r8': |
Søren Gjesse | 3330db2 | 2017-09-13 13:53:11 +0200 | [diff] [blame] | 149 | gradle.RunGradle(['d8', 'r8', 'compatdx', 'compatproguard']) |
Søren Gjesse | 6d9e155 | 2017-09-13 12:41:45 +0200 | [diff] [blame] | 150 | |
| 151 | setup_and_clean_dex(args.aosp_root, args.tool, args.clean_dex) |
| 152 | |
Søren Gjesse | edd097d | 2017-09-18 17:10:15 +0200 | [diff] [blame] | 153 | 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 Gjesse | 6d9e155 | 2017-09-13 12:41:45 +0200 | [diff] [blame] | 162 | |
| 163 | if __name__ == '__main__': |
| 164 | sys.exit(Main()) |