diff options
-rw-r--r-- | WORKSPACE | 19 | ||||
-rwxr-xr-x | scripts/ci/build.sh | 7 | ||||
-rw-r--r-- | src/BUILD | 35 | ||||
-rwxr-xr-x | src/create_embedded_tools.sh | 14 | ||||
-rw-r--r-- | src/main/cpp/startup_options.cc | 12 | ||||
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/runtime/commands/LicenseCommand.java | 45 | ||||
-rw-r--r-- | src/test/shell/bazel/BUILD | 10 | ||||
-rwxr-xr-x | src/test/shell/bazel/bazel_with_jdk_test.sh | 77 |
8 files changed, 212 insertions, 7 deletions
@@ -67,3 +67,22 @@ new_local_repository( path = "./third_party/protobuf/3.0.0/", build_file = "./third_party/protobuf/3.0.0/com_google_protobuf_java.BUILD", ) + +# OpenJDK distributions used to create a version of Bazel bundled with the OpenJDK. +http_file( + name = "openjdk_linux", + url = "https://bazel-mirror.storage.googleapis.com/openjdk/azul-zulu-8.20.0.5-jdk8.0.121/zulu8.20.0.5-jdk8.0.121-linux_x64.tar.gz", + sha256 = "7fdfb17d890406470b2303d749d3138e7f353749e67a0a22f542e1ab3e482745", +) + +http_file( + name = "openjdk_macos", + url = "https://bazel-mirror.storage.googleapis.com/openjdk/azul-zulu-8.20.0.5-jdk8.0.121/zulu8.20.0.5-jdk8.0.121-macosx_x64.zip", + sha256 = "2a58bd1d9b0cbf0b3d8d1bcdd117c407e3d5a0ec01e2f53565c9bec5cf9ea78b", +) + +http_file( + name = "openjdk_win", + url = "https://bazel-mirror.storage.googleapis.com/openjdk/azul-zulu-8.20.0.5-jdk8.0.121/zulu8.20.0.5-jdk8.0.121-win_x64.zip", + sha256 = "35414df28f17704546b9559b5e62b4d00cdc8fdfd349116be4f987abaeaaff68", +) diff --git a/scripts/ci/build.sh b/scripts/ci/build.sh index 17fb98ec08..8bcaf693b4 100755 --- a/scripts/ci/build.sh +++ b/scripts/ci/build.sh @@ -217,6 +217,13 @@ _Notice_: Bazel installers contain binaries licensed under the GPLv2 with Classpath exception. Those installers should always be redistributed along with the source code. +Some versions of Bazel contain a bundled version of OpenJDK. The license of the +bundled OpenJDK and other open-source components can be displayed by running +the command `bazel license`. The vendor and version information of the bundled +OpenJDK can be displayed by running the command `bazel info java-runtime`. +The binaries and source-code of the bundled OpenJDK can be +[downloaded from our mirror server](https://bazel-mirror.storage.googleapis.com/openjdk/index.html). + _Security_: All our binaries are signed with our [public key](https://bazel.build/bazel-release.pub.gpg) 48457EE0. " @@ -40,6 +40,7 @@ filegroup( }), ) for suffix, embedded_tools in { "": [":embedded_tools"], + "_with_jdk": [":embedded_tools_with_jdk"], "_notools": [], }.items()] @@ -127,8 +128,8 @@ filegroup( ], ) -genrule( - name = "embedded_tools", +[genrule( + name = "embedded_tools" + suffix, srcs = [ ":create_embedded_tools.sh", "//tools:embedded_tools_srcs", @@ -171,14 +172,33 @@ genrule( "//conditions:default": [ "//src/java_tools/buildjar/java/com/google/devtools/build/java/turbine:turbine_deploy.jar", ], - }), - outs = ["embedded_tools.zip"], + }) + (select({ + ":darwin": [ + "@openjdk_macos//file", + ], + ":darwin_x86_64": [ + "@openjdk_macos//file", + ], + ":windows": [ + "@openjdk_win//file", + ], + ":windows_msvc": [ + "@openjdk_win//file", + ], + "//conditions:default": [ + "@openjdk_linux//file", + ], + }) if (suffix == "_with_jdk") else []), + outs = ["embedded_tools" + suffix + ".zip"], cmd = "$(location :create_embedded_tools.sh) $@ $(SRCS)", -) +) for suffix in [ + "", + "_with_jdk", +]] [genrule( name = "package-zip" + suffix, - srcs = ([":embedded_tools.zip"] if embed else []) + [ + srcs = ([":embedded_tools" + suffix + ".zip"] if embed else []) + [ # The script assumes that the embedded tools zip (if exists) is the # first item here, the deploy jar the second and install base key is the # third @@ -199,6 +219,7 @@ genrule( ) for suffix, embed in [ ("", True), ("_notools", False), + ("_with_jdk", True), ]] [genrule( @@ -223,6 +244,7 @@ genrule( ) for suffix in [ "", "_notools", + "_with_jdk", ]] # Build an executable named `bazel.exe`. @@ -243,6 +265,7 @@ genrule( ) for suffix in [ "", "_notools", + "_with_jdk", ]] config_setting( diff --git a/src/create_embedded_tools.sh b/src/create_embedded_tools.sh index a9b27f0153..a883d9582f 100755 --- a/src/create_embedded_tools.sh +++ b/src/create_embedded_tools.sh @@ -63,6 +63,8 @@ for i in $*; do *xcode*xcode-locator) OUTPUT_PATH=tools/objc/xcode-locator ;; *src/tools/xcode/*.sh) OUTPUT_PATH=tools/objc/${i##*/} ;; *src/tools/xcode/*) OUTPUT_PATH=tools/objc/${i##*/}.sh ;; + *external/openjdk_*/file/*.tar.gz) OUTPUT_PATH=jdk.tar.gz ;; + *external/openjdk_*/file/*.zip) OUTPUT_PATH=jdk.zip ;; *) OUTPUT_PATH=$(echo $i | sed 's_^.*bazel-out/[^/]*/bin/__') ;; esac @@ -71,6 +73,18 @@ for i in $*; do chmod u+w "${PACKAGE_DIR}/${OUTPUT_PATH}" done +if [ -f ${PACKAGE_DIR}/jdk.tar.gz ]; then + tar xz -C ${PACKAGE_DIR} -f ${PACKAGE_DIR}/jdk.tar.gz + rm ${PACKAGE_DIR}/jdk.tar.gz + mv ${PACKAGE_DIR}/zulu* ${PACKAGE_DIR}/jdk +fi + +if [ -f ${PACKAGE_DIR}/jdk.zip ]; then + unzip -d ${PACKAGE_DIR} ${PACKAGE_DIR}/jdk.zip > /dev/null + rm ${PACKAGE_DIR}/jdk.zip + mv ${PACKAGE_DIR}/zulu* ${PACKAGE_DIR}/jdk +fi + if [ ! -f ${PACKAGE_DIR}/third_party/java/jdk/langtools/javac-9-dev-r3297-4.jar ]; then cp ${PACKAGE_DIR}/third_party/java/jdk/langtools/javac7.jar \ ${PACKAGE_DIR}/third_party/java/jdk/langtools/javac-9-dev-r3297-4.jar diff --git a/src/main/cpp/startup_options.cc b/src/main/cpp/startup_options.cc index 414e95d476..55cc85d812 100644 --- a/src/main/cpp/startup_options.cc +++ b/src/main/cpp/startup_options.cc @@ -347,9 +347,19 @@ string StartupOptions::GetDefaultHostJavabase() const { } string StartupOptions::GetHostJavabase() { + // 1) Allow overriding the host_javabase via --host_javabase. if (host_javabase.empty()) { if (default_host_javabase.empty()) { - default_host_javabase = GetDefaultHostJavabase(); + string bundled_jre_path = blaze_util::JoinPath( + install_base, "_embedded_binaries/embedded_tools/jdk"); + if (blaze_util::CanExecuteFile(blaze_util::JoinPath( + bundled_jre_path, GetJavaBinaryUnderJavabase()))) { + // 2) Use a bundled JVM if we have one. + default_host_javabase = bundled_jre_path; + } else { + // 3) Otherwise fall back to using the default system JVM. + default_host_javabase = GetDefaultHostJavabase(); + } } return default_host_javabase; diff --git a/src/main/java/com/google/devtools/build/lib/runtime/commands/LicenseCommand.java b/src/main/java/com/google/devtools/build/lib/runtime/commands/LicenseCommand.java index 5dc8a3a1b2..8902b07a68 100644 --- a/src/main/java/com/google/devtools/build/lib/runtime/commands/LicenseCommand.java +++ b/src/main/java/com/google/devtools/build/lib/runtime/commands/LicenseCommand.java @@ -13,6 +13,7 @@ // limitations under the License. package com.google.devtools.build.lib.runtime.commands; +import com.google.common.io.Files; import com.google.devtools.build.lib.analysis.NoBuildEvent; import com.google.devtools.build.lib.runtime.BlazeCommand; import com.google.devtools.build.lib.runtime.Command; @@ -20,9 +21,11 @@ import com.google.devtools.build.lib.runtime.CommandEnvironment; import com.google.devtools.build.lib.util.ExitCode; import com.google.devtools.build.lib.util.ResourceFileLoader; import com.google.devtools.build.lib.util.io.OutErr; +import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.common.options.OptionsParser; import com.google.devtools.common.options.OptionsProvider; import java.io.IOException; +import java.util.TreeSet; /** A command that prints an embedded license text. */ @Command( @@ -34,6 +37,16 @@ import java.io.IOException; ) public class LicenseCommand implements BlazeCommand { + private static final TreeSet<String> JAVA_LICENSE_FILES = + new TreeSet<>(String.CASE_INSENSITIVE_ORDER); + + static { + JAVA_LICENSE_FILES.add("ASSEMBLY_EXCEPTION"); + JAVA_LICENSE_FILES.add("DISCLAIMER"); + JAVA_LICENSE_FILES.add("LICENSE"); + JAVA_LICENSE_FILES.add("THIRD_PARTY_README"); + } + public static boolean isSupported() { return ResourceFileLoader.resourceExists(LicenseCommand.class, "LICENSE"); } @@ -52,9 +65,41 @@ public class LicenseCommand implements BlazeCommand { "I/O error while trying to print 'LICENSE' resource: " + e.getMessage(), e); } + Path bundledJdk = + env.getDirectories().getEmbeddedBinariesRoot().getRelative("embedded_tools/jdk"); + if (bundledJdk.exists()) { + outErr.printOutLn( + "This binary comes with a bundled JDK, which contains the following license files:\n"); + printJavaLicenseFiles(outErr, bundledJdk); + } + + Path bundledJre = + env.getDirectories().getEmbeddedBinariesRoot().getRelative("embedded_tools/jre"); + if (bundledJre.exists()) { + outErr.printOutLn( + "This binary comes with a bundled JRE, which contains the following license files:\n"); + printJavaLicenseFiles(outErr, bundledJre); + } + return ExitCode.SUCCESS; } + private static void printJavaLicenseFiles(OutErr outErr, Path bundledJdkOrJre) { + try { + for (Path path : bundledJdkOrJre.getDirectoryEntries()) { + if (JAVA_LICENSE_FILES.contains(path.getBaseName().toLowerCase())) { + outErr.printOutLn(path.getPathString() + ":\n"); + Files.copy(path.getPathFile(), outErr.getOutputStream()); + outErr.printOutLn("\n"); + } + } + } catch (IOException e) { + throw new IllegalStateException( + "I/O error while trying to print license file of bundled JDK or JRE: " + e.getMessage(), + e); + } + } + @Override public void editOptions(CommandEnvironment env, OptionsParser optionsParser) {} } diff --git a/src/test/shell/bazel/BUILD b/src/test/shell/bazel/BUILD index ba16b20a82..4dcf277f04 100644 --- a/src/test/shell/bazel/BUILD +++ b/src/test/shell/bazel/BUILD @@ -391,6 +391,16 @@ sh_test( ) sh_test( + name = "bazel_with_jdk_test", + size = "medium", + srcs = ["bazel_with_jdk_test.sh"], + data = [ + ":test-deps", + "//src:bazel_with_jdk", + ], +) + +sh_test( name = "build_files_test", size = "medium", srcs = ["build_files_test.sh"], diff --git a/src/test/shell/bazel/bazel_with_jdk_test.sh b/src/test/shell/bazel/bazel_with_jdk_test.sh new file mode 100755 index 0000000000..d4a51f391c --- /dev/null +++ b/src/test/shell/bazel/bazel_with_jdk_test.sh @@ -0,0 +1,77 @@ +#!/bin/bash +# +# Copyright 2017 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Tests that the version of Bazel with a bundled JDK works. +# + +# Load the test setup defined in the parent directory +source $(rlocation io_bazel/src/test/shell/integration_test_setup.sh) \ + || { echo "integration_test_setup.sh not found!" >&2; exit 1; } + +function bazel_with_jdk() { + $(rlocation io_bazel/src/bazel_with_jdk) --bazelrc=$TEST_TMPDIR/bazelrc "$@" + return $? +} + +function set_up() { + # TODO(philwo) remove this when the testenv improvement change is in + if is_windows; then + export PATH=/c/python_27_amd64/files:$PATH + EXTRA_BAZELRC="build --cpu=x64_windows_msvc" + setup_bazelrc + fi + + # The default test setup adds a --host_javabase flag, which prevents us from + # actually using the bundled one. Remove it. + fgrep -v -- "--host_javabase" "$TEST_TMPDIR/bazelrc" > "$TEST_TMPDIR/bazelrc.new" + mv "$TEST_TMPDIR/bazelrc.new" "$TEST_TMPDIR/bazelrc" +} + +function cleanup() { + # Prevent the default "cleanup" function from running, which fails on Windows. + return 0 +} + +function test_bazel_uses_bundled_jdk() { + bazel_with_jdk --batch info &> "$TEST_log" || fail "bazel_with_jdk info failed" + install_base="$(bazel_with_jdk --batch info install_base)" + + # Case-insensitive match, because Windows paths are case-insensitive. + grep -sqi -- "^java-home: ${install_base}/_embedded_binaries/embedded_tools/jdk" $TEST_log || \ + fail "bazel_with_jdk's java-home is not inside the install base" +} + +# Tests that "bazel_with_jdk license" prints the license of the bundled JDK by grepping for +# representative strings from those files. If this test breaks after upgrading the version of the +# bundled JDK, the strings may have to be updated. +function test_bazel_license_prints_jdk_license() { + bazel_with_jdk --batch license \ + &> "$TEST_log" || fail "running bazel_with_jdk license failed" + + expect_log "OPENJDK ASSEMBLY EXCEPTION" || \ + fail "'bazel_with_jdk license' did not print an expected string from ASSEMBLY_EXCEPTION" + + expect_log "Provided you have not received the software directly from Azul and have already" || \ + fail "'bazel_with_jdk license' did not print an expected string from DISCLAIMER" + + expect_log '"CLASSPATH" EXCEPTION TO THE GPL' || \ + fail "'bazel_with_jdk license' did not print an expected string from LICENSE" + + expect_log "which may be included with JRE [0-9]\+, JDK [0-9]\+, and OpenJDK [0-9]\+" || \ + fail "'bazel_with_jdk license' did not print an expected string from THIRD_PARTY_README" +} + +run_suite "bazel_with_jdk test suite" |