[英]How to use different bootclasspaths in Bazel workspace?
I'm currently trying to build a Bazel 0.11.1 workspace with projects that use different Java language levels. 我目前正在尝试使用使用不同Java语言级别的项目构建Bazel 0.11.1工作区。 The actual application uses Java 7, but for some code that won't ship, I want to settle with a more recent Java version to be able to use the new language features.
实际的应用程序使用Java 7,但是对于某些无法交付的代码,我希望使用较新的Java版本才能使用新的语言功能。
I can solve this to some extent by using --javacopt
in .bazelrc
, setting -source 1.7 -target 1.7
and override the defaults on a project level with the javacopts
attribute, but this is not enough to ensure proper Java 7 compatibility when compiling with a more recent Java version. 我可以通过在
.bazelrc
使用--javacopt
,设置-source 1.7 -target 1.7
并在项目级别使用javacopts
属性覆盖默认值来在某种程度上解决此问题,但这不足以确保在使用最新的Java版本。 For this I really need to compile Java 7 projects against a Java 7 classpath as well. 为此,我确实还需要针对Java 7类路径编译Java 7项目。
The only way to use a custom bootclasspath seems to be via java_toolchain
. 使用自定义
java_toolchain
的唯一方法似乎是通过java_toolchain
。 It works. 有用。 But I could not found a way to use different bootclasspaths for different projects, because the toolchain affects all projects and unlike with
javacopts
cannot be overridden at the project level. 但是我找不到用于不同项目的不同
javacopts
方法,因为该工具链会影响所有项目,并且与javacopts
不同,该工具链无法在项目级别覆盖。
Is this a usecase that is simply not (yet?) possible with Bazel? 这是Bazel无法(还可以)使用的用例吗? Or is there some trickery to make it work?
还是有一些使它起作用的技巧?
It turns out there is a way: write a custom rule that performs compilation. 事实证明,有一种方法:编写执行编译的自定义规则。
The java_common
module provides an interface to the compiler. 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"],
)
This rule I can now use to set a different toolchain for compilation. 我现在可以使用此规则来设置不同的工具链进行编译。
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 = ["..."],
)
Unfortunately I'm not 100% there yet. 不幸的是,我还不是100%。
java_common.compile
does not seem to have an equivalent for the data
attribute of java_library
, but for the most part the toolchain problem is solved. java_common.compile
似乎与java_library
的data
属性没有等效项,但是在大多数情况下,工具链问题已解决。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.