| #!/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 gradle | 
 | import jdk | 
 | import os | 
 | import subprocess | 
 | import toolhelper | 
 | import utils | 
 |  | 
 | parser = argparse.ArgumentParser(description=__doc__.strip(), | 
 |                                  formatter_class=argparse.RawTextHelpFormatter) | 
 | parser.add_argument('-e', '--exclude_deps', action='store_true', | 
 |                     help='Create lib jar without dependencies') | 
 | parser.add_argument('-k', '--keep', default=utils.R8LIB_KEEP_RULES, | 
 |                     help='Keep rules file for lib') | 
 | parser.add_argument('-n', '--no_relocate', action='store_true', | 
 |                     help='Create lib jar without relocating libraries') | 
 | parser.add_argument('-o', '--out', default=None, | 
 |                     help='Output for built library') | 
 | parser.add_argument('-t', '--target', default='r8', | 
 |                     help='Compile target for library') | 
 |  | 
 | API_LEVEL = 26 | 
 | DEPS_JAR = os.path.join(utils.LIBS, 'deps.jar') | 
 | SAMPLE_JAR = os.path.join(utils.REPO_ROOT, 'tests', 'd8_api_usage_sample.jar') | 
 |  | 
 | def build_r8lib(target, exclude_deps, no_relocate, keep_rules_path, | 
 |     output_path, **kwargs): | 
 |   # Clean the build directory to ensure no repackaging of any existing | 
 |   # lib or deps. | 
 |   gradle.RunGradle(['clean']) | 
 |   lib_args = [target] | 
 |   deps_args = ['repackageDeps'] | 
 |   if exclude_deps: | 
 |     lib_args.append('-Pexclude_deps') | 
 |   if no_relocate: | 
 |     lib_args.append('-Plib_no_relocate') | 
 |     deps_args.append('-Plib_no_relocate') | 
 |   # Produce the r8lib target to be processed later. | 
 |   gradle.RunGradle(lib_args) | 
 |   target_lib = os.path.join(utils.LIBS, target + '.jar') | 
 |   temp_lib = os.path.join(utils.LIBS, target + '_to_process.jar') | 
 |   os.rename(target_lib, temp_lib) | 
 |   # Produce the dependencies needed for running r8 on lib.jar. | 
 |   gradle.RunGradle(deps_args) | 
 |   temp_deps = os.path.join(utils.LIBS, target + 'lib_deps.jar') | 
 |   os.rename(DEPS_JAR, temp_deps) | 
 |   # Produce R8 for compiling lib | 
 |   if output_path is None: | 
 |     output_path = target + 'lib.jar' | 
 |   output_map_path = output_path + '.map' | 
 |   toolhelper.run( | 
 |       'r8', | 
 |       ('--release', | 
 |        '--classfile', | 
 |        '--lib', utils.RT_JAR, | 
 |        '--lib', temp_deps, | 
 |        temp_lib, | 
 |        '--output', output_path, | 
 |        '--pg-conf', keep_rules_path, | 
 |        '--pg-map-output', output_map_path), | 
 |       **kwargs) | 
 |   if exclude_deps: | 
 |     return [output_path, temp_deps] | 
 |   else: | 
 |     return [output_path] | 
 |  | 
 |  | 
 | def test_d8sample(paths): | 
 |   with utils.TempDir() as path: | 
 |     args = [jdk.GetJavaExecutable(), | 
 |             '-cp', '%s:%s' % (SAMPLE_JAR, ":".join(paths)), | 
 |             'com.android.tools.apiusagesample.D8ApiUsageSample', | 
 |             '--output', path, | 
 |             '--min-api', str(API_LEVEL), | 
 |             '--lib', utils.get_android_jar(API_LEVEL), | 
 |             '--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 test_r8command(paths): | 
 |   with utils.TempDir() as path: | 
 |     # SAMPLE_JAR and LIB_JAR should not have any classes in common, since e.g. | 
 |     # R8CommandParser should have been minified in LIB_JAR. | 
 |     # Just in case R8CommandParser is also present in LIB_JAR, we put | 
 |     # SAMPLE_JAR first on the classpath to use its version of R8CommandParser. | 
 |     args = [jdk.GetJavaExecutable(), | 
 |             '-cp', '%s:%s' % (SAMPLE_JAR, ":".join(paths)), | 
 |             'com.android.tools.r8.R8CommandParser', | 
 |             '--output', path + "/output.zip", | 
 |             '--min-api', str(API_LEVEL), | 
 |             '--lib', utils.get_android_jar(API_LEVEL), | 
 |             '--main-dex-list', '/dev/null', | 
 |             os.path.join(utils.BUILD, 'test/examples/hello.jar')] | 
 |     utils.PrintCmd(args) | 
 |     subprocess.check_call(args) | 
 |  | 
 |  | 
 | def test_r8cfcommand(paths): | 
 |   with utils.TempDir() as path: | 
 |     # SAMPLE_JAR and LIB_JAR should not have any classes in common, since e.g. | 
 |     # R8CommandParser should have been minified in LIB_JAR. | 
 |     # Just in case R8CommandParser is also present in LIB_JAR, we put | 
 |     # SAMPLE_JAR first on the classpath to use its version of R8CommandParser. | 
 |     args = [jdk.GetJavaExecutable(), | 
 |             '-cp', '%s:%s' % (SAMPLE_JAR, ":".join(paths)), | 
 |             'com.android.tools.r8.R8CommandParser', | 
 |             '--classfile', | 
 |             '--output', path + "/output.jar", | 
 |             '--lib', utils.RT_JAR, | 
 |             os.path.join(utils.BUILD, 'test/examples/hello.jar')] | 
 |     utils.PrintCmd(args) | 
 |     subprocess.check_call(args) | 
 |  | 
 |  | 
 | def main(): | 
 |   # Handle --help | 
 |   args = parser.parse_args() | 
 |   output_paths = build_r8lib( | 
 |       args.target, args.exclude_deps, args.no_relocate, args.keep, args.out) | 
 |   if args.target == 'r8': | 
 |     gradle.RunGradle(['buildExampleJars']) | 
 |     test_r8command(output_paths) | 
 |     test_r8cfcommand(output_paths) | 
 |   if args.target == 'd8': | 
 |     gradle.RunGradle(['buildExampleJars']) | 
 |     test_d8sample(output_paths) | 
 |  | 
 |  | 
 | if __name__ == '__main__': | 
 |   main() |