Adds experimental support for Java 8 via gn arg

Requires host machines to have jdk8 installed and uses retrolambda to
convert java 8 .jar files into java 7 .jar files.

Future work includes adding Retrolambda into third_party libraries.

BUG=642600

Review-Url: https://codereview.chromium.org/2543463002
Cr-Original-Commit-Position: refs/heads/master@{#435629}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: d8c7a8acef06acc9f093177d568789f8f3329c23
This commit is contained in:
zpeng 2016-12-01 08:56:51 -08:00 коммит произвёл Commit bot
Родитель b1952fc7d4
Коммит c98544d340
5 изменённых файлов: 187 добавлений и 59 удалений

Просмотреть файл

@ -4,6 +4,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import distutils.spawn
import optparse
import os
import shutil
@ -319,6 +320,13 @@ def _ParseOptions(argv):
for arg in options.bootclasspath:
bootclasspath += build_utils.ParseGnList(arg)
options.bootclasspath = bootclasspath
if options.java_version == '1.8' and options.bootclasspath:
# Android's boot jar doesn't contain all java 8 classes.
# See: https://github.com/evant/gradle-retrolambda/issues/23.
javac_path = os.path.realpath(distutils.spawn.find_executable('javac'))
jdk_dir = os.path.dirname(os.path.dirname(javac_path))
rt_jar = os.path.join(jdk_dir, 'jre', 'lib', 'rt.jar')
options.bootclasspath.append(rt_jar)
classpath = []
for arg in options.classpath:

68
android/gyp/retrolambda.py Executable file
Просмотреть файл

@ -0,0 +1,68 @@
#!/usr/bin/env python
#
# Copyright 2016 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import argparse
import os
import shutil
import sys
import tempfile
from util import build_utils
_SRC_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__),
'..', '..', '..'))
_RETROLAMBDA_JAR_PATH = os.path.normpath(os.path.join(
_SRC_ROOT, 'third_party', 'retrolambda', 'retrolambda-2.3.0.jar'))
def _OnStaleMd5(input_jar, output_jar, classpath, android_sdk_jar):
with build_utils.TempDir() as temp_dir:
build_utils.ExtractAll(input_jar, path=temp_dir)
cmd = [
'java',
'-Dretrolambda.inputDir=' + temp_dir,
'-Dretrolambda.classpath=' +
':'.join([temp_dir] + classpath + [android_sdk_jar]),
'-javaagent:' + _RETROLAMBDA_JAR_PATH,
'-jar',
_RETROLAMBDA_JAR_PATH,
]
build_utils.CheckOutput(cmd, print_stdout=False)
build_utils.ZipDir(output_jar + '.tmp', temp_dir)
shutil.move(output_jar + '.tmp', output_jar)
def main():
args = build_utils.ExpandFileArgs(sys.argv[1:])
parser = argparse.ArgumentParser()
build_utils.AddDepfileOption(parser)
parser.add_argument('--input-jar', required=True,
help='Jar input path to include .class files from.')
parser.add_argument('--output-jar', required=True,
help='Jar output path.')
parser.add_argument('--classpath', required=True,
help='Classpath.')
parser.add_argument('--android-sdk-jar', required=True,
help='Android sdk jar path.')
options = parser.parse_args(args)
options.classpath = build_utils.ParseGnList(options.classpath)
input_paths = options.classpath + [options.input_jar]
output_paths = [options.output_jar]
build_utils.CallAndWriteDepfileIfStale(
lambda: _OnStaleMd5(options.input_jar, options.output_jar,
options.classpath, options.android_sdk_jar),
options,
input_paths=input_paths,
input_strings=[],
output_paths=output_paths)
if __name__ == '__main__':
sys.exit(main())

Просмотреть файл

@ -132,7 +132,7 @@ if (is_android) {
# Required for Android M+ due to SELinux policies (stronger sandboxing).
disable_incremental_isolated_processes = false
# Speed up incremental compiles by compiling only changed files.
# Speeds up incremental compiles by compiling only changed files.
enable_incremental_javac = false
# Adds intrumentation to each function. Writes a file with the order that
@ -142,6 +142,10 @@ if (is_android) {
# Builds secondary abi for APKs, supports build 32-bit arch as secondary
# abi in 64-bit Monochrome and WebView.
build_apk_secondary_abi = true
# Enables java8 language features (via retrolambda).
# work-in-progress (http://crbug.com/642600)
use_java8 = false
}
# We need a second declare_args block to make sure we are using the overridden

Просмотреть файл

@ -418,7 +418,7 @@ template("copy_ex") {
}
}
# Generates a script in the output bin directory which runs the test
# Generates a script in the build bin directory which runs the test
# target using the test runner script in build/android/test_runner.py.
template("test_runner_script") {
testonly = true
@ -823,10 +823,10 @@ if (enable_java_templates) {
}
}
# Generates a script in the output bin.java directory to run a java binary.
# Generates a script in the build bin directory to run a java binary.
#
# Variables
# main_class: The class containing the progam entry point.
# main_class: The class containing the program entry point.
# jar_path: The path to the jar to run.
# script_name: Name of the script to generate.
# build_config: Path to .build_config for the jar (contains classpath).
@ -1004,9 +1004,6 @@ if (enable_java_templates) {
_input_jar_path = invoker.input_jar_path
_output_jar_path = invoker.output_jar_path
_proguard_preprocess =
defined(invoker.proguard_preprocess) && invoker.proguard_preprocess
_jar_excluded_patterns = []
if (defined(invoker.jar_excluded_patterns)) {
_jar_excluded_patterns = invoker.jar_excluded_patterns
@ -1015,56 +1012,65 @@ if (enable_java_templates) {
invoker.strip_resource_classes
_filter_jar = _jar_excluded_patterns != [] || _strip_resource_classes
_proguard_preprocess =
defined(invoker.proguard_preprocess) && invoker.proguard_preprocess
_enable_assert =
defined(invoker.supports_android) && invoker.supports_android &&
(is_java_debug || dcheck_always_on)
assert(_enable_assert || true) # Mark used.
_retrolambda = defined(invoker.supports_android) &&
invoker.supports_android && use_java8
_deps = []
_previous_output_jar = _input_jar_path
if (_filter_jar) {
_filter_target = "${target_name}__filter"
_filter_input_jar = _previous_output_jar
_filter_output_jar = "$target_out_dir/$target_name-filtered.jar"
_filter_jar_path = "$target_out_dir/$target_name-filtered.jar"
action(_filter_target) {
script = "//build/android/gyp/jar.py"
forward_variables_from(invoker,
[
"deps",
"public_deps",
])
deps = _deps
if (defined(invoker.deps)) {
deps += invoker.deps
}
if (defined(invoker.public_deps)) {
public_deps = invoker.public_deps
}
inputs = [
_build_config,
_input_jar_path,
_filter_input_jar,
]
outputs = [
_filter_jar_path,
_filter_output_jar,
]
args = [
"--input-jar",
rebase_path(_input_jar_path, root_build_dir),
rebase_path(_filter_input_jar, root_build_dir),
"--jar-path",
rebase_path(_filter_jar_path, root_build_dir),
rebase_path(_filter_output_jar, root_build_dir),
"--excluded-classes=$_jar_excluded_patterns",
]
if (_strip_resource_classes) {
args += [ "--strip-resource-classes-for=@FileArg($_rebased_build_config:javac:resource_packages)" ]
}
}
_deps = []
_deps = [ ":$_filter_target" ]
_previous_output_jar = _filter_output_jar
}
if (_proguard_preprocess) {
_output_jar_target = "${target_name}__proguard_process"
_proguard_output_jar = _output_jar_path
_proguard_target = "${target_name}__proguard_process"
_proguard_input_jar = _previous_output_jar
_proguard_output_jar = "$target_out_dir/$target_name-proguarded.jar"
_proguard_config_path = invoker.proguard_preprocess_config
proguard(_output_jar_target) {
if (_filter_jar) {
_proguard_input_jar = _filter_jar_path
deps = [
":$_filter_target",
]
} else {
_proguard_input_jar = _input_jar_path
deps = []
}
proguard(_proguard_target) {
deps = _deps
if (defined(invoker.deps)) {
deps += invoker.deps
}
@ -1088,20 +1094,23 @@ if (enable_java_templates) {
"--classpath=@FileArg($_rebased_build_config:javac:classpath)",
]
}
} else if (_enable_assert) {
_output_jar_target = "${target_name}__assert"
_assert_output_jar = _output_jar_path
action(_output_jar_target) {
script = "$root_out_dir/bin/helper/java_assertion_enabler"
_deps = []
_deps = [ ":$_proguard_target" ]
_previous_output_jar = _proguard_output_jar
}
if (_enable_assert) {
_assert_target = "${target_name}__assert"
_assert_input_jar = _previous_output_jar
_assert_output_jar = "$target_out_dir/$target_name-asserted.jar"
action(_assert_target) {
script = "$root_build_dir/bin/helper/java_assertion_enabler"
deps = [
"//build/android/java_assertion_enabler($default_toolchain)",
]
if (_filter_jar) {
_assert_input_jar = _filter_jar_path
deps += [ ":$_filter_target" ]
} else {
_assert_input_jar = _input_jar_path
}
deps += _deps
if (defined(invoker.deps)) {
deps += invoker.deps
}
@ -1119,31 +1128,65 @@ if (enable_java_templates) {
rebase_path(_assert_output_jar, root_build_dir),
]
}
} else {
_output_jar_target = "${target_name}__copy"
copy(_output_jar_target) {
if (_filter_jar) {
_copy_input_jar = _filter_jar_path
public_deps = [
":$_filter_target",
]
} else {
_copy_input_jar = _input_jar_path
public_deps = []
}
_deps = []
_deps = [ ":$_assert_target" ]
_previous_output_jar = _assert_output_jar
}
if (_retrolambda) {
_retrolambda_target = "${target_name}__retrolambda"
_retrolambda_input_jar = _previous_output_jar
_retrolambda_output_jar = "$target_out_dir/$target_name-retrolambda.jar"
android_sdk_jar = "$android_sdk/android.jar"
action(_retrolambda_target) {
script = "//build/android/gyp/retrolambda.py"
deps = _deps
if (defined(invoker.deps)) {
deps = invoker.deps
deps += invoker.deps
}
if (defined(invoker.public_deps)) {
public_deps += invoker.public_deps
public_deps = invoker.public_deps
}
sources = [
_copy_input_jar,
inputs = [
_build_config,
_retrolambda_input_jar,
]
outputs = [
_output_jar_path,
_retrolambda_output_jar,
]
args = [
"--input-jar",
rebase_path(_retrolambda_input_jar, root_build_dir),
"--output-jar",
rebase_path(_retrolambda_output_jar, root_build_dir),
"--classpath=@FileArg($_rebased_build_config:javac:classpath)",
"--android-sdk-jar",
rebase_path(android_sdk_jar, root_build_dir),
]
}
_deps = []
_deps = [ ":$_retrolambda_target" ]
_previous_output_jar = _retrolambda_output_jar
}
_output_jar_target = "${target_name}__copy"
copy(_output_jar_target) {
deps = _deps
if (defined(invoker.deps)) {
deps += invoker.deps
}
if (defined(invoker.public_deps)) {
public_deps = invoker.public_deps
}
sources = [
_previous_output_jar,
]
outputs = [
_output_jar_path,
]
}
group(target_name) {
@ -2083,7 +2126,9 @@ if (enable_java_templates) {
rebase_path(_android_sdk_ijar, root_build_dir)
args += [ "--bootclasspath=$_rebased_android_sdk_ijar" ]
}
if (_supports_android) {
if (use_java8) {
args += [ "--java-version=1.8" ]
} else if (_supports_android) {
args += [ "--java-version=1.7" ]
}
foreach(e, _manifest_entries) {

Просмотреть файл

@ -1160,6 +1160,9 @@ if (enable_java_templates) {
# will be added to the javac classpath.
# jar_path: Path to the prebuilt jar.
# jar_dep: Target that builds jar_path (optional).
# main_class: When specified, a wrapper script is created within
# $root_build_dir/bin to launch the binary with the given class as the
# entrypoint.
# output_name: File name for the output .jar (not including extension).
# Defaults to the input .jar file name.
# proguard_preprocess: If true, proguard preprocessing will be run. This can