Ian Zerny | a0d27cf | 2021-10-14 13:55:34 +0200 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
| 2 | # Copyright (c) 2021, 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 | import argparse |
Ian Zerny | d31dd73 | 2021-10-15 11:49:26 +0200 | [diff] [blame] | 7 | import os |
Ian Zerny | a0d27cf | 2021-10-14 13:55:34 +0200 | [diff] [blame] | 8 | import subprocess |
Rico Wind | f4f713b | 2025-02-19 09:39:42 +0100 | [diff] [blame] | 9 | import shutil |
Ian Zerny | a0d27cf | 2021-10-14 13:55:34 +0200 | [diff] [blame] | 10 | import sys |
Rico Wind | f4f713b | 2025-02-19 09:39:42 +0100 | [diff] [blame] | 11 | import zipfile |
Ian Zerny | a0d27cf | 2021-10-14 13:55:34 +0200 | [diff] [blame] | 12 | |
| 13 | import jdk |
Ian Zerny | d31dd73 | 2021-10-15 11:49:26 +0200 | [diff] [blame] | 14 | import utils |
Ian Zerny | a0d27cf | 2021-10-14 13:55:34 +0200 | [diff] [blame] | 15 | |
Ian Zerny | d31dd73 | 2021-10-15 11:49:26 +0200 | [diff] [blame] | 16 | VERSION_EXTRACTOR = """ |
| 17 | import com.android.tools.r8.Version; |
| 18 | public class VersionExtractor { |
| 19 | public static void main(String[] args) { |
| 20 | System.out.println(Version.LABEL); |
| 21 | } |
| 22 | } |
| 23 | """ |
Ian Zerny | a0d27cf | 2021-10-14 13:55:34 +0200 | [diff] [blame] | 24 | |
Christoffer Quist Adamsen | 2434a4d | 2023-10-16 11:29:03 +0200 | [diff] [blame] | 25 | |
Ian Zerny | a0d27cf | 2021-10-14 13:55:34 +0200 | [diff] [blame] | 26 | def parse_options(): |
Christoffer Quist Adamsen | 2434a4d | 2023-10-16 11:29:03 +0200 | [diff] [blame] | 27 | parser = argparse.ArgumentParser(description='Tag R8 Versions') |
| 28 | parser.add_argument('--classpath', |
| 29 | action='append', |
| 30 | help='Dependencies to add to classpath') |
| 31 | parser.add_argument('--debug-agent', |
| 32 | action='store_true', |
| 33 | default=False, |
| 34 | help='Create a socket for debugging') |
Rico Wind | f4f713b | 2025-02-19 09:39:42 +0100 | [diff] [blame] | 35 | parser.add_argument('--replace-from-jar', |
| 36 | default=None, |
| 37 | help='Replace output jar with classes from this jar.') |
Christoffer Quist Adamsen | 2434a4d | 2023-10-16 11:29:03 +0200 | [diff] [blame] | 38 | parser.add_argument( |
| 39 | '--excldeps-variant', |
| 40 | action='store_true', |
| 41 | default=False, |
| 42 | help='Mark this artifact as an "excldeps" variant of the compiler') |
| 43 | parser.add_argument('--debug-variant', |
| 44 | action='store_true', |
| 45 | default=False, |
| 46 | help='Compile with debug flag') |
| 47 | parser.add_argument( |
| 48 | '--lib', |
| 49 | action='append', |
| 50 | help='Additional libraries (JDK 1.8 rt.jar already included)') |
| 51 | parser.add_argument('--output', |
| 52 | required=True, |
| 53 | help='The output path for the r8lib') |
| 54 | parser.add_argument('--pg-conf', action='append', help='Keep configuration') |
| 55 | parser.add_argument('--pg-map', |
| 56 | default=None, |
| 57 | help='Input map for distribution and composition') |
| 58 | parser.add_argument('--r8jar', required=True, help='The R8 jar to compile') |
| 59 | parser.add_argument('--r8compiler', |
| 60 | default='build/libs/r8_with_deps.jar', |
| 61 | help='The R8 compiler to use') |
| 62 | return parser.parse_args() |
| 63 | |
Ian Zerny | a0d27cf | 2021-10-14 13:55:34 +0200 | [diff] [blame] | 64 | |
Ian Zerny | 848da97 | 2021-10-14 19:40:16 +0200 | [diff] [blame] | 65 | def get_r8_version(r8jar): |
Christoffer Quist Adamsen | 2434a4d | 2023-10-16 11:29:03 +0200 | [diff] [blame] | 66 | with utils.TempDir() as temp: |
| 67 | name = os.path.join(temp, "VersionExtractor.java") |
| 68 | fd = open(name, 'w') |
| 69 | fd.write(VERSION_EXTRACTOR) |
| 70 | fd.close() |
| 71 | cmd = [jdk.GetJavacExecutable(), '-cp', r8jar, name] |
| 72 | print(' '.join(cmd)) |
| 73 | cp_separator = ';' if utils.IsWindows() else ':' |
| 74 | subprocess.check_call(cmd) |
| 75 | output = subprocess.check_output([ |
| 76 | jdk.GetJavaExecutable(), '-cp', |
| 77 | cp_separator.join([r8jar, os.path.dirname(name)]), |
| 78 | 'VersionExtractor' |
| 79 | ]).decode('UTF-8').strip() |
| 80 | if output == 'main': |
| 81 | return subprocess.check_output(['git', 'rev-parse', |
| 82 | 'HEAD']).decode('UTF-8').strip() |
| 83 | else: |
| 84 | return output |
| 85 | |
Rico Wind | f4f713b | 2025-02-19 09:39:42 +0100 | [diff] [blame] | 86 | def replace_in_jar(r8jar, replace_from): |
| 87 | with utils.TempDir() as temp: |
| 88 | result = os.path.join(temp, 'result.jar') |
| 89 | skip_from_r8jar = set() |
| 90 | with zipfile.ZipFile(result, 'w') as output_file: |
| 91 | with zipfile.ZipFile(replace_from, 'r') as input_file: |
| 92 | for zipinfo in input_file.infolist(): |
| 93 | if zipinfo.filename.endswith('.class'): |
| 94 | data = input_file.read(zipinfo) |
| 95 | zipinfo.date_time = (1980, 1, 1, 0, 0, 0) |
| 96 | output_file.writestr(zipinfo, data) |
| 97 | skip_from_r8jar.add(zipinfo.filename) |
| 98 | else: |
| 99 | assert (zipinfo.filename == 'META-INF/MANIFEST.MF' or |
| 100 | zipinfo.is_dir()) |
| 101 | with zipfile.ZipFile(r8jar, 'r') as input_file: |
| 102 | for zipinfo in input_file.infolist(): |
| 103 | if not zipinfo.filename in skip_from_r8jar: |
| 104 | output_file.writestr(zipinfo, input_file.read(zipinfo)) |
| 105 | shutil.copyfile(result, r8jar) |
Ian Zerny | 848da97 | 2021-10-14 19:40:16 +0200 | [diff] [blame] | 106 | |
Ian Zerny | a0d27cf | 2021-10-14 13:55:34 +0200 | [diff] [blame] | 107 | def main(): |
Christoffer Quist Adamsen | 2434a4d | 2023-10-16 11:29:03 +0200 | [diff] [blame] | 108 | args = parse_options() |
| 109 | if not os.path.exists(args.r8jar): |
| 110 | print("Could not find jar: " + args.r8jar) |
| 111 | return 1 |
| 112 | version = get_r8_version(args.r8jar) |
| 113 | variant = '+excldeps' if args.excldeps_variant else '' |
| 114 | map_id_template = version + variant |
| 115 | source_file_template = 'R8_%MAP_ID_%MAP_HASH' |
| 116 | # TODO(b/139725780): See if we can remove or lower the heap size (-Xmx8g). |
| 117 | cmd = [jdk.GetJavaExecutable(), '-Xmx8g', '-ea'] |
| 118 | if args.debug_agent: |
| 119 | cmd.extend([ |
| 120 | '-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005' |
| 121 | ]) |
Ian Zerny | 8a7a68f | 2023-11-06 11:24:57 +0100 | [diff] [blame] | 122 | cmd.append('-Dcom.android.tools.r8.enableKeepAnnotations=1') |
Christoffer Adamsen | 5901b19 | 2024-08-01 13:11:47 +0200 | [diff] [blame] | 123 | # TODO(b/356344563): Remove when this is default. |
| 124 | cmd.append('-Dcom.android.tools.r8.enableEmptyMemberRulesToDefaultInitRuleConversion=0') |
Søren Gjesse | 75d7b62 | 2024-11-04 14:32:23 +0100 | [diff] [blame] | 125 | cmd.append('-Dcom.android.tools.r8.tracereferences.obfuscateAllEnums') |
Christoffer Quist Adamsen | 2434a4d | 2023-10-16 11:29:03 +0200 | [diff] [blame] | 126 | cmd.extend(['-cp', args.r8compiler, 'com.android.tools.r8.R8']) |
| 127 | cmd.append(args.r8jar) |
| 128 | if args.debug_variant: |
| 129 | cmd.append('--debug') |
| 130 | cmd.append('--classfile') |
| 131 | cmd.extend(['--map-id-template', map_id_template]) |
| 132 | cmd.extend(['--source-file-template', source_file_template]) |
| 133 | cmd.extend(['--output', args.output]) |
Ian Zerny | 51cb415 | 2023-11-17 10:47:13 +0100 | [diff] [blame] | 134 | cmd.extend(['--pg-conf-output', args.output + '.config']) |
Christoffer Quist Adamsen | 2434a4d | 2023-10-16 11:29:03 +0200 | [diff] [blame] | 135 | cmd.extend(['--pg-map-output', args.output + '.map']) |
| 136 | cmd.extend(['--partition-map-output', args.output + '_map.zip']) |
Søren Gjesse | 19078da | 2025-03-31 11:51:23 +0200 | [diff] [blame] | 137 | cmd.extend(['--lib', jdk.GetDefaultJdkHome()]) |
Christoffer Quist Adamsen | 2434a4d | 2023-10-16 11:29:03 +0200 | [diff] [blame] | 138 | if args.pg_conf: |
| 139 | for pgconf in args.pg_conf: |
| 140 | cmd.extend(['--pg-conf', pgconf]) |
| 141 | if args.lib: |
| 142 | for lib in args.lib: |
| 143 | cmd.extend(['--lib', lib]) |
| 144 | if args.classpath: |
| 145 | for cp in args.classpath: |
| 146 | cmd.extend(['--classpath', cp]) |
| 147 | if args.pg_map: |
| 148 | cmd.extend(['--pg-map', args.pg_map]) |
| 149 | print(' '.join(cmd)) |
| 150 | subprocess.check_call(cmd) |
Rico Wind | f4f713b | 2025-02-19 09:39:42 +0100 | [diff] [blame] | 151 | if args.replace_from_jar: |
| 152 | replace_in_jar(args.output, args.replace_from_jar) |
Ian Zerny | a0d27cf | 2021-10-14 13:55:34 +0200 | [diff] [blame] | 153 | |
| 154 | if __name__ == '__main__': |
Christoffer Quist Adamsen | 2434a4d | 2023-10-16 11:29:03 +0200 | [diff] [blame] | 155 | sys.exit(main()) |