diff options
author | Romain Jobredeaux <jobredeaux@google.com> | 2023-06-23 23:19:25 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-06-23 23:19:25 +0000 |
commit | 8e548c7053dffd1717d565f0409a88992f401da1 (patch) | |
tree | bbcbc6947dcfb0db5620b5551499cd6c21befd61 | |
parent | 46d2e3625390f640d652bde0577dc7433ab42ed9 (diff) | |
parent | 00df52457a9a49dbd065623852dde2f6e6811f73 (diff) | |
download | bazelbuild-rules_java-master.tar.gz |
Initial import of rules_java. am: 4ba159a9c4 am: 640e0bdda9 am: fb2d8c8a4e am: 926d40d0a4 am: 31a90a6fb5 am: 00df52457aHEADandroid-14.0.0_r37android-14.0.0_r36android-14.0.0_r35android-14.0.0_r34android-14.0.0_r33android-14.0.0_r32android-14.0.0_r31android-14.0.0_r30android-14.0.0_r29android-14.0.0_r28mastermain-kernel-build-2024mainandroid14-qpr2-s5-releaseandroid14-qpr2-s4-releaseandroid14-qpr2-s3-releaseandroid14-qpr2-s2-releaseandroid14-qpr2-s1-releaseandroid14-qpr2-release
Original change: https://android-review.googlesource.com/c/platform/external/bazelbuild-rules_java/+/2637269
Change-Id: Ib58c46b9c611de78b590e5a31cae2e904f33b449
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
38 files changed, 2914 insertions, 0 deletions
diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml new file mode 100644 index 0000000..cd90651 --- /dev/null +++ b/.bazelci/presubmit.yml @@ -0,0 +1,55 @@ +--- +build_targets: &build_targets + - "//..." + - "@remote_java_tools//java_tools/..." + # TODO: Look into broken targets in //toolchains + - "-//toolchains/..." + +build_targets_bzlmod: &build_targets_bzlmod + - "//..." + - "@remote_java_tools//java_tools/..." + - "-//toolchains/..." + # TODO(pcloudy): pkg_tar doesn't work with Bzlmod due to https://github.com/bazelbuild/bazel/issues/14259 + # Enable once the issue is fixed. + - "-//distro/..." + +buildifier: + version: latest + warnings: "all" +tasks: + ubuntu2004: + build_targets: *build_targets + macos: + build_targets: *build_targets + windows: + build_targets: *build_targets + ubuntu2004_head: + bazel: last_green + platform: ubuntu2004 + build_targets: *build_targets + macos_head: + bazel: last_green + platform: macos + build_targets: *build_targets + windows_head: + bazel: last_green + platform: windows + build_targets: *build_targets + ubuntu2004_bzlmod: + bazel: last_green + platform: ubuntu2004 + build_flags: + - "--config=bzlmod" + build_targets: *build_targets_bzlmod + macos_bzlmod: + bazel: last_green + platform: macos + build_flags: + - "--config=bzlmod" + build_targets: *build_targets_bzlmod + windows_bzlmod: + bazel: last_green + platform: windows + build_flags: + - "--config=bzlmod" + build_targets: *build_targets_bzlmod diff --git a/.bazelrc b/.bazelrc new file mode 100644 index 0000000..4fadfce --- /dev/null +++ b/.bazelrc @@ -0,0 +1 @@ +build:bzlmod --experimental_enable_bzlmod diff --git a/.bcr/metadata.template.json b/.bcr/metadata.template.json new file mode 100644 index 0000000..41ba4c2 --- /dev/null +++ b/.bcr/metadata.template.json @@ -0,0 +1,9 @@ +{ + "homepage": "https://github.com/bazelbuild/rules_java", + "maintainers": [], + "versions": [], + "yanked_versions": {}, + "repository": [ + "github:bazelbuild/rules_java" + ] +} diff --git a/.bcr/presubmit.yml b/.bcr/presubmit.yml new file mode 100644 index 0000000..52f713e --- /dev/null +++ b/.bcr/presubmit.yml @@ -0,0 +1,8 @@ +matrix: + platform: ["centos7", "debian10", "macos", "ubuntu2004", "windows"] +tasks: + verify_build_targets: + name: "Verify build targets" + platform: ${{ platform }} + build_targets: + - "@rules_java//java/..." diff --git a/.bcr/source.template.json b/.bcr/source.template.json new file mode 100644 index 0000000..095a9e8 --- /dev/null +++ b/.bcr/source.template.json @@ -0,0 +1,5 @@ +{ + "integrity": "", + "strip_prefix": "", + "url": "https://github.com/{OWNER}/{REPO}/releases/download/{TAG}/rules_java-{TAG}.tar.gz" +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ef43625 --- /dev/null +++ b/.gitignore @@ -0,0 +1,19 @@ +# Ignore backup files. +*~ +# Ignore Vim swap files. +.*.swp +# Ignore files generated by IDEs. +/.classpath +/.factorypath +/.idea/ +/.ijwb/ +/.project +/.settings +# Ignore all bazel-* symlinks. There is no full list since this can change +# based on the name of the directory bazel is cloned into. +/bazel-* +# Ignore outputs generated during Bazel bootstrapping. +/output/ +# Ignore jekyll build output. +/production +/.sass-cache @@ -0,0 +1,9 @@ +# This the official list of Bazel authors for copyright purposes. +# This file is distinct from the CONTRIBUTORS files. +# See the latter for an explanation. + +# Names should be added to this file as: +# Name or Organization <email address> +# The email address is not required for organizations. + +Google Inc. @@ -0,0 +1,19 @@ +licenses(["notice"]) + +exports_files([ + "LICENSE", + "WORKSPACE", +]) + +filegroup( + name = "distribution", + srcs = [ + "AUTHORS", + "BUILD", + "LICENSE", + "MODULE.bazel", + "//java:srcs", + "//toolchains:srcs", + ], + visibility = ["//distro:__pkg__"], +) diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000..1f7a7ed --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,17 @@ +# Each line is a file pattern followed by one or more owners. + +# Order is important; the last matching pattern takes the most precedence. + +# When someone opens a pull request that only modifies files in directory, only +# component owners and not the global owner(s) will be requested for a review. + +# Syntax: https://help.github.com/articles/about-codeowners/ + +# Use individual usernames instead of teams (like @bazelbuild/android) for +# auto-assignment to work, unless everyone in the team has write permissions to the repository. +# See https://github.community/t5/How-to-use-Git-and-GitHub/CODEOWNERS-works-with-users-but-not-teams/td-p/4986 + +# Component owners +# ---------------- + +* @comius @bazelbuild/java-team diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..db177d4 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,28 @@ +# How to Contribute + +We'd love to accept your patches and contributions to this project. There are +just a few small guidelines you need to follow. + +## Contributor License Agreement + +Contributions to this project must be accompanied by a Contributor License +Agreement. You (or your employer) retain the copyright to your contribution; +this simply gives us permission to use and redistribute your contributions as +part of the project. Head over to <https://cla.developers.google.com/> to see +your current agreements on file or to sign a new one. + +You generally only need to submit a CLA once, so if you've already submitted one +(even if it was for a different project), you probably don't need to do it +again. + +## Code reviews + +All submissions, including submissions by project members, require review. We +use GitHub pull requests for this purpose. Consult +[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more +information on using pull requests. + +## Community Guidelines + +This project follows +[Google's Open Source Community Guidelines](https://opensource.google.com/conduct/). @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/METADATA b/METADATA new file mode 100644 index 0000000..7414aa4 --- /dev/null +++ b/METADATA @@ -0,0 +1,13 @@ +name: "rules_java" +description: + "Bazel rules for building java code" + +third_party { + url { + type: GIT + value: "https://github.com/bazelbuild/rules_java" + } + version: "6.1.1" + last_upgrade_date { year: 2023 month: 6 day: 23 } + license_type: NOTICE +} diff --git a/MODULE.bazel b/MODULE.bazel new file mode 100644 index 0000000..ebf3c8c --- /dev/null +++ b/MODULE.bazel @@ -0,0 +1,75 @@ +module( + name = "rules_java", + version = "6.1.1", + compatibility_level = 1, +) + +bazel_dep(name = "platforms", version = "0.0.4") +bazel_dep(name = "rules_cc", version = "0.0.2") +bazel_dep(name = "bazel_skylib", version = "1.2.0") + +# Required by @remote_java_tools, which is loaded via module extension. +bazel_dep(name = "rules_proto", version = "4.0.0") +bazel_dep(name = "rules_license", version = "0.0.3") + +register_toolchains("//toolchains:all") + +toolchains = use_extension("//java:extensions.bzl", "toolchains") + +# Declare remote java tools repos +use_repo(toolchains, "remote_java_tools") +use_repo(toolchains, "remote_java_tools_linux") +use_repo(toolchains, "remote_java_tools_windows") +use_repo(toolchains, "remote_java_tools_darwin_x86_64") +use_repo(toolchains, "remote_java_tools_darwin_arm64") + +# Declare local jdk repo +use_repo(toolchains, "local_jdk") + +register_toolchains("@local_jdk//:runtime_toolchain_definition") + +# Declare all remote jdk toolchain config repos +JDKS = { + # Must match JDK repos defined in remote_jdk11_repos() + "11": [ + "linux", + "linux_aarch64", + "linux_ppc64le", + "linux_s390x", + "macos", + "macos_aarch64", + "win", + "win_arm64", + ], + # Must match JDK repos defined in remote_jdk17_repos() + "17": [ + "linux", + "linux_aarch64", + "linux_ppc64le", + "linux_s390x", + "macos", + "macos_aarch64", + "win", + "win_arm64", + ], + # Must match JDK repos defined in remote_jdk20_repos() + "20": [ + "linux", + "linux_aarch64", + "macos", + "macos_aarch64", + "win", + ], +} + +REMOTE_JDK_REPOS = [("remotejdk" + version + "_" + platform) for version in JDKS for platform in JDKS[version]] + +[use_repo( + toolchains, + repo + "_toolchain_config_repo", +) for repo in REMOTE_JDK_REPOS] + +[register_toolchains("@" + name + "_toolchain_config_repo//:toolchain") for name in REMOTE_JDK_REPOS] + +# Dev dependencies +bazel_dep(name = "rules_pkg", version = "0.5.1", dev_dependency = True) diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/MODULE_LICENSE_APACHE2 @@ -0,0 +1,3 @@ +include platform/build/bazel:/OWNERS +jobredeaux@google.com +agespino@google.com diff --git a/README.md b/README.md new file mode 100644 index 0000000..8c946de --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +# rules_java + +* Postsubmit [![Build status](https://badge.buildkite.com/d4f950ef5f481b8ca066624ba06c238fa1446d84a057ddbf89.svg?branch=master)](https://buildkite.com/bazel/rules-java-java) +* Postsubmit + Current Bazel Incompatible Flags [![Build status](https://badge.buildkite.com/ef265d270238c02aff65106a0b861abb9265efacdf4af399c3.svg?branch=master)](https://buildkite.com/bazel/rules-java-plus-bazelisk-migrate) + +Java Rules for Bazel https://bazel.build. diff --git a/WORKSPACE b/WORKSPACE new file mode 100644 index 0000000..059716f --- /dev/null +++ b/WORKSPACE @@ -0,0 +1,29 @@ +workspace(name = "rules_java") + +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + +http_archive( + name = "bazel_skylib", + sha256 = "af87959afe497dc8dfd4c6cb66e1279cb98ccc84284619ebfec27d9c09a903de", + urls = [ + "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.2.0/bazel-skylib-1.2.0.tar.gz", + "https://github.com/bazelbuild/bazel-skylib/releases/download/1.2.0/bazel-skylib-1.2.0.tar.gz", + ], +) + +load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace") + +bazel_skylib_workspace() + +http_archive( + name = "rules_pkg", + sha256 = "a89e203d3cf264e564fcb96b6e06dd70bc0557356eb48400ce4b5d97c2c3720d", + urls = [ + "https://mirror.bazel.build/github.com/bazelbuild/rules_pkg/releases/download/0.5.1/rules_pkg-0.5.1.tar.gz", + "https://github.com/bazelbuild/rules_pkg/releases/download/0.5.1/rules_pkg-0.5.1.tar.gz", + ], +) + +load("@rules_pkg//:deps.bzl", "rules_pkg_dependencies") + +rules_pkg_dependencies() diff --git a/WORKSPACE.bzlmod b/WORKSPACE.bzlmod new file mode 100644 index 0000000..b021fa6 --- /dev/null +++ b/WORKSPACE.bzlmod @@ -0,0 +1,2 @@ +# A completely empty WORKSPACE file to replace the original WORKSPACE content when enabling Bzlmod. +# No WORKSPACE prefix or suffix are added for this file. diff --git a/distro/BUILD.bazel b/distro/BUILD.bazel new file mode 100644 index 0000000..d136ca1 --- /dev/null +++ b/distro/BUILD.bazel @@ -0,0 +1,30 @@ +load("@rules_pkg//:pkg.bzl", "pkg_tar") +load("@rules_pkg//releasing:defs.bzl", "print_rel_notes") +load("//java:defs.bzl", "version") + +package( + default_visibility = ["//visibility:private"], +) + +# Build the artifact to put on the github release page. +pkg_tar( + name = "rules_java-%s" % version, + srcs = ["//:distribution"], + extension = "tar.gz", + # It is all source code, so make it read-only. + mode = "0444", + # Make it owned by root so it does not have the uid of the CI robot. + owner = "0.0", + package_dir = ".", + strip_prefix = ".", +) + +print_rel_notes( + name = "relnotes", + outs = ["relnotes.txt"], + deps_method = "rules_java_dependencies", + repo = "rules_java", + setup_file = "java:repositories.bzl", + toolchains_method = "rules_java_toolchains", + version = version, +) diff --git a/distro/README.md b/distro/README.md new file mode 100644 index 0000000..eb57af3 --- /dev/null +++ b/distro/README.md @@ -0,0 +1,9 @@ +# Releasing rules_java + +1. Update version in [java/defs.bzl](/java/defs.bzl), + [MODULE.bazel](/MODULE.bazel) and merge it +2. Build the release running `bazel build //distro:rules_java-{version}` +3. Prepare release notes running `bazel build //distro:relnotes` +4. Create a new release on GitHub +5. Copy/paste the produced `relnotes.txt` into the notes. Adjust as needed. +6. Upload the produced tar.gz file as an artifact. diff --git a/examples/hello_world/BUILD b/examples/hello_world/BUILD new file mode 100644 index 0000000..282e2d7 --- /dev/null +++ b/examples/hello_world/BUILD @@ -0,0 +1,7 @@ +load("//java:defs.bzl", "java_binary") + +java_binary( + name = "hello_world", + srcs = ["com/google/HelloWorld.java"], + main_class = "com.google.HelloWorld", +) diff --git a/examples/hello_world/com/google/HelloWorld.java b/examples/hello_world/com/google/HelloWorld.java new file mode 100644 index 0000000..5104eb0 --- /dev/null +++ b/examples/hello_world/com/google/HelloWorld.java @@ -0,0 +1,23 @@ +// Copyright 2021 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. +package com.google; + +public class HelloWorld { + + private HelloWorld() {} + + public static void main (String[] args) { + System.out.println("Hello World!\n"); + } +} diff --git a/java/BUILD b/java/BUILD new file mode 100644 index 0000000..8e07ca3 --- /dev/null +++ b/java/BUILD @@ -0,0 +1,18 @@ +load("@bazel_skylib//:bzl_library.bzl", "bzl_library") + +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +filegroup( + name = "srcs", + srcs = glob(["**"]) + ["//java/private:srcs"], + visibility = ["//:__pkg__"], +) + +bzl_library( + name = "rules", + srcs = ["defs.bzl"], + visibility = ["//visibility:public"], + deps = ["//java/private"], +) diff --git a/java/defs.bzl b/java/defs.bzl new file mode 100644 index 0000000..bbfc55f --- /dev/null +++ b/java/defs.bzl @@ -0,0 +1,154 @@ +# Copyright 2019 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. +"""Starlark rules for building Java projects.""" + +load("//java/private:native.bzl", "NativeJavaInfo", "NativeJavaPluginInfo", "native_java_common") + +# Do not touch: This line marks the end of loads; needed for PR importing. + +_MIGRATION_TAG = "__JAVA_RULES_MIGRATION_DO_NOT_USE_WILL_BREAK__" +version = "6.1.1" + +def _add_tags(attrs): + if "tags" in attrs and attrs["tags"] != None: + attrs["tags"] = attrs["tags"] + [_MIGRATION_TAG] + else: + attrs["tags"] = [_MIGRATION_TAG] + return attrs + +def java_binary(**attrs): + """Bazel java_binary rule. + + https://docs.bazel.build/versions/master/be/java.html#java_binary + + Args: + **attrs: Rule attributes + """ + + # buildifier: disable=native-java + native.java_binary(**_add_tags(attrs)) + +def java_import(**attrs): + """Bazel java_import rule. + + https://docs.bazel.build/versions/master/be/java.html#java_import + + Args: + **attrs: Rule attributes + """ + + # buildifier: disable=native-java + native.java_import(**_add_tags(attrs)) + +def java_library(**attrs): + """Bazel java_library rule. + + https://docs.bazel.build/versions/master/be/java.html#java_library + + Args: + **attrs: Rule attributes + """ + + # buildifier: disable=native-java + native.java_library(**_add_tags(attrs)) + +def java_lite_proto_library(**attrs): + """Bazel java_lite_proto_library rule. + + https://docs.bazel.build/versions/master/be/java.html#java_lite_proto_library + + Args: + **attrs: Rule attributes + """ + + # buildifier: disable=native-java + native.java_lite_proto_library(**_add_tags(attrs)) + +def java_proto_library(**attrs): + """Bazel java_proto_library rule. + + https://docs.bazel.build/versions/master/be/java.html#java_proto_library + + Args: + **attrs: Rule attributes + """ + + # buildifier: disable=native-java + native.java_proto_library(**_add_tags(attrs)) + +def java_test(**attrs): + """Bazel java_test rule. + + https://docs.bazel.build/versions/master/be/java.html#java_test + + Args: + **attrs: Rule attributes + """ + + # buildifier: disable=native-java + native.java_test(**_add_tags(attrs)) + +def java_package_configuration(**attrs): + """Bazel java_package_configuration rule. + + https://docs.bazel.build/versions/master/be/java.html#java_package_configuration + + Args: + **attrs: Rule attributes + """ + + # buildifier: disable=native-java + native.java_package_configuration(**_add_tags(attrs)) + +def java_plugin(**attrs): + """Bazel java_plugin rule. + + https://docs.bazel.build/versions/master/be/java.html#java_plugin + + Args: + **attrs: Rule attributes + """ + + # buildifier: disable=native-java + native.java_plugin(**_add_tags(attrs)) + +def java_runtime(**attrs): + """Bazel java_runtime rule. + + https://docs.bazel.build/versions/master/be/java.html#java_runtime + + Args: + **attrs: Rule attributes + """ + + # buildifier: disable=native-java + native.java_runtime(**_add_tags(attrs)) + +def java_toolchain(**attrs): + """Bazel java_toolchain rule. + + https://docs.bazel.build/versions/master/be/java.html#java_toolchain + + Args: + **attrs: Rule attributes + """ + + # buildifier: disable=native-java + native.java_toolchain(**_add_tags(attrs)) + +java_common = native_java_common + +JavaInfo = NativeJavaInfo + +JavaPluginInfo = NativeJavaPluginInfo diff --git a/java/extensions.bzl b/java/extensions.bzl new file mode 100644 index 0000000..5e456ed --- /dev/null +++ b/java/extensions.bzl @@ -0,0 +1,25 @@ +# Copyright 2021 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. +"""Module extensions for rules_java.""" + +load("//java:repositories.bzl", "java_tools_repos", "local_jdk_repo", "remote_jdk11_repos", "remote_jdk17_repos", "remote_jdk20_repos") + +def _toolchains_impl(_ctx): + java_tools_repos() + local_jdk_repo() + remote_jdk11_repos() + remote_jdk17_repos() + remote_jdk20_repos() + +toolchains = module_extension(implementation = _toolchains_impl) diff --git a/java/private/BUILD b/java/private/BUILD new file mode 100644 index 0000000..9f50995 --- /dev/null +++ b/java/private/BUILD @@ -0,0 +1,15 @@ +load("@bazel_skylib//:bzl_library.bzl", "bzl_library") + +licenses(["notice"]) + +bzl_library( + name = "private", + srcs = ["native.bzl"], + visibility = ["//java:__pkg__"], +) + +filegroup( + name = "srcs", + srcs = glob(["**"]), + visibility = ["//java:__pkg__"], +) diff --git a/java/private/native.bzl b/java/private/native.bzl new file mode 100644 index 0000000..64a4d5a --- /dev/null +++ b/java/private/native.bzl @@ -0,0 +1,31 @@ +# Copyright 2022 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. + +# Redefine native symbols with a new name as a workaround for +# exporting them in `//third_party/bazel_rules/rules_proto/proto:defs.bzl` with their original name. +# +# While we cannot force users to load these symbol due to the lack of a +# allowlisting mechanism, we can still export them and tell users to +# load it to make a future migration to pure Starlark easier. + +"""Lovely workaround to be able to expose native constants pretending to be Starlark.""" + +# buildifier: disable=native-java +native_java_common = java_common + +# buildifier: disable=native-java +NativeJavaInfo = JavaInfo + +# buildifier: disable=native-java +NativeJavaPluginInfo = JavaPluginInfo diff --git a/java/repositories.bzl b/java/repositories.bzl new file mode 100644 index 0000000..eaef6d7 --- /dev/null +++ b/java/repositories.bzl @@ -0,0 +1,557 @@ +# Copyright 2019 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. + +"""Development and production dependencies of rules_java.""" + +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") +load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe") +load("//toolchains:jdk_build_file.bzl", "JDK_BUILD_TEMPLATE") +load("//toolchains:local_java_repository.bzl", "local_java_repository") +load("//toolchains:remote_java_repository.bzl", "remote_java_repository") + +def java_tools_repos(): + """ Declares the remote java_tools repositories """ + maybe( + http_archive, + name = "remote_java_tools", + sha256 = "cbb62ecfef61568ded46260a8e8e8430755db7ec9638c0c7ff668a656f6c042f", + urls = [ + "https://mirror.bazel.build/bazel_java_tools/releases/java/v12.3/java_tools-v12.3.zip", + "https://github.com/bazelbuild/java_tools/releases/download/java_v12.3/java_tools-v12.3.zip", + ], + ) + + maybe( + http_archive, + name = "remote_java_tools_linux", + sha256 = "32157b5218b151009f5b99bf5e2f65e28823d269dfbba8cd57e7da5e7cdd291d", + urls = [ + "https://mirror.bazel.build/bazel_java_tools/releases/java/v12.3/java_tools_linux-v12.3.zip", + "https://github.com/bazelbuild/java_tools/releases/download/java_v12.3/java_tools_linux-v12.3.zip", + ], + ) + + maybe( + http_archive, + name = "remote_java_tools_windows", + sha256 = "ec6f91387d2353eacb0ca0492f35f68c5c7b0e7a80acd1fb825088b4b069fab1", + urls = [ + "https://mirror.bazel.build/bazel_java_tools/releases/java/v12.3/java_tools_windows-v12.3.zip", + "https://github.com/bazelbuild/java_tools/releases/download/java_v12.3/java_tools_windows-v12.3.zip", + ], + ) + + maybe( + http_archive, + name = "remote_java_tools_darwin_x86_64", + sha256 = "3c3fb1967a0f35c73ff509505de53ca4611518922a6b7c8c22a468aa7503132c", + urls = [ + "https://mirror.bazel.build/bazel_java_tools/releases/java/v12.3/java_tools_darwin_x86_64-v12.3.zip", + "https://github.com/bazelbuild/java_tools/releases/download/java_v12.3/java_tools_darwin_x86_64-v12.3.zip", + ], + ) + + maybe( + http_archive, + name = "remote_java_tools_darwin_arm64", + sha256 = "29aa0c2de4e3cf45bc55d2995ba803ecbd1173a8d363860abbc309551db7931b", + urls = [ + "https://mirror.bazel.build/bazel_java_tools/releases/java/v12.3/java_tools_darwin_arm64-v12.3.zip", + "https://github.com/bazelbuild/java_tools/releases/download/java_v12.3/java_tools_darwin_arm64-v12.3.zip", + ], + ) + +def local_jdk_repo(): + maybe( + local_java_repository, + name = "local_jdk", + build_file_content = JDK_BUILD_TEMPLATE, + ) + +def remote_jdk8_repos(name = ""): + """Imports OpenJDK 8 repositories. + + Args: + name: The name of this macro (not used) + """ + maybe( + remote_java_repository, + name = "remote_jdk8_linux_aarch64", + target_compatible_with = [ + "@platforms//os:linux", + "@platforms//cpu:aarch64", + ], + sha256 = "f4072e82faa5a09fab2accf2892d4684324fc999d614583c3ff785e87c03963f", + strip_prefix = "zulu8.50.51.263-ca-jdk8.0.275-linux_aarch64", + urls = [ + "https://mirror.bazel.build/openjdk/azul-zulu-8.50.0.51-ca-jdk8.0.275/zulu8.50.51.263-ca-jdk8.0.275-linux_aarch64.tar.gz", + "https://cdn.azul.com/zulu-embedded/bin/zulu8.50.51.263-ca-jdk8.0.275-linux_aarch64.tar.gz", + ], + version = "8", + ) + maybe( + remote_java_repository, + name = "remote_jdk8_linux_s390x", + target_compatible_with = [ + "@platforms//os:linux", + "@platforms//cpu:s390x", + ], + sha256 = "276a431c79b7e94bc1b1b4fd88523383ae2d635ea67114dfc8a6174267f8fb2c", + strip_prefix = "jdk8u292-b10", + urls = [ + "https://github.com/AdoptOpenJDK/openjdk8-binaries/releases/download/jdk8u292-b10/OpenJDK8U-jdk_s390x_linux_hotspot_8u292b10.tar.gz", + ], + version = "8", + ) + maybe( + remote_java_repository, + name = "remote_jdk8_linux", + target_compatible_with = [ + "@platforms//os:linux", + "@platforms//cpu:x86_64", + ], + sha256 = "1db6b2fa642950ee1b4b1ec2b6bc8a9113d7a4cd723f79398e1ada7dab1c981c", + strip_prefix = "zulu8.50.0.51-ca-jdk8.0.275-linux_x64", + urls = [ + "https://mirror.bazel.build/openjdk/azul-zulu-8.50.0.51-ca-jdk8.0.275/zulu8.50.0.51-ca-jdk8.0.275-linux_x64.tar.gz", + "https://cdn.azul.com/zulu/bin/zulu8.50.0.51-ca-jdk8.0.275-linux_x64.tar.gz", + ], + version = "8", + ) + maybe( + remote_java_repository, + name = "remote_jdk8_macos_aarch64", + target_compatible_with = [ + "@platforms//os:macos", + "@platforms//cpu:aarch64", + ], + sha256 = "e5c84a46bbd985c3a53358db9c97a6fd4930f92b833c3163a0d1e47dab59768c", + strip_prefix = "zulu8.62.0.19-ca-jdk8.0.332-macosx_aarch64", + urls = [ + "https://cdn.azul.com/zulu/bin/zulu8.62.0.19-ca-jdk8.0.332-macosx_aarch64.tar.gz", + ], + version = "8", + ) + maybe( + remote_java_repository, + name = "remote_jdk8_macos", + target_compatible_with = [ + "@platforms//os:macos", + "@platforms//cpu:x86_64", + ], + sha256 = "b03176597734299c9a15b7c2cc770783cf14d121196196c1248e80c026b59c17", + strip_prefix = "zulu8.50.0.51-ca-jdk8.0.275-macosx_x64", + urls = [ + "https://mirror.bazel.build/openjdk/azul-zulu-8.50.0.51-ca-jdk8.0.275/zulu8.50.0.51-ca-jdk8.0.275-macosx_x64.tar.gz", + "https://cdn.azul.com/zulu/bin/zulu8.50.0.51-ca-jdk8.0.275-macosx_x64.tar.gz", + ], + version = "8", + ) + maybe( + remote_java_repository, + name = "remote_jdk8_windows", + target_compatible_with = [ + "@platforms//os:windows", + "@platforms//cpu:x86_64", + ], + sha256 = "49759b2bd2ab28231a21ff3a3bb45824ddef55d89b5b1a05a62e26a365da0774", + strip_prefix = "zulu8.50.0.51-ca-jdk8.0.275-win_x64", + urls = [ + "https://mirror.bazel.build/openjdk/azul-zulu-8.50.0.51-ca-jdk8.0.275/zulu8.50.0.51-ca-jdk8.0.275-win_x64.zip", + "https://cdn.azul.com/zulu/bin/zulu8.50.0.51-ca-jdk8.0.275-win_x64.zip", + ], + version = "8", + ) + REMOTE_JDK8_REPOS = [ + "remote_jdk8_linux_aarch64", + "remote_jdk8_linux_s390x", + "remote_jdk8_linux", + "remote_jdk8_macos_aarch64", + "remote_jdk8_macos", + "remote_jdk8_windows", + ] + for name in REMOTE_JDK8_REPOS: + native.register_toolchains("@" + name + "_toolchain_config_repo//:toolchain") + +def remote_jdk11_repos(): + """Imports OpenJDK 11 repositories.""" + maybe( + remote_java_repository, + name = "remotejdk11_linux", + target_compatible_with = [ + "@platforms//os:linux", + "@platforms//cpu:x86_64", + ], + sha256 = "e064b61d93304012351242bf0823c6a2e41d9e28add7ea7f05378b7243d34247", + strip_prefix = "zulu11.56.19-ca-jdk11.0.15-linux_x64", + urls = [ + "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu11.56.19-ca-jdk11.0.15-linux_x64.tar.gz", + "https://cdn.azul.com/zulu/bin/zulu11.56.19-ca-jdk11.0.15-linux_x64.tar.gz", + ], + version = "11", + ) + + maybe( + remote_java_repository, + name = "remotejdk11_linux_aarch64", + target_compatible_with = [ + "@platforms//os:linux", + "@platforms//cpu:aarch64", + ], + sha256 = "fc7c41a0005180d4ca471c90d01e049469e0614cf774566d4cf383caa29d1a97", + strip_prefix = "zulu11.56.19-ca-jdk11.0.15-linux_aarch64", + urls = [ + "https://mirror.bazel.build/cdn.azul.com/zulu-embedded/bin/zulu11.56.19-ca-jdk11.0.15-linux_aarch64.tar.gz", + "https://cdn.azul.com/zulu-embedded/bin/zulu11.56.19-ca-jdk11.0.15-linux_aarch64.tar.gz", + ], + version = "11", + ) + + maybe( + remote_java_repository, + name = "remotejdk11_linux_ppc64le", + target_compatible_with = [ + "@platforms//os:linux", + "@platforms//cpu:ppc", + ], + sha256 = "a8fba686f6eb8ae1d1a9566821dbd5a85a1108b96ad857fdbac5c1e4649fc56f", + strip_prefix = "jdk-11.0.15+10", + urls = [ + "https://mirror.bazel.build/github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.15+10/OpenJDK11U-jdk_ppc64le_linux_hotspot_11.0.15_10.tar.gz", + "https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.15+10/OpenJDK11U-jdk_ppc64le_linux_hotspot_11.0.15_10.tar.gz", + ], + version = "11", + ) + + maybe( + remote_java_repository, + name = "remotejdk11_linux_s390x", + target_compatible_with = [ + "@platforms//os:linux", + "@platforms//cpu:s390x", + ], + sha256 = "a58fc0361966af0a5d5a31a2d8a208e3c9bb0f54f345596fd80b99ea9a39788b", + strip_prefix = "jdk-11.0.15+10", + urls = [ + "https://mirror.bazel.build/github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.15+10/OpenJDK11U-jdk_s390x_linux_hotspot_11.0.15_10.tar.gz", + "https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.15+10/OpenJDK11U-jdk_s390x_linux_hotspot_11.0.15_10.tar.gz", + ], + version = "11", + ) + + maybe( + remote_java_repository, + name = "remotejdk11_macos", + target_compatible_with = [ + "@platforms//os:macos", + "@platforms//cpu:x86_64", + ], + sha256 = "2614e5c5de8e989d4d81759de4c333aa5b867b17ab9ee78754309ba65c7f6f55", + strip_prefix = "zulu11.56.19-ca-jdk11.0.15-macosx_x64", + urls = [ + "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu11.56.19-ca-jdk11.0.15-macosx_x64.tar.gz", + "https://cdn.azul.com/zulu/bin/zulu11.56.19-ca-jdk11.0.15-macosx_x64.tar.gz", + ], + version = "11", + ) + + maybe( + remote_java_repository, + name = "remotejdk11_macos_aarch64", + target_compatible_with = [ + "@platforms//os:macos", + "@platforms//cpu:aarch64", + ], + sha256 = "6bb0d2c6e8a29dcd9c577bbb2986352ba12481a9549ac2c0bcfd00ed60e538d2", + strip_prefix = "zulu11.56.19-ca-jdk11.0.15-macosx_aarch64", + urls = [ + "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu11.56.19-ca-jdk11.0.15-macosx_aarch64.tar.gz", + "https://cdn.azul.com/zulu/bin/zulu11.56.19-ca-jdk11.0.15-macosx_aarch64.tar.gz", + ], + version = "11", + ) + + maybe( + remote_java_repository, + name = "remotejdk11_win", + target_compatible_with = [ + "@platforms//os:windows", + "@platforms//cpu:x86_64", + ], + sha256 = "a106c77389a63b6bd963a087d5f01171bd32aa3ee7377ecef87531390dcb9050", + strip_prefix = "zulu11.56.19-ca-jdk11.0.15-win_x64", + urls = [ + "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu11.56.19-ca-jdk11.0.15-win_x64.zip", + "https://cdn.azul.com/zulu/bin/zulu11.56.19-ca-jdk11.0.15-win_x64.zip", + ], + version = "11", + ) + + maybe( + remote_java_repository, + name = "remotejdk11_win_arm64", + target_compatible_with = [ + "@platforms//os:windows", + "@platforms//cpu:arm64", + ], + sha256 = "b8a28e6e767d90acf793ea6f5bed0bb595ba0ba5ebdf8b99f395266161e53ec2", + strip_prefix = "jdk-11.0.13+8", + urls = [ + "https://mirror.bazel.build/aka.ms/download-jdk/microsoft-jdk-11.0.13.8.1-windows-aarch64.zip", + ], + version = "11", + ) + +def remote_jdk17_repos(): + """Imports OpenJDK 17 repositories.""" + maybe( + remote_java_repository, + name = "remotejdk17_linux", + target_compatible_with = [ + "@platforms//os:linux", + "@platforms//cpu:x86_64", + ], + sha256 = "20c91a922eec795f3181eaa70def8b99d8eac56047c9a14bfb257c85b991df1b", + strip_prefix = "zulu17.38.21-ca-jdk17.0.5-linux_x64", + urls = [ + "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu17.38.21-ca-jdk17.0.5-linux_x64.tar.gz", + "https://cdn.azul.com/zulu/bin/zulu17.38.21-ca-jdk17.0.5-linux_x64.tar.gz", + ], + version = "17", + ) + + maybe( + remote_java_repository, + name = "remotejdk17_linux_aarch64", + target_compatible_with = [ + "@platforms//os:linux", + "@platforms//cpu:aarch64", + ], + sha256 = "dbc6ae9163e7ff469a9ab1f342cd1bc1f4c1fb78afc3c4f2228ee3b32c4f3e43", + strip_prefix = "zulu17.38.21-ca-jdk17.0.5-linux_aarch64", + urls = [ + "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu17.38.21-ca-jdk17.0.5-linux_aarch64.tar.gz", + "https://cdn.azul.com/zulu/bin/zulu17.38.21-ca-jdk17.0.5-linux_aarch64.tar.gz", + ], + version = "17", + ) + + maybe( + remote_java_repository, + name = "remotejdk17_linux_s390x", + target_compatible_with = [ + "@platforms//os:linux", + "@platforms//cpu:s390x", + ], + sha256 = "fdc82f4b06c880762503b0cb40e25f46cf8190d06011b3b768f4091d3334ef7f", + strip_prefix = "jdk-17.0.4.1+1", + urls = [ + "https://mirror.bazel.build/github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.4.1%2B1/OpenJDK17U-jdk_s390x_linux_hotspot_17.0.4.1_1.tar.gz", + "https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.4.1%2B1/OpenJDK17U-jdk_s390x_linux_hotspot_17.0.4.1_1.tar.gz", + ], + version = "17", + ) + + maybe( + remote_java_repository, + name = "remotejdk17_linux_ppc64le", + target_compatible_with = [ + "@platforms//os:linux", + "@platforms//cpu:ppc", + ], + sha256 = "cbedd0a1428b3058d156e99e8e9bc8769e0d633736d6776a4c4d9136648f2fd1", + strip_prefix = "jdk-17.0.4.1+1", + urls = [ + "https://mirror.bazel.build/github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.4.1%2B1/OpenJDK17U-jdk_ppc64le_linux_hotspot_17.0.4.1_1.tar.gz", + "https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.4.1%2B1/OpenJDK17U-jdk_ppc64le_linux_hotspot_17.0.4.1_1.tar.gz", + ], + version = "17", + ) + + maybe( + remote_java_repository, + name = "remotejdk17_macos", + target_compatible_with = [ + "@platforms//os:macos", + "@platforms//cpu:x86_64", + ], + sha256 = "e6317cee4d40995f0da5b702af3f04a6af2bbd55febf67927696987d11113b53", + strip_prefix = "zulu17.38.21-ca-jdk17.0.5-macosx_x64", + urls = [ + "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu17.38.21-ca-jdk17.0.5-macosx_x64.tar.gz", + "https://cdn.azul.com/zulu/bin/zulu17.38.21-ca-jdk17.0.5-macosx_x64.tar.gz", + ], + version = "17", + ) + + maybe( + remote_java_repository, + name = "remotejdk17_macos_aarch64", + target_compatible_with = [ + "@platforms//os:macos", + "@platforms//cpu:aarch64", + ], + sha256 = "515dd56ec99bb5ae8966621a2088aadfbe72631818ffbba6e4387b7ee292ab09", + strip_prefix = "zulu17.38.21-ca-jdk17.0.5-macosx_aarch64", + urls = [ + "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu17.38.21-ca-jdk17.0.5-macosx_aarch64.tar.gz", + "https://cdn.azul.com/zulu/bin/zulu17.38.21-ca-jdk17.0.5-macosx_aarch64.tar.gz", + ], + version = "17", + ) + maybe( + remote_java_repository, + name = "remotejdk17_win", + target_compatible_with = [ + "@platforms//os:windows", + "@platforms//cpu:x86_64", + ], + sha256 = "9972c5b62a61b45785d3d956c559e079d9e91f144ec46225f5deeda214d48f27", + strip_prefix = "zulu17.38.21-ca-jdk17.0.5-win_x64", + urls = [ + "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu17.38.21-ca-jdk17.0.5-win_x64.zip", + "https://cdn.azul.com/zulu/bin/zulu17.38.21-ca-jdk17.0.5-win_x64.zip", + ], + version = "17", + ) + maybe( + remote_java_repository, + name = "remotejdk17_win_arm64", + target_compatible_with = [ + "@platforms//os:windows", + "@platforms//cpu:arm64", + ], + sha256 = "bc3476f2161bf99bc9a243ff535b8fc033b34ce9a2fa4b62fb8d79b6bfdc427f", + strip_prefix = "zulu17.38.21-ca-jdk17.0.5-win_aarch64", + urls = [ + "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu17.38.21-ca-jdk17.0.5-win_aarch64.zip", + "https://cdn.azul.com/zulu/bin/zulu17.38.21-ca-jdk17.0.5-win_aarch64.zip", + ], + version = "17", + ) + +def remote_jdk20_repos(): + """Imports OpenJDK 20 repositories.""" + maybe( + remote_java_repository, + name = "remotejdk20_linux", + target_compatible_with = [ + "@platforms//os:linux", + "@platforms//cpu:x86_64", + ], + sha256 = "0386418db7f23ae677d05045d30224094fc13423593ce9cd087d455069893bac", + strip_prefix = "zulu20.28.85-ca-jdk20.0.0-linux_x64", + urls = [ + "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu20.28.85-ca-jdk20.0.0-linux_x64.tar.gz", + "https://cdn.azul.com/zulu/bin/zulu20.28.85-ca-jdk20.0.0-linux_x64.tar.gz", + ], + version = "20", + ) + + maybe( + remote_java_repository, + name = "remotejdk20_linux_aarch64", + target_compatible_with = [ + "@platforms//os:linux", + "@platforms//cpu:aarch64", + ], + sha256 = "47ce58ead9a05d5d53b96706ff6fa0eb2e46755ee67e2b416925e28f5b55038a", + strip_prefix = "zulu20.28.85-ca-jdk20.0.0-linux_aarch64", + urls = [ + "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu20.28.85-ca-jdk20.0.0-linux_aarch64.tar.gz", + "https://cdn.azul.com/zulu/bin/zulu20.28.85-ca-jdk20.0.0-linux_aarch64.tar.gz", + ], + version = "20", + ) + + maybe( + remote_java_repository, + name = "remotejdk20_macos", + target_compatible_with = [ + "@platforms//os:macos", + "@platforms//cpu:x86_64", + ], + sha256 = "fde6cc17a194ea0d9b0c6c0cb6178199d8edfc282d649eec2c86a9796e843f86", + strip_prefix = "zulu20.28.85-ca-jdk20.0.0-macosx_x64", + urls = [ + "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu20.28.85-ca-jdk20.0.0-macosx_x64.tar.gz", + "https://cdn.azul.com/zulu/bin/zulu20.28.85-ca-jdk20.0.0-macosx_x64.tar.gz", + ], + version = "20", + ) + + maybe( + remote_java_repository, + name = "remotejdk20_macos_aarch64", + target_compatible_with = [ + "@platforms//os:macos", + "@platforms//cpu:aarch64", + ], + sha256 = "a2eff6a940c2df3a2352278027e83f5959f34dcfc8663034fe92be0f1b91ce6f", + strip_prefix = "zulu20.28.85-ca-jdk20.0.0-macosx_aarch64", + urls = [ + "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu20.28.85-ca-jdk20.0.0-macosx_aarch64.tar.gz", + "https://cdn.azul.com/zulu/bin/zulu20.28.85-ca-jdk20.0.0-macosx_aarch64.tar.gz", + ], + version = "20", + ) + maybe( + remote_java_repository, + name = "remotejdk20_win", + target_compatible_with = [ + "@platforms//os:windows", + "@platforms//cpu:x86_64", + ], + sha256 = "ac5f6a7d84dbbb0bb4d376feb331cc4c49a9920562f2a5e85b7a6b4863b10e1e", + strip_prefix = "zulu20.28.85-ca-jdk20.0.0-win_x64", + urls = [ + "https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu20.28.85-ca-jdk20.0.0-win_x64.zip", + "https://cdn.azul.com/zulu/bin/zulu20.28.85-ca-jdk20.0.0-win_x64.zip", + ], + version = "20", + ) + +def rules_java_dependencies(): + """An utility method to load all dependencies of rules_java. + + Loads the remote repositories used by default in Bazel. + """ + + local_jdk_repo() + remote_jdk11_repos() + remote_jdk17_repos() + remote_jdk20_repos() + java_tools_repos() + +def rules_java_toolchains(name = "toolchains"): + """An utility method to load all Java toolchains. + + Args: + name: The name of this macro (not used) + """ + JDKS = { + # Must match JDK repos defined in remote_jdk11_repos() + "11": ["linux", "linux_aarch64", "linux_ppc64le", "linux_s390x", "macos", "macos_aarch64", "win", "win_arm64"], + # Must match JDK repos defined in remote_jdk17_repos() + "17": ["linux", "linux_aarch64", "linux_ppc64le", "linux_s390x", "macos", "macos_aarch64", "win", "win_arm64"], + # Must match JDK repos defined in remote_jdk20_repos() + "20": ["linux", "linux_aarch64", "macos", "macos_aarch64", "win"], + } + + REMOTE_JDK_REPOS = [("remotejdk" + version + "_" + platform) for version in JDKS for platform in JDKS[version]] + + native.register_toolchains("//toolchains:all") + native.register_toolchains("@local_jdk//:runtime_toolchain_definition") + for name in REMOTE_JDK_REPOS: + native.register_toolchains("@" + name + "_toolchain_config_repo//:toolchain") diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..ee8c906 --- /dev/null +++ b/renovate.json @@ -0,0 +1,5 @@ +{ + "extends": [ + "config:base" + ] +} diff --git a/toolchains/BUILD b/toolchains/BUILD new file mode 100644 index 0000000..b8cb35d --- /dev/null +++ b/toolchains/BUILD @@ -0,0 +1,317 @@ +load("@rules_cc//cc:defs.bzl", "cc_library") +load( + ":default_java_toolchain.bzl", + "DEFAULT_TOOLCHAIN_CONFIGURATION", + "PREBUILT_TOOLCHAIN_CONFIGURATION", + "bootclasspath", + "default_java_toolchain", + "java_runtime_files", +) +load( + ":java_toolchain_alias.bzl", + "java_host_runtime_alias", + "java_runtime_alias", + "java_runtime_version_alias", + "java_toolchain_alias", +) + +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +filegroup( + name = "srcs", + srcs = glob(["**"]), +) + +filegroup( + name = "bzl_srcs", + srcs = glob(["*.bzl"]), +) + +# Used to distinguish toolchains used for Java development, ie the JavaToolchainProvider. +# TODO: migrate away from using @bazel_tools//tools/jdk:toolchain_type ? +# toolchain_type(name = "toolchain_type") + +# Used to distinguish toolchains used for Java execution, ie the JavaRuntimeInfo. +# TODO: migrate away from using @bazel_tools//tools/jdk:runtime_toolchain_type ? +# toolchain_type(name = "runtime_toolchain_type") + +# Points to toolchain[":runtime_toolchain_type"] (was :legacy_current_java_runtime) +java_runtime_alias(name = "current_java_runtime") + +# Host configuration of ":current_java_runtime" +java_host_runtime_alias(name = "current_host_java_runtime") + +# Points to toolchain[":toolchain_type"] (was :legacy_current_java_toolchain) +java_toolchain_alias(name = "current_java_toolchain") + +# These individual jni_* targets are exposed for legacy reasons. +# Most users should depend on :jni. + +java_runtime_files( + name = "jni_header", + srcs = ["include/jni.h"], +) + +java_runtime_files( + name = "jni_md_header-darwin", + srcs = ["include/darwin/jni_md.h"], +) + +java_runtime_files( + name = "jni_md_header-linux", + srcs = ["include/linux/jni_md.h"], +) + +java_runtime_files( + name = "jni_md_header-windows", + srcs = ["include/win32/jni_md.h"], +) + +java_runtime_files( + name = "jni_md_header-freebsd", + srcs = ["include/freebsd/jni_md.h"], +) + +java_runtime_files( + name = "jni_md_header-openbsd", + srcs = ["include/openbsd/jni_md.h"], +) + +# The Java native interface. Depend on this package if you #include <jni.h>. +# +# See test_jni in third_party/bazel/src/test/shell/bazel/bazel_java_test.sh for +# an example of using Bazel to build a Java program that calls a C function. +# +# TODO(ilist): use //src:condition:linux when released in Bazel +cc_library( + name = "jni", + hdrs = [":jni_header"] + select({ + "@bazel_tools//src/conditions:darwin": [":jni_md_header-darwin"], + "@bazel_tools//src/conditions:freebsd": [":jni_md_header-freebsd"], + "@bazel_tools//src/conditions:linux_aarch64": [":jni_md_header-linux"], + "@bazel_tools//src/conditions:linux_mips64": [":jni_md_header-linux"], + "@bazel_tools//src/conditions:linux_ppc64le": [":jni_md_header-linux"], + "@bazel_tools//src/conditions:linux_riscv64": [":jni_md_header-linux"], + "@bazel_tools//src/conditions:linux_s390x": [":jni_md_header-linux"], + "@bazel_tools//src/conditions:linux_x86_64": [":jni_md_header-linux"], + "@bazel_tools//src/conditions:openbsd": [":jni_md_header-openbsd"], + "@bazel_tools//src/conditions:windows": [":jni_md_header-windows"], + "//conditions:default": [], + }), + includes = ["include"] + select({ + "@bazel_tools//src/conditions:darwin": ["include/darwin"], + "@bazel_tools//src/conditions:freebsd": ["include/freebsd"], + "@bazel_tools//src/conditions:linux_aarch64": ["include/linux"], + "@bazel_tools//src/conditions:linux_mips64": [":include/linux"], + "@bazel_tools//src/conditions:linux_ppc64le": ["include/linux"], + "@bazel_tools//src/conditions:linux_riscv64": [":include/linux"], + "@bazel_tools//src/conditions:linux_s390x": ["include/linux"], + "@bazel_tools//src/conditions:linux_x86_64": ["include/linux"], + "@bazel_tools//src/conditions:openbsd": ["include/openbsd"], + "@bazel_tools//src/conditions:windows": ["include/win32"], + "//conditions:default": [], + }), + tags = ["nobuilder"], +) + +[ + ( + alias( + name = "ijar_prebuilt_binary_%s" % OS, + actual = "@remote_java_tools_%s//:ijar_prebuilt_binary" % OS, + visibility = ["//visibility:private"], + ), + alias( + name = "prebuilt_singlejar_%s" % OS, + actual = "@remote_java_tools_%s//:prebuilt_singlejar" % OS, + visibility = ["//visibility:private"], + ), + ) + for OS in [ + "linux", + "darwin_x86_64", + "darwin_arm64", + "windows", + ] +] + +# On Windows, executables end in ".exe", but the label we reach it through +# must be platform-independent. Thus, we create a little filegroup that +# contains the appropriate platform-dependent file. +alias( + name = "ijar", + actual = ":ijar_prebuilt_binary_or_cc_binary", +) + +alias( + name = "ijar_prebuilt_binary_or_cc_binary", + actual = select({ + "@bazel_tools//src/conditions:darwin_arm64": ":ijar_prebuilt_binary_darwin_arm64", + "@bazel_tools//src/conditions:darwin_x86_64": ":ijar_prebuilt_binary_darwin_x86_64", + "@bazel_tools//src/conditions:linux_x86_64": ":ijar_prebuilt_binary_linux", + "@bazel_tools//src/conditions:windows": ":ijar_prebuilt_binary_windows", + "//conditions:default": "@remote_java_tools//:ijar_cc_binary", + }), +) + +alias( + name = "ijar_prebuilt_binary", + actual = select({ + "@bazel_tools//src/conditions:darwin_arm64": ":ijar_prebuilt_binary_darwin_arm64", + "@bazel_tools//src/conditions:darwin_x86_64": ":ijar_prebuilt_binary_darwin_x86_64", + "@bazel_tools//src/conditions:linux_x86_64": ":ijar_prebuilt_binary_linux", + "@bazel_tools//src/conditions:windows": ":ijar_prebuilt_binary_windows", + }), +) + +# On Windows, Java implementation of singlejar is used. We create a little +# filegroup that contains the appropriate platform-dependent file. +# Once https://github.com/bazelbuild/bazel/issues/2241 is fixed (that is, +# the native singlejar is used on windows), this file group can be reused since +# on Windows, executables end in ".exe", but the label we reach it through +# must be platform-independent. +alias( + name = "singlejar", + actual = ":singlejar_prebuilt_or_cc_binary", +) + +alias( + name = "singlejar_prebuilt_or_cc_binary", + actual = select({ + "@bazel_tools//src/conditions:darwin_arm64": ":prebuilt_singlejar_darwin_arm64", + "@bazel_tools//src/conditions:darwin_x86_64": ":prebuilt_singlejar_darwin_x86_64", + "@bazel_tools//src/conditions:linux_x86_64": ":prebuilt_singlejar_linux", + "@bazel_tools//src/conditions:windows": ":prebuilt_singlejar_windows", + "//conditions:default": "@remote_java_tools//:singlejar_cc_bin", + }), +) + +alias( + name = "prebuilt_singlejar", + actual = select({ + "@bazel_tools//src/conditions:darwin_arm64": ":prebuilt_singlejar_darwin_arm64", + "@bazel_tools//src/conditions:darwin_x86_64": ":prebuilt_singlejar_darwin_x86_64", + "@bazel_tools//src/conditions:linux_x86_64": ":prebuilt_singlejar_linux", + "@bazel_tools//src/conditions:windows": ":prebuilt_singlejar_windows", + }), +) + +bootclasspath( + name = "platformclasspath", + src = "DumpPlatformClassPath.java", + host_javabase = ":current_java_runtime", + target_javabase = ":current_java_runtime", +) + +default_java_toolchain( + name = "toolchain", + configuration = DEFAULT_TOOLCHAIN_CONFIGURATION, + toolchain_definition = False, +) + +alias( + name = "remote_toolchain", + actual = ":toolchain", +) + +RELEASES = (8, 9, 10, 11) + +[ + default_java_toolchain( + name = "toolchain_java%d" % release, + configuration = DEFAULT_TOOLCHAIN_CONFIGURATION, + source_version = "%s" % release, + target_version = "%s" % release, + ) + for release in RELEASES +] + +# A toolchain that targets java 14. +default_java_toolchain( + name = "toolchain_jdk_14", + configuration = dict(), + java_runtime = "//toolchains:remotejdk_14", + source_version = "14", + target_version = "14", +) + +# A toolchain that targets java 15. +default_java_toolchain( + name = "toolchain_jdk_15", + configuration = dict(), + java_runtime = "//toolchains:remotejdk_15", + source_version = "15", + target_version = "15", +) + +# A toolchain that targets java 16. +default_java_toolchain( + name = "toolchain_jdk_16", + configuration = dict(), + java_runtime = "//toolchains:remotejdk_16", + source_version = "16", + target_version = "16", +) + +# A toolchain that targets java 17. +default_java_toolchain( + name = "toolchain_jdk_17", + configuration = dict(), + java_runtime = "//toolchains:remotejdk_17", + source_version = "17", + target_version = "17", +) + +# A toolchain that targets java 20. +default_java_toolchain( + name = "toolchain_jdk_20", + configuration = dict(), + java_runtime = "//toolchains:remotejdk_20", + source_version = "20", + target_version = "20", +) + +default_java_toolchain( + name = "prebuilt_toolchain", + configuration = PREBUILT_TOOLCHAIN_CONFIGURATION, + toolchain_definition = False, +) + +# A JDK 11 for use as a --host_javabase. +java_runtime_version_alias( + name = "remote_jdk11", + runtime_version = "remotejdk_11", + visibility = ["//visibility:public"], +) + +java_runtime_version_alias( + name = "remotejdk_15", + runtime_version = "remotejdk_15", + visibility = ["//visibility:public"], +) + +java_runtime_version_alias( + name = "remotejdk_16", + runtime_version = "remotejdk_16", + visibility = ["//visibility:public"], +) + +java_runtime_version_alias( + name = "remotejdk_17", + runtime_version = "remotejdk_17", + visibility = ["//visibility:public"], +) + +java_runtime_version_alias( + name = "remotejdk_20", + runtime_version = "remotejdk_20", + visibility = ["//visibility:public"], +) + +java_runtime_version_alias( + name = "jdk_8", + runtime_version = "8", + visibility = ["//visibility:public"], +) diff --git a/toolchains/DumpPlatformClassPath.java b/toolchains/DumpPlatformClassPath.java new file mode 100644 index 0000000..0832853 --- /dev/null +++ b/toolchains/DumpPlatformClassPath.java @@ -0,0 +1,269 @@ +// 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. + +import com.sun.tools.javac.api.JavacTool; +import com.sun.tools.javac.util.Context; +import java.io.BufferedOutputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UncheckedIOException; +import java.lang.reflect.Method; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.EnumSet; +import java.util.GregorianCalendar; +import java.util.List; +import java.util.Map; +import java.util.SortedMap; +import java.util.TreeMap; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.jar.JarOutputStream; +import java.util.zip.CRC32; +import java.util.zip.ZipEntry; +import javax.tools.JavaFileManager; +import javax.tools.JavaFileObject; +import javax.tools.JavaFileObject.Kind; +import javax.tools.StandardJavaFileManager; +import javax.tools.StandardLocation; + +/** + * Output a jar file containing all classes on the platform classpath of the given JDK release. + * + * <p>usage: DumpPlatformClassPath <release version> <output jar> <path to target JDK>? + */ +public class DumpPlatformClassPath { + + public static void main(String[] args) throws Exception { + if (args.length != 2) { + System.err.println("usage: DumpPlatformClassPath <output jar> <path to target JDK>"); + System.exit(1); + } + Path output = Paths.get(args[0]); + Path targetJavabase = Paths.get(args[1]); + + int hostMajorVersion = hostMajorVersion(); + boolean ok; + if (hostMajorVersion == 8) { + ok = dumpJDK8BootClassPath(output, targetJavabase); + } else { + ok = dumpJDK9AndNewerBootClassPath(hostMajorVersion, output, targetJavabase); + } + System.exit(ok ? 0 : 1); + } + + // JDK 8 bootclasspath handling. + // * JDK 8 represents a bootclasspath as a search path of jars (rt.jar, etc.). + // * It does not support --release or --system. + static boolean dumpJDK8BootClassPath(Path output, Path targetJavabase) throws IOException { + List<Path> bootClassPathJars = getBootClassPathJars(targetJavabase); + writeClassPathJars(output, bootClassPathJars); + return true; + } + + // JDK > 8 --host_javabase bootclasspath handling. + // (The default --host_javabase is currently JDK 9.) + static boolean dumpJDK9AndNewerBootClassPath( + int hostMajorVersion, Path output, Path targetJavabase) throws IOException { + + // JDK 9 and newer support cross-compiling to older platform versions using the --system + // and --release flags. + // * --system takes the path to a JDK root for JDK 9 and up, and causes the compilation + // to target the APIs from that JDK. + // * --release takes a language level (e.g. '9') and uses the API information baked in to + // the host JDK (in lib/ct.sym). + + // Since --system only supports JDK >= 9, first check of the target JDK defines a JDK 8 + // bootclasspath. + List<Path> bootClassPathJars = getBootClassPathJars(targetJavabase); + if (!bootClassPathJars.isEmpty()) { + writeClassPathJars(output, bootClassPathJars); + return true; + } + + // Initialize a FileManager to process the --system argument, and then read the + // initialized bootclasspath data back out. + + Context context = new Context(); + try { + JavacTool.create() + .getTask( + /* out = */ null, + /* fileManager = */ null, + /* diagnosticListener = */ null, + /* options = */ Arrays.asList("--system", String.valueOf(targetJavabase)), + /* classes = */ null, + /* compilationUnits = */ null, + context); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException( + String.format( + "Failed to collect system class path. Please ensure that the configured Java runtime" + + " ('%s') is a complete JDK. There are known issues with Homebrew versions of" + + " the Java runtime.", + targetJavabase.toRealPath()), + e); + } + StandardJavaFileManager fileManager = + (StandardJavaFileManager) context.get(JavaFileManager.class); + + SortedMap<String, InputStream> entries = new TreeMap<>(); + for (JavaFileObject fileObject : + fileManager.list( + StandardLocation.PLATFORM_CLASS_PATH, + "", + EnumSet.of(Kind.CLASS), + /* recurse= */ true)) { + String binaryName = + fileManager.inferBinaryName(StandardLocation.PLATFORM_CLASS_PATH, fileObject); + entries.put(binaryName.replace('.', '/') + ".class", fileObject.openInputStream()); + } + writeEntries(output, entries); + return true; + } + + /** Writes the given entry names and data to a jar archive at the given path. */ + private static void writeEntries(Path output, Map<String, InputStream> entries) + throws IOException { + if (!entries.containsKey("java/lang/Object.class")) { + throw new AssertionError( + "\nCould not find java.lang.Object on bootclasspath; something has gone terribly wrong.\n" + + "Please file a bug: https://github.com/bazelbuild/bazel/issues"); + } + try (OutputStream os = Files.newOutputStream(output); + BufferedOutputStream bos = new BufferedOutputStream(os, 65536); + JarOutputStream jos = new JarOutputStream(bos)) { + entries.entrySet().stream() + .forEachOrdered( + entry -> { + try { + addEntry(jos, entry.getKey(), entry.getValue()); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + }); + } + } + + /** Collects the entries of the given jar files into a map from jar entry names to their data. */ + private static void writeClassPathJars(Path output, Collection<Path> paths) throws IOException { + List<JarFile> jars = new ArrayList<>(); + for (Path path : paths) { + jars.add(new JarFile(path.toFile())); + } + SortedMap<String, InputStream> entries = new TreeMap<>(); + for (JarFile jar : jars) { + jar.stream() + .filter(p -> p.getName().endsWith(".class")) + .forEachOrdered( + entry -> { + try { + entries.put(entry.getName(), jar.getInputStream(entry)); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + }); + } + writeEntries(output, entries); + for (JarFile jar : jars) { + jar.close(); + } + } + + /** Returns paths to the entries of a JDK 8-style bootclasspath. */ + private static List<Path> getBootClassPathJars(Path javaHome) throws IOException { + List<Path> jars = new ArrayList<>(); + Path extDir = javaHome.resolve("jre/lib/ext"); + if (Files.exists(extDir)) { + for (Path extJar : Files.newDirectoryStream(extDir, "*.jar")) { + jars.add(extJar); + } + } + for (String jar : + Arrays.asList("rt.jar", "resources.jar", "jsse.jar", "jce.jar", "charsets.jar")) { + Path path = javaHome.resolve("jre/lib").resolve(jar); + if (Files.exists(path)) { + jars.add(path); + } + } + return jars; + } + + // Use a fixed timestamp for deterministic jar output. + private static final long FIXED_TIMESTAMP = + new GregorianCalendar(2010, 0, 1, 0, 0, 0).getTimeInMillis(); + + /** + * Add a jar entry to the given {@link JarOutputStream}, normalizing the entry timestamps to + * ensure deterministic build output. + */ + private static void addEntry(JarOutputStream jos, String name, InputStream input) + throws IOException { + JarEntry je = new JarEntry(name); + je.setTime(FIXED_TIMESTAMP); + je.setMethod(ZipEntry.STORED); + byte[] bytes = toByteArray(input); + // When targeting JDK >= 10, patch the major version so it will be accepted by javac 9 + // TODO(cushon): remove this after updating javac + if (bytes[7] > 53) { + bytes[7] = 53; + } + je.setSize(bytes.length); + CRC32 crc = new CRC32(); + crc.update(bytes); + je.setCrc(crc.getValue()); + jos.putNextEntry(je); + jos.write(bytes); + } + + private static byte[] toByteArray(InputStream is) throws IOException { + byte[] buffer = new byte[8192]; + ByteArrayOutputStream boas = new ByteArrayOutputStream(); + while (true) { + int r = is.read(buffer); + if (r == -1) { + break; + } + boas.write(buffer, 0, r); + } + return boas.toByteArray(); + } + + /** + * Returns the major version of the host Java runtime (e.g. '8' for JDK 8), using {@link + * Runtime#version} if it is available, and otherwise falling back to the {@code + * java.class.version} system. property. + */ + static int hostMajorVersion() { + try { + Method versionMethod = Runtime.class.getMethod("version"); + Object version = versionMethod.invoke(null); + return (int) version.getClass().getMethod("major").invoke(version); + } catch (ReflectiveOperationException e) { + // Runtime.version() isn't available on JDK 8; continue below + } + int version = (int) Double.parseDouble(System.getProperty("java.class.version")); + if (49 <= version && version <= 52) { + return version - (49 - 5); + } + throw new IllegalStateException( + "Unknown Java version: " + System.getProperty("java.specification.version")); + } +} diff --git a/toolchains/default_java_toolchain.bzl b/toolchains/default_java_toolchain.bzl new file mode 100644 index 0000000..9442c5e --- /dev/null +++ b/toolchains/default_java_toolchain.bzl @@ -0,0 +1,289 @@ +# Copyright 2022 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. + +"""Rules for defining default_java_toolchain""" + +load("//java:defs.bzl", "java_toolchain") + +# JVM options, without patching java.compiler and jdk.compiler modules. +BASE_JDK9_JVM_OPTS = [ + # Allow JavaBuilder to access internal javac APIs. + "--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED", + "--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED", + "--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED", + "--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED", + "--add-exports=jdk.compiler/com.sun.tools.javac.resources=ALL-UNNAMED", + "--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED", + "--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED", + "--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED", + "--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED", + "--add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED", + "--add-opens=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED", + + # quiet warnings from com.google.protobuf.UnsafeUtil, + # see: https://github.com/google/protobuf/issues/3781 + # and: https://github.com/bazelbuild/bazel/issues/5599 + "--add-opens=java.base/java.nio=ALL-UNNAMED", + "--add-opens=java.base/java.lang=ALL-UNNAMED", + + # TODO(b/64485048): Disable this option in persistent worker mode only. + # Disable symlinks resolution cache since symlinks in exec root change + "-Dsun.io.useCanonCaches=false", + + # Compact strings make JavaBuilder slightly slower. + "-XX:-CompactStrings", + + # Since https://bugs.openjdk.org/browse/JDK-8153723, JVM logging goes to stdout. This + # makes it go to stderr instead. + "-Xlog:disable", + "-Xlog:all=warning:stderr:uptime,level,tags", +] + +JDK9_JVM_OPTS = BASE_JDK9_JVM_OPTS + +DEFAULT_JAVACOPTS = [ + "-XDskipDuplicateBridges=true", + "-XDcompilePolicy=simple", + "-g", + "-parameters", + # https://github.com/bazelbuild/bazel/issues/15219 + "-Xep:ReturnValueIgnored:OFF", + # https://github.com/bazelbuild/bazel/issues/16996 + "-Xep:IgnoredPureGetter:OFF", + "-Xep:EmptyTopLevelDeclaration:OFF", + "-Xep:LenientFormatStringValidation:OFF", + "-Xep:ReturnMissingNullable:OFF", +] + +# Default java_toolchain parameters +_BASE_TOOLCHAIN_CONFIGURATION = dict( + forcibly_disable_header_compilation = False, + genclass = [Label("@remote_java_tools//:GenClass")], + header_compiler = [Label("@remote_java_tools//:TurbineDirect")], + header_compiler_direct = [Label("@remote_java_tools//:TurbineDirect")], + ijar = [Label("//toolchains:ijar")], + javabuilder = [Label("@remote_java_tools//:JavaBuilder")], + javac_supports_workers = True, + jacocorunner = Label("@remote_java_tools//:jacoco_coverage_runner_filegroup"), + jvm_opts = BASE_JDK9_JVM_OPTS, + turbine_jvm_opts = [ + # Turbine is not a worker and parallel GC is faster for short-lived programs. + "-XX:+UseParallelGC", + ], + misc = DEFAULT_JAVACOPTS, + singlejar = [Label("//toolchains:singlejar")], + # Code to enumerate target JVM boot classpath uses host JVM. Because + # java_runtime-s are involved, its implementation is in @bazel_tools. + bootclasspath = [Label("//toolchains:platformclasspath")], + source_version = "8", + target_version = "8", + reduced_classpath_incompatible_processors = [ + "dagger.hilt.processor.internal.root.RootProcessor", # see b/21307381 + ], + java_runtime = Label("//toolchains:remotejdk_17"), +) + +DEFAULT_TOOLCHAIN_CONFIGURATION = _BASE_TOOLCHAIN_CONFIGURATION + +# The 'vanilla' toolchain is an unsupported alternative to the default. +# +# It does not provide any of the following features: +# * Error Prone +# * Strict Java Deps +# * Reduced Classpath Optimization +# +# It uses the version of internal javac from the `--host_javabase` JDK instead +# of providing a javac. Internal javac may not be source- or bug-compatible with +# the javac that is provided with other toolchains. +# +# However it does allow using a wider range of `--host_javabase`s, including +# versions newer than the current JDK. +VANILLA_TOOLCHAIN_CONFIGURATION = dict( + javabuilder = [Label("@remote_java_tools//:VanillaJavaBuilder")], + jvm_opts = [], + java_runtime = None, +) + +# The new toolchain is using all the pre-built tools, including +# singlejar and ijar, even on remote execution. This toolchain +# should be used only when host and execution platform are the +# same, otherwise the binaries will not work on the execution +# platform. +PREBUILT_TOOLCHAIN_CONFIGURATION = dict( + ijar = [Label("//toolchains:ijar_prebuilt_binary")], + singlejar = [Label("//toolchains:prebuilt_singlejar")], +) + +# The new toolchain is using all the tools from sources. +NONPREBUILT_TOOLCHAIN_CONFIGURATION = dict( + ijar = [Label("@remote_java_tools//:ijar_cc_binary")], + singlejar = [Label("@remote_java_tools//:singlejar_cc_bin")], +) + +_DEFAULT_SOURCE_VERSION = "8" + +def default_java_toolchain(name, configuration = DEFAULT_TOOLCHAIN_CONFIGURATION, toolchain_definition = True, exec_compatible_with = [], target_compatible_with = [], **kwargs): + """Defines a remote java_toolchain with appropriate defaults for Bazel. + + Args: + name: The name of the toolchain + configuration: Toolchain configuration + toolchain_definition: Whether to define toolchain target and its config setting + exec_compatible_with: A list of constraint values that must be + satisifed for the exec platform. + target_compatible_with: A list of constraint values that must be + satisifed for the target platform. + **kwargs: More arguments for the java_toolchain target + """ + + toolchain_args = dict(_BASE_TOOLCHAIN_CONFIGURATION) + toolchain_args.update(configuration) + toolchain_args.update(kwargs) + java_toolchain( + name = name, + **toolchain_args + ) + if toolchain_definition: + source_version = toolchain_args["source_version"] + if source_version == _DEFAULT_SOURCE_VERSION: + native.config_setting( + name = name + "_default_version_setting", + values = {"java_language_version": ""}, + visibility = ["//visibility:private"], + ) + native.toolchain( + name = name + "_default_definition", + toolchain_type = Label("@bazel_tools//tools/jdk:toolchain_type"), + target_settings = [name + "_default_version_setting"], + toolchain = name, + exec_compatible_with = exec_compatible_with, + target_compatible_with = target_compatible_with, + ) + + native.config_setting( + name = name + "_version_setting", + values = {"java_language_version": source_version}, + visibility = ["//visibility:private"], + ) + native.toolchain( + name = name + "_definition", + toolchain_type = Label("@bazel_tools//tools/jdk:toolchain_type"), + target_settings = [name + "_version_setting"], + toolchain = name, + exec_compatible_with = exec_compatible_with, + target_compatible_with = target_compatible_with, + ) + +def java_runtime_files(name, srcs): + """Copies the given sources out of the current Java runtime.""" + + native.filegroup( + name = name, + srcs = srcs, + tags = ["manual"], + ) + for src in srcs: + native.genrule( + name = "gen_%s" % src, + srcs = [Label("//toolchains:current_java_runtime")], + toolchains = [Label("//toolchains:current_java_runtime")], + cmd = "cp $(JAVABASE)/%s $@" % src, + outs = [src], + tags = ["manual"], + ) + +def _bootclasspath_impl(ctx): + host_javabase = ctx.attr.host_javabase[java_common.JavaRuntimeInfo] + + class_dir = ctx.actions.declare_directory("%s_classes" % ctx.label.name) + + args = ctx.actions.args() + args.add("-source") + args.add("8") + args.add("-target") + args.add("8") + args.add("-Xlint:-options") + args.add("-d") + args.add_all([class_dir], expand_directories = False) + args.add(ctx.file.src) + + ctx.actions.run( + executable = "%s/bin/javac" % host_javabase.java_home, + mnemonic = "JavaToolchainCompileClasses", + inputs = [ctx.file.src] + ctx.files.host_javabase, + outputs = [class_dir], + arguments = [args], + ) + + bootclasspath = ctx.outputs.output_jar + + inputs = [class_dir] + ctx.files.host_javabase + + args = ctx.actions.args() + args.add("-XX:+IgnoreUnrecognizedVMOptions") + args.add("--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED") + args.add("--add-exports=jdk.compiler/com.sun.tools.javac.platform=ALL-UNNAMED") + args.add("--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED") + args.add_all("-cp", [class_dir], expand_directories = False) + args.add("DumpPlatformClassPath") + args.add(bootclasspath) + + system_files = ("release", "modules", "jrt-fs.jar") + system = [f for f in ctx.files.target_javabase if f.basename in system_files] + if len(system) != len(system_files): + system = None + if ctx.attr.target_javabase: + inputs.extend(ctx.files.target_javabase) + args.add(ctx.attr.target_javabase[java_common.JavaRuntimeInfo].java_home) + + ctx.actions.run( + executable = str(host_javabase.java_executable_exec_path), + mnemonic = "JavaToolchainCompileBootClasspath", + inputs = inputs, + outputs = [bootclasspath], + arguments = [args], + ) + return [ + DefaultInfo(files = depset([bootclasspath])), + java_common.BootClassPathInfo( + bootclasspath = [bootclasspath], + system = system, + ), + OutputGroupInfo(jar = [bootclasspath]), + ] + +_bootclasspath = rule( + implementation = _bootclasspath_impl, + attrs = { + "host_javabase": attr.label( + cfg = "exec", + providers = [java_common.JavaRuntimeInfo], + ), + "output_jar": attr.output(mandatory = True), + "src": attr.label( + cfg = "exec", + allow_single_file = True, + ), + "target_javabase": attr.label( + providers = [java_common.JavaRuntimeInfo], + ), + }, +) + +def bootclasspath(name, **kwargs): + _bootclasspath( + name = name, + output_jar = name + ".jar", + **kwargs + ) diff --git a/toolchains/fail_rule.bzl b/toolchains/fail_rule.bzl new file mode 100644 index 0000000..a8a3da2 --- /dev/null +++ b/toolchains/fail_rule.bzl @@ -0,0 +1,35 @@ +# Copyright 2020 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. + +"""A rule than fails during analysis.""" + +def _fail_rule_impl(ctx): + if ctx.attr.header: + fail("%s %s" % (ctx.attr.header, ctx.attr.message)) + else: + fail(ctx.attr.message) + +fail_rule = rule( + doc = "A rule that fails during analysis.", + implementation = _fail_rule_impl, + attrs = { + "header": attr.string( + doc = "Header of the message.", + ), + "message": attr.string( + mandatory = True, + doc = "Message to display.", + ), + }, +) diff --git a/toolchains/java_toolchain_alias.bzl b/toolchains/java_toolchain_alias.bzl new file mode 100644 index 0000000..21fae7e --- /dev/null +++ b/toolchains/java_toolchain_alias.bzl @@ -0,0 +1,114 @@ +# Copyright 2019 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. + +"""Experimental re-implementations of Java toolchain aliases using toolchain resolution.""" + +def _java_runtime_alias(ctx): + """An experimental implementation of java_runtime_alias using toolchain resolution.""" + toolchain_info = ctx.toolchains["@bazel_tools//tools/jdk:runtime_toolchain_type"] + toolchain = toolchain_info.java_runtime + return [ + toolchain_info, + toolchain, + platform_common.TemplateVariableInfo({ + "JAVA": str(toolchain.java_executable_exec_path), + "JAVABASE": str(toolchain.java_home), + }), + # See b/65239471 for related discussion of handling toolchain runfiles/data. + DefaultInfo( + runfiles = ctx.runfiles(transitive_files = toolchain.files), + files = toolchain.files, + ), + ] + +java_runtime_alias = rule( + implementation = _java_runtime_alias, + toolchains = ["@bazel_tools//tools/jdk:runtime_toolchain_type"], + incompatible_use_toolchain_transition = True, +) + +def _java_host_runtime_alias(ctx): + """An experimental implementation of java_host_runtime_alias using toolchain resolution.""" + runtime = ctx.attr._runtime + java_runtime = runtime[java_common.JavaRuntimeInfo] + template_variable_info = runtime[platform_common.TemplateVariableInfo] + toolchain_info = platform_common.ToolchainInfo(java_runtime = java_runtime) + return [ + java_runtime, + template_variable_info, + toolchain_info, + runtime[DefaultInfo], + ] + +java_host_runtime_alias = rule( + implementation = _java_host_runtime_alias, + attrs = { + "_runtime": attr.label( + default = Label("//toolchains:current_java_runtime"), + providers = [ + java_common.JavaRuntimeInfo, + platform_common.TemplateVariableInfo, + ], + cfg = "exec", + ), + }, + provides = [ + java_common.JavaRuntimeInfo, + platform_common.TemplateVariableInfo, + platform_common.ToolchainInfo, + ], +) + +def _java_runtime_transition_impl(_settings, attr): + return {"//command_line_option:java_runtime_version": attr.runtime_version} + +_java_runtime_transition = transition( + implementation = _java_runtime_transition_impl, + inputs = [], + outputs = ["//command_line_option:java_runtime_version"], +) + +java_runtime_version_alias = rule( + implementation = _java_runtime_alias, + toolchains = ["@bazel_tools//tools/jdk:runtime_toolchain_type"], + incompatible_use_toolchain_transition = True, + attrs = { + "runtime_version": attr.string(mandatory = True), + "_allowlist_function_transition": attr.label( + default = "@bazel_tools//tools/allowlists/function_transition_allowlist", + ), + }, + cfg = _java_runtime_transition, +) + +def _java_toolchain_alias(ctx): + """An experimental implementation of java_toolchain_alias using toolchain resolution.""" + toolchain_info = ctx.toolchains["@bazel_tools//tools/jdk:toolchain_type"] + toolchain = toolchain_info.java + + # buildifier: disable=rule-impl-return + return struct( + providers = [ + toolchain_info, + toolchain, + ], + # Use the legacy provider syntax for compatibility with the native rules. + java_toolchain = toolchain, + ) + +java_toolchain_alias = rule( + implementation = _java_toolchain_alias, + toolchains = ["@bazel_tools//tools/jdk:toolchain_type"], + incompatible_use_toolchain_transition = True, +) diff --git a/toolchains/jdk_build_file.bzl b/toolchains/jdk_build_file.bzl new file mode 100644 index 0000000..71b615a --- /dev/null +++ b/toolchains/jdk_build_file.bzl @@ -0,0 +1,88 @@ +# Copyright 2023 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. + +"""A templated BUILD file for Java repositories.""" + +JDK_BUILD_TEMPLATE = """load("@rules_java//java:defs.bzl", "java_runtime") + +package(default_visibility = ["//visibility:public"]) + +exports_files(["WORKSPACE", "BUILD.bazel"]) + +filegroup( + name = "jre", + srcs = glob( + [ + "jre/bin/**", + "jre/lib/**", + ], + allow_empty = True, + # In some configurations, Java browser plugin is considered harmful and + # common antivirus software blocks access to npjp2.dll interfering with Bazel, + # so do not include it in JRE on Windows. + exclude = ["jre/bin/plugin2/**"], + ), +) + +filegroup( + name = "jdk-bin", + srcs = glob( + ["bin/**"], + # The JDK on Windows sometimes contains a directory called + # "%systemroot%", which is not a valid label. + exclude = ["**/*%*/**"], + ), +) + +# This folder holds security policies. +filegroup( + name = "jdk-conf", + srcs = glob( + ["conf/**"], + allow_empty = True, + ), +) + +filegroup( + name = "jdk-include", + srcs = glob( + ["include/**"], + allow_empty = True, + ), +) + +filegroup( + name = "jdk-lib", + srcs = glob( + ["lib/**", "release"], + allow_empty = True, + exclude = [ + "lib/missioncontrol/**", + "lib/visualvm/**", + ], + ), +) + +java_runtime( + name = "jdk", + srcs = [ + ":jdk-bin", + ":jdk-conf", + ":jdk-include", + ":jdk-lib", + ":jre", + ], + version = {RUNTIME_VERSION}, +) +""" diff --git a/toolchains/local_java_repository.bzl b/toolchains/local_java_repository.bzl new file mode 100644 index 0000000..ab25f0d --- /dev/null +++ b/toolchains/local_java_repository.bzl @@ -0,0 +1,283 @@ +# Copyright 2021 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. + +"""Rules for importing and registering a local JDK.""" + +load("//java:defs.bzl", "java_runtime") +load(":default_java_toolchain.bzl", "default_java_toolchain") + +def _detect_java_version(repository_ctx, java_bin): + properties_out = repository_ctx.execute([java_bin, "-XshowSettings:properties"]).stderr + # This returns an indented list of properties separated with newlines: + # " java.vendor.url.bug = ... \n" + # " java.version = 11.0.8\n" + # " java.version.date = 2020-11-05\" + + strip_properties = [property.strip() for property in properties_out.splitlines()] + version_property = [property for property in strip_properties if property.startswith("java.version = ")] + if len(version_property) != 1: + return None + + version_value = version_property[0][len("java.version = "):] + parts = version_value.split(".") + major = parts[0] + if len(parts) == 1: + return major + elif major == "1": # handles versions below 1.8 + minor = parts[1] + return minor + return major + +def local_java_runtime(name, java_home, version, runtime_name = None, visibility = ["//visibility:public"], exec_compatible_with = [], target_compatible_with = []): + """Defines a java_runtime target together with Java runtime and compile toolchain definitions. + + Java runtime toolchain is constrained by flag --java_runtime_version having + value set to either name or version argument. + + Java compile toolchains are created for --java_language_version flags values + between 8 and version (inclusive). Java compile toolchains use the same + (local) JDK for compilation. This requires a different configuration for JDK8 + than the newer versions. + + Args: + name: name of the target. + java_home: Path to the JDK. + version: Version of the JDK. + runtime_name: name of java_runtime target if it already exists. + visibility: Visibility that will be applied to the java runtime target + exec_compatible_with: A list of constraint values that must be + satisfied for the exec platform. + target_compatible_with: A list of constraint values that must be + satisfied for the target platform. + """ + + if runtime_name == None: + runtime_name = name + java_runtime( + name = runtime_name, + java_home = java_home, + visibility = visibility, + version = int(version) if version.isdigit() else 0, + ) + + native.config_setting( + name = name + "_name_setting", + values = {"java_runtime_version": name}, + visibility = ["//visibility:private"], + ) + native.config_setting( + name = name + "_version_setting", + values = {"java_runtime_version": version}, + visibility = ["//visibility:private"], + ) + native.config_setting( + name = name + "_name_version_setting", + values = {"java_runtime_version": name + "_" + version}, + visibility = ["//visibility:private"], + ) + native.alias( + name = name + "_settings_alias", + actual = select({ + name + "_name_setting": name + "_name_setting", + name + "_version_setting": name + "_version_setting", + "//conditions:default": name + "_name_version_setting", + }), + visibility = ["//visibility:private"], + ) + native.toolchain( + name = "runtime_toolchain_definition", + target_settings = [":%s_settings_alias" % name], + toolchain_type = Label("@bazel_tools//tools/jdk:runtime_toolchain_type"), + toolchain = runtime_name, + ) + + if type(version) == type("") and version.isdigit() and int(version) > 8: + for version in range(8, int(version) + 1): + default_java_toolchain( + name = name + "_toolchain_java" + str(version), + source_version = str(version), + target_version = str(version), + java_runtime = runtime_name, + exec_compatible_with = exec_compatible_with, + target_compatible_with = target_compatible_with, + ) + + # else version is not recognized and no compilation toolchains are predefined + +def _is_macos(repository_ctx): + return repository_ctx.os.name.lower().find("mac os x") != -1 + +def _is_windows(repository_ctx): + return repository_ctx.os.name.lower().find("windows") != -1 + +def _with_os_extension(repository_ctx, binary): + return binary + (".exe" if _is_windows(repository_ctx) else "") + +def _determine_java_home(repository_ctx): + """Determine the java home path. + + If the `java_home` attribute is specified, then use the given path, + otherwise, try to detect the java home path on the system. + + Args: + repository_ctx: repository context + """ + java_home = repository_ctx.attr.java_home + if java_home: + java_home_path = repository_ctx.path(java_home) + if not java_home_path.exists: + fail('The path indicated by the "java_home" attribute "%s" (absolute: "%s") does not exist.' % (java_home, str(java_home_path))) + return java_home_path + if "JAVA_HOME" in repository_ctx.os.environ: + return repository_ctx.path(repository_ctx.os.environ["JAVA_HOME"]) + + if _is_macos(repository_ctx): + # Replicate GetSystemJavabase() in src/main/cpp/blaze_util_darwin.cc + result = repository_ctx.execute(["/usr/libexec/java_home", "-v", "1.11+"]) + if result.return_code == 0: + return repository_ctx.path(result.stdout.strip()) + else: + # Calculate java home by locating the javac binary + # javac should exists at ${JAVA_HOME}/bin/javac + # Replicate GetSystemJavabase() in src/main/cpp/blaze_util_linux.cc + # This logic should also work on Windows. + javac_path = repository_ctx.which(_with_os_extension(repository_ctx, "javac")) + if javac_path: + return javac_path.realpath.dirname.dirname + return repository_ctx.path("./nosystemjdk") + +def _local_java_repository_impl(repository_ctx): + """Repository rule local_java_repository implementation. + + Args: + repository_ctx: repository context + """ + + java_home = _determine_java_home(repository_ctx) + + # When Bzlmod is enabled, the Java runtime name should be the last segment of the repository name. + local_java_runtime_name = repository_ctx.name.split("~")[-1] + + repository_ctx.file( + "WORKSPACE", + "# DO NOT EDIT: automatically generated WORKSPACE file for local_java_repository\n" + + "workspace(name = \"{name}\")\n".format(name = local_java_runtime_name), + ) + + java_bin = java_home.get_child("bin").get_child(_with_os_extension(repository_ctx, "java")) + + if not java_bin.exists: + # Java binary does not exist + repository_ctx.file( + "BUILD.bazel", + _NOJDK_BUILD_TPL.format( + local_jdk = local_java_runtime_name, + java_binary = _with_os_extension(repository_ctx, "bin/java"), + java_home = java_home, + ), + False, + ) + return + + # Detect version + version = repository_ctx.attr.version if repository_ctx.attr.version != "" else _detect_java_version(repository_ctx, java_bin) + + # Prepare BUILD file using "local_java_runtime" macro + if repository_ctx.attr.build_file_content and repository_ctx.attr.build_file: + fail("build_file and build_file_content are exclusive") + if repository_ctx.attr.build_file_content: + build_file = repository_ctx.attr.build_file_content + elif repository_ctx.attr.build_file: + build_file = repository_ctx.read(repository_ctx.path(repository_ctx.attr.build_file)) + else: + build_file = "" + build_file = build_file.format(RUNTIME_VERSION = version if version.isdigit() else "0") + + runtime_name = '"jdk"' if build_file else None + local_java_runtime_macro = """ +local_java_runtime( + name = "%s", + runtime_name = %s, + java_home = "%s", + version = "%s", +) +""" % (local_java_runtime_name, runtime_name, java_home, version) + + repository_ctx.file( + "BUILD.bazel", + 'load("@rules_java//toolchains:local_java_repository.bzl", "local_java_runtime")\n' + + build_file + + local_java_runtime_macro, + ) + + # Symlink all files + for file in repository_ctx.path(java_home).readdir(): + repository_ctx.symlink(file, file.basename) + +# Build file template, when JDK does not exist +_NOJDK_BUILD_TPL = '''load("@rules_java//toolchains:fail_rule.bzl", "fail_rule") +fail_rule( + name = "jdk", + header = "Auto-Configuration Error:", + message = ("Cannot find Java binary {java_binary} in {java_home}; either correct your JAVA_HOME, " + + "PATH or specify Java from remote repository (e.g. " + + "--java_runtime_version=remotejdk_11)") +) +config_setting( + name = "localjdk_setting", + values = {{"java_runtime_version": "{local_jdk}"}}, + visibility = ["//visibility:private"], +) +toolchain( + name = "runtime_toolchain_definition", + target_settings = [":localjdk_setting"], + toolchain_type = "@bazel_tools//tools/jdk:runtime_toolchain_type", + toolchain = ":jdk", +) +''' + +_local_java_repository_rule = repository_rule( + implementation = _local_java_repository_impl, + local = True, + configure = True, + environ = ["JAVA_HOME"], + attrs = { + "build_file": attr.label(), + "build_file_content": attr.string(), + "java_home": attr.string(), + "version": attr.string(), + }, +) + +def local_java_repository(name, java_home = "", version = "", build_file = None, build_file_content = None, **kwargs): + """Registers a runtime toolchain for local JDK and creates an unregistered compile toolchain. + + Toolchain resolution is constrained with --java_runtime_version flag + having value of the "name" or "version" parameter. + + Java compile toolchains are created for --java_language_version flags values + between 8 and version (inclusive). Java compile toolchains use the same + (local) JDK for compilation. + + If there is no JDK "virtual" targets are created, which fail only when actually needed. + + Args: + name: A unique name for this rule. + java_home: Location of the JDK imported. + build_file: optionally BUILD file template + build_file_content: optional BUILD file template as a string + version: optionally java version + **kwargs: additional arguments for repository rule + """ + _local_java_repository_rule(name = name, java_home = java_home, version = version, build_file = build_file, build_file_content = build_file_content, **kwargs) diff --git a/toolchains/remote_java_repository.bzl b/toolchains/remote_java_repository.bzl new file mode 100644 index 0000000..cbd8b13 --- /dev/null +++ b/toolchains/remote_java_repository.bzl @@ -0,0 +1,88 @@ +# Copyright 2020 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. + +"""Rules for importing and registering JDKs from http archive. + +Rule remote_java_repository imports and registers JDK with the toolchain resolution. +""" + +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") +load("//toolchains:jdk_build_file.bzl", "JDK_BUILD_TEMPLATE") + +def _toolchain_config_impl(ctx): + ctx.file("WORKSPACE", "workspace(name = \"{name}\")\n".format(name = ctx.name)) + ctx.file("BUILD.bazel", ctx.attr.build_file) + +_toolchain_config = repository_rule( + local = True, + implementation = _toolchain_config_impl, + attrs = { + "build_file": attr.string(), + }, +) + +def remote_java_repository(name, version, target_compatible_with = None, prefix = "remotejdk", **kwargs): + """Imports and registers a JDK from a http archive. + + Toolchain resolution is determined with target_compatible_with + parameter and constrained with --java_runtime_version flag either having value + of "version" or "{prefix}_{version}" parameters. + + Args: + name: A unique name for this rule. + version: Version of the JDK imported. + target_compatible_with: Target platform constraints (CPU and OS) for this JDK. + prefix: Optional alternative prefix for configuration flag value used to determine this JDK. + **kwargs: Refer to http_archive documentation + """ + http_archive( + name = name, + build_file_content = JDK_BUILD_TEMPLATE.format(RUNTIME_VERSION = version), + **kwargs + ) + _toolchain_config( + name = name + "_toolchain_config_repo", + build_file = """ +config_setting( + name = "prefix_version_setting", + values = {{"java_runtime_version": "{prefix}_{version}"}}, + visibility = ["//visibility:private"], +) +config_setting( + name = "version_setting", + values = {{"java_runtime_version": "{version}"}}, + visibility = ["//visibility:private"], +) +alias( + name = "version_or_prefix_version_setting", + actual = select({{ + ":version_setting": ":version_setting", + "//conditions:default": ":prefix_version_setting", + }}), + visibility = ["//visibility:private"], +) +toolchain( + name = "toolchain", + target_compatible_with = {target_compatible_with}, + target_settings = [":version_or_prefix_version_setting"], + toolchain_type = "@bazel_tools//tools/jdk:runtime_toolchain_type", + toolchain = "{toolchain}", +) +""".format( + prefix = prefix, + version = version, + target_compatible_with = target_compatible_with, + toolchain = "@{repo}//:jdk".format(repo = name), + ), + ) diff --git a/toolchains/toolchain_utils.bzl b/toolchains/toolchain_utils.bzl new file mode 100644 index 0000000..7177092 --- /dev/null +++ b/toolchains/toolchain_utils.bzl @@ -0,0 +1,58 @@ +# Copyright 2019 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. + +""" +Finds the Java toolchain. + +Returns the toolchain if enabled, and falls back to a toolchain constructed from +legacy toolchain selection. +""" + +def find_java_toolchain(ctx, target): + """ + Finds the Java toolchain. + + If the Java toolchain is in use, returns it. Otherwise, returns a Java + toolchain derived from legacy toolchain selection. + + Args: + ctx: The rule context for which to find a toolchain. + target: A java_toolchain target (for legacy toolchain resolution). + + Returns: + A JavaToolchainInfo. + """ + + _ignore = [ctx] # buildifier: disable=unused-variable + + return target[java_common.JavaToolchainInfo] + +def find_java_runtime_toolchain(ctx, target): + """ + Finds the Java runtime. + + If the Java toolchain is in use, returns it. Otherwise, returns a Java + runtime derived from legacy toolchain selection. + + Args: + ctx: The rule context for which to find a toolchain. + target: A java_runtime target (for legacy toolchain resolution). + + Returns: + A JavaRuntimeInfo. + """ + + _ignore = [ctx] # buildifier: disable=unused-variable + + return target[java_common.JavaRuntimeInfo] |