blob: 54cf915ac6c5615d45cde366bfd39eaa2eefbce1 [file] [log] [blame]
#!/usr/bin/env python3
# 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'
r8_output_map_path = output_path + '_map.zip'
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,
'--partition-map-output', r8_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()