如何在Bazel中定义本地Java工具链



我想为我的Java构建使用一个特定的Azul-Zulu JDK。因此,我已将其存储在本地存储库中,例如tools/zulu19.30.11-ca-jdk19.0.1-macosx_x64下。现在我想配置一个java工具链目标,这样我就可以通过--java_toolchain=//tools:my_custom_java_toolchain传递它。我不想依赖一些远程存储库。

实现这一目标需要采取哪些步骤?

我已找到此存储库:https://github.com/salesforce/bazel-jdt-java-toolchain/blob/main/jdt/defs.bzl它定义了类型为CCD_ 3的目标,但我不能导出对我的用例有用的东西。例如,我不知道字段header_compiler是什么意思。我天真的假设是,我只需要传递一些路径到java编译所需的工具(如bin/javac(。

我当前的方法使用规则java_toolchainjava_runtime。我的BUILD文件如下:

java_runtime(
name = "zulu19.30.11-ca-jdk19.0.1-macosx_x64",
srcs = glob(["zulu19.30.11-ca-jdk19.0.1-macosx_x64/**"]),
java_home = "zulu19.30.11-ca-jdk19.0.1-macosx_x64",
)
java_toolchain(
name = "zulu-19",
source_version = "19",
target_version = "19",
java_runtime = ":zulu19.30.11-ca-jdk19.0.1-macosx_x64",
javabuilder = "",
ijar = "",
singlejar = "",
genclass = "",
)

我正在尝试执行命令:bazel build --extra_toolchains="//tools:zulu-19" //:ProjectRunner,它抱怨缺少强制属性javabuilderijarsinglejargenclass,但我不知道哪些是正确的路径或值。

我只是想知道bazel怎么知道如何用这些信息编译java代码。例如,为什么我不必指定javac

基本上,我想出了以下解决方案,它似乎解决了我的问题,并受到规则default_java_toolchain的启发。我使用了@bazel_tools//tools/jdk中定义的javabuilderijarsinglejargenclass的现有目标。请注意,我必须使用BASE_JDK9_JVM_OPTS才能成功构建。

load("@bazel_tools//tools/jdk:default_java_toolchain.bzl", "BASE_JDK9_JVM_OPTS")
java_runtime(
name = "zulu19.30.11-ca-jdk19.0.1-macosx_x64",
srcs = glob(["zulu19.30.11-ca-jdk19.0.1-macosx_x64/**"]),
java_home = "zulu19.30.11-ca-jdk19.0.1-macosx_x64",
)
config_setting(
name = "zulu-19-runtime_version_setting",
values = {"java_runtime_version": "19"},
visibility = ["//visibility:private"],
)
toolchain(
name = "zulu-19_runtime_toolchain_definition",
target_settings = ["zulu-19-runtime_version_setting"],
toolchain_type = "@bazel_tools//tools/jdk:runtime_toolchain_type",
toolchain = "zulu19.30.11-ca-jdk19.0.1-macosx_x64",
)
java_toolchain(
name = "zulu-19",
source_version = "19",
target_version = "19",
java_runtime = ":zulu19.30.11-ca-jdk19.0.1-macosx_x64",
jvm_opts = BASE_JDK9_JVM_OPTS,
javabuilder = ["@bazel_tools//tools/jdk:javabuilder"],
ijar = ["@bazel_tools//tools/jdk:ijar"],
singlejar = ["@bazel_tools//tools/jdk:singlejar"],
genclass = ["@bazel_tools//tools/jdk:genclass"],
)
config_setting(
name = "zulu-19_version_setting",
values = {"java_language_version": "19"},
visibility = ["//visibility:private"],
)
toolchain(
name = "zulu-19_toolchain_definition",
toolchain_type = "@bazel_tools//tools/jdk:toolchain_type",
target_settings = ["zulu-19_version_setting"],
toolchain = "zulu-19",
)

以下命令现在成功运行,没有任何错误。System.out.println(Runtime.version());还打印正确的版本。

bazel run --extra_toolchains="//tools:zulu-19_toolchain_definition,//tools:zulu-19_runtime_toolchain_definition" --java_language_version="19" --java_runtime_version="19" //:ProjectRunner

但我仍然有几个问题,例如为什么需要javabuilderijarsinglejargenclass,以及这些目标的目的是什么?工具链目标如何了解我的javac二进制文件以编译java代码?为什么我必须使用BASE_JDK9_JVM_OPTS才能成功构建,并且我可以省略一些设置吗?

最新更新