Add @Keep and @KeepForSubclassing annotations for public R8 API
Add simple src/main/keep.txt file specifying that public members of
types marked with @Keep and public/protected members of types marked
with @KeepForSubclassing should be kept.
Add tools/build_r8lib.py to build a minified r8lib.jar from r8.jar and
test that d8_api_usage_sample.jar works with the minified r8lib.jar.
Also move RT_JAR from minify_tool.py to utils.py since it is used in
build_r8lib.py as well.
Change-Id: Ie091895705bfd4637513876a93f35911e958c479
diff --git a/tools/build_r8lib.py b/tools/build_r8lib.py
new file mode 100755
index 0000000..e08c141
--- /dev/null
+++ b/tools/build_r8lib.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+# Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+'''
+Build r8lib.jar using src/main/keep.txt and test that d8_api_usage_sample.jar
+works with the minified R8.
+'''
+
+import argparse
+import os
+import subprocess
+import toolhelper
+import utils
+
+parser = argparse.ArgumentParser(description=__doc__.strip(),
+ formatter_class=argparse.RawTextHelpFormatter)
+
+SAMPLE_JAR = os.path.join(utils.REPO_ROOT, 'tests/d8_api_usage_sample.jar')
+KEEP_RULES = os.path.join(utils.REPO_ROOT, 'src/main/keep.txt')
+R8LIB_JAR = os.path.join(utils.LIBS, 'r8lib.jar')
+R8LIB_MAP_FILE = os.path.join(utils.LIBS, 'r8lib-map.txt')
+
+API_LEVEL = 26
+ANDROID_JAR = 'third_party/android_jar/lib-v%s/android.jar' % API_LEVEL
+
+
+def build_r8lib():
+ toolhelper.run(
+ 'r8',
+ ('--release',
+ '--classfile',
+ '--lib', utils.RT_JAR,
+ utils.R8_JAR,
+ '--output', R8LIB_JAR,
+ '--pg-conf', KEEP_RULES,
+ '--pg-map-output', R8LIB_MAP_FILE))
+
+
+def test_d8sample():
+ with utils.TempDir() as path:
+ args = ['java', '-cp', '%s:%s' % (R8LIB_JAR, SAMPLE_JAR),
+ 'com.android.tools.apiusagesample.D8ApiUsageSample',
+ '--output', path,
+ '--min-api', str(API_LEVEL),
+ '--lib', ANDROID_JAR,
+ '--classpath', utils.R8_JAR,
+ '--main-dex-list', '/dev/null',
+ os.path.join(utils.BUILD, 'test/examples/hello.jar')]
+ utils.PrintCmd(args)
+ subprocess.check_call(args)
+
+
+def main():
+ # Handle --help
+ parser.parse_args()
+
+ build_r8lib()
+ test_d8sample()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/tools/minify_tool.py b/tools/minify_tool.py
index 787c1e1..8f440dd 100755
--- a/tools/minify_tool.py
+++ b/tools/minify_tool.py
@@ -27,7 +27,6 @@
MANIFEST_PATH = 'META-INF/MANIFEST.MF'
MANIFEST = 'Manifest-Version: 1.0\nMain-Class: %s\n\n'
MANIFEST_PATTERN = r'Main-Class:\s*(\S+)'
-RT = os.path.join(utils.REPO_ROOT, 'third_party/openjdk/openjdk-rt-1.8/rt.jar')
parser = argparse.ArgumentParser(description=__doc__.strip(),
formatter_class=argparse.RawTextHelpFormatter)
@@ -38,7 +37,7 @@
'-o', '--output-jar',
help='Path to output JAR (default: build/libs/<MainClass>-min.jar)')
parser.add_argument(
- '-l', '--lib', default=RT,
+ '-l', '--lib', default=utils.RT_JAR,
help='Path to rt.jar to use instead of OpenJDK 1.8')
parser.add_argument(
'-m', '--mainclass',
@@ -85,8 +84,8 @@
'No --mainclass specified and no Main-Class in input JAR manifest.')
return mo.group(1)
-def minify_tool(mainclass=None, input_jar=utils.R8_JAR, output_jar=None, lib=RT,
- debug=True, build=True, benchmark_name=None):
+def minify_tool(mainclass=None, input_jar=utils.R8_JAR, output_jar=None,
+ lib=utils.RT_JAR, debug=True, build=True, benchmark_name=None):
if output_jar is None:
output_jar = generate_output_name(input_jar, mainclass)
with utils.TempDir() as path:
diff --git a/tools/utils.py b/tools/utils.py
index 9f6959f..3aab572 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -35,6 +35,7 @@
COMPATPROGUARD_JAR = os.path.join(LIBS, 'compatproguard.jar')
MAVEN_ZIP = os.path.join(LIBS, 'r8.zip')
GENERATED_LICENSE = os.path.join(GENERATED_LICENSE_DIR, 'LICENSE')
+RT_JAR = os.path.join(REPO_ROOT, 'third_party/openjdk/openjdk-rt-1.8/rt.jar')
def PrintCmd(s):
if type(s) is list: