如何在 Bazel 工作区中使用不同的引导类路径?
How to use different bootclasspaths in Bazel workspace?
我目前正在尝试构建一个 Bazel 0.11.1 工作区,其中包含使用不同 Java 语言级别的项目。实际应用程序使用 Java 7,但对于某些无法发布的代码,我想使用更新的 Java 版本来解决,以便能够使用新的语言功能。
我可以在一定程度上解决这个问题,方法是在 .bazelrc
中使用 --javacopt
,设置 -source 1.7 -target 1.7
并使用 javacopts
属性覆盖项目级别的默认值,但是在使用更新的 Java 版本编译时,这不足以确保适当的 Java 7 兼容性。为此,我确实需要针对 Java 7 个类路径编译 Java 7 个项目。
使用自定义引导类路径的唯一方法似乎是通过 java_toolchain
。有用。但是我找不到为不同的项目使用不同的引导类路径的方法,因为工具链影响所有项目并且与 javacopts
不同,不能在项目级别覆盖。
这是 Bazel 根本不可能(还?)的用例吗?还是有什么技巧可以让它发挥作用?
原来有一个方法:写一个执行编译的自定义规则。
java_common
模块为编译器提供接口。
library.bzl
def _impl(ctx):
deps = []
for dep in ctx.attr.deps:
if java_common.provider in dep:
deps.append(dep[java_common.provider])
output_jar = ctx.new_file("lib{0}.jar".format(ctx.label.name))
runtime = java_common.JavaRuntimeInfo
compilation_provider = java_common.compile(
ctx,
source_jars = ctx.files.srcs_jars,
source_files = ctx.files.srcs,
output = output_jar,
javac_opts = ctx.attr.javac_opts,
deps = deps,
strict_deps = ctx.attr.strict_deps,
java_toolchain = ctx.attr.toolchain,
host_javabase = ctx.attr._host_javabase,
resources = ctx.files.resources,
neverlink = ctx.attr.neverlink,
)
return struct(
files = depset([output_jar]),
providers = [compilation_provider],
)
library = rule(
implementation = _impl,
attrs = {
"srcs_jars": attr.label_list(allow_files=True),
"srcs": attr.label_list(allow_files=True),
"javac_opts": attr.string_list(default=[]),
"deps": attr.label_list(),
"strict_deps": attr.string(default="ERROR"),
"toolchain": attr.label(default=Label("@bazel_tools//tools/jdk:toolchain")),
"sourcepath": attr.label_list(),
"resources": attr.label_list(),
"neverlink": attr.bool(default=False),
"_host_javabase": attr.label(default=Label("@local_jdk//:jdk")),
},
fragments = ["java"],
)
我现在可以使用这条规则来设置不同的编译工具链。
BUILD
load('//build/jdk:library.bzl', 'library')
library(
name = "test",
srcs = glob(["src/main/java/**/*.java"]),
# data = glob(["src/main/resources/**"]),
toolchain = "//build/jdk:jdk8",
deps = ["..."],
)
不幸的是,我还没有 100% 达到目标。 java_common.compile
似乎没有 java_library
的 data
属性的等价物,但大部分工具链问题已解决。
我目前正在尝试构建一个 Bazel 0.11.1 工作区,其中包含使用不同 Java 语言级别的项目。实际应用程序使用 Java 7,但对于某些无法发布的代码,我想使用更新的 Java 版本来解决,以便能够使用新的语言功能。
我可以在一定程度上解决这个问题,方法是在 .bazelrc
中使用 --javacopt
,设置 -source 1.7 -target 1.7
并使用 javacopts
属性覆盖项目级别的默认值,但是在使用更新的 Java 版本编译时,这不足以确保适当的 Java 7 兼容性。为此,我确实需要针对 Java 7 个类路径编译 Java 7 个项目。
使用自定义引导类路径的唯一方法似乎是通过 java_toolchain
。有用。但是我找不到为不同的项目使用不同的引导类路径的方法,因为工具链影响所有项目并且与 javacopts
不同,不能在项目级别覆盖。
这是 Bazel 根本不可能(还?)的用例吗?还是有什么技巧可以让它发挥作用?
原来有一个方法:写一个执行编译的自定义规则。
java_common
模块为编译器提供接口。
library.bzl
def _impl(ctx):
deps = []
for dep in ctx.attr.deps:
if java_common.provider in dep:
deps.append(dep[java_common.provider])
output_jar = ctx.new_file("lib{0}.jar".format(ctx.label.name))
runtime = java_common.JavaRuntimeInfo
compilation_provider = java_common.compile(
ctx,
source_jars = ctx.files.srcs_jars,
source_files = ctx.files.srcs,
output = output_jar,
javac_opts = ctx.attr.javac_opts,
deps = deps,
strict_deps = ctx.attr.strict_deps,
java_toolchain = ctx.attr.toolchain,
host_javabase = ctx.attr._host_javabase,
resources = ctx.files.resources,
neverlink = ctx.attr.neverlink,
)
return struct(
files = depset([output_jar]),
providers = [compilation_provider],
)
library = rule(
implementation = _impl,
attrs = {
"srcs_jars": attr.label_list(allow_files=True),
"srcs": attr.label_list(allow_files=True),
"javac_opts": attr.string_list(default=[]),
"deps": attr.label_list(),
"strict_deps": attr.string(default="ERROR"),
"toolchain": attr.label(default=Label("@bazel_tools//tools/jdk:toolchain")),
"sourcepath": attr.label_list(),
"resources": attr.label_list(),
"neverlink": attr.bool(default=False),
"_host_javabase": attr.label(default=Label("@local_jdk//:jdk")),
},
fragments = ["java"],
)
我现在可以使用这条规则来设置不同的编译工具链。
BUILD
load('//build/jdk:library.bzl', 'library')
library(
name = "test",
srcs = glob(["src/main/java/**/*.java"]),
# data = glob(["src/main/resources/**"]),
toolchain = "//build/jdk:jdk8",
deps = ["..."],
)
不幸的是,我还没有 100% 达到目标。 java_common.compile
似乎没有 java_library
的 data
属性的等价物,但大部分工具链问题已解决。