Skip to content

Commit

Permalink
Copybara Merge: #114
Browse files Browse the repository at this point in the history
BEGIN_PUBLIC
Copybara import of the project:

--
cb82ccb by Fabian Meumertzheim <fabian@meumertzhe.im>:

Obtain bootstrap class path from dedicated runtime toolchain type

This decouples the concepts of a Java runtime used to run on the target
platform from the Java runtime that provides the bootstrap class path
used during compilation.

The former needs constraints on the target platform, whereas the latter
should not have any constraints on the target platform to allow for
cross-compilation to target platforms for which a JDK runtime is not
available (e.g. Android).

Work towards #17085
Work towards #64
Split off from #18262

--
ab3c792 by Fabian Meumertzheim <fabian@meumertzhe.im>:

Register toolchains in MODULE.bazel

--
f2218a4 by Fabian Meumertzheim <fabian@meumertzhe.im>:

Update Bazel to 7.0.0-pre.20230710.5

--
0294790 by Fabian Meumertzheim <fabian@meumertzhe.im>:

Add missing WORKSPACE `register_toolchains` calls

END_PUBLIC

COPYBARA_INTEGRATE_REVIEW=#114 from fmeum:17085-bootstrap-toolchain 0294790
PiperOrigin-RevId: 554446834
Change-Id: I961944be5bfe461528e94c85247f6c36236a561d
  • Loading branch information
fmeum authored and copybara-github committed Aug 7, 2023
1 parent ca72739 commit ea0bd91
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 23 deletions.
1 change: 1 addition & 0 deletions .bazelversion
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
7.0.0-pre.20230710.5
7 changes: 5 additions & 2 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ use_repo(toolchains, "remote_java_tools_darwin_arm64")
# Declare local jdk repo
use_repo(toolchains, "local_jdk")

register_toolchains("@local_jdk//:runtime_toolchain_definition")
register_toolchains(
"@local_jdk//:runtime_toolchain_definition",
"@local_jdk//:bootstrap_runtime_toolchain_definition",
)

# Declare all remote jdk toolchain config repos
JDKS = {
Expand Down Expand Up @@ -70,7 +73,7 @@ REMOTE_JDK_REPOS = [("remotejdk" + version + "_" + platform) for version in JDKS
repo + "_toolchain_config_repo",
) for repo in REMOTE_JDK_REPOS]

[register_toolchains("@" + name + "_toolchain_config_repo//:toolchain") for name in REMOTE_JDK_REPOS]
[register_toolchains("@" + name + "_toolchain_config_repo//:all") for name in REMOTE_JDK_REPOS]

# Dev dependencies
bazel_dep(name = "rules_pkg", version = "0.5.1", dev_dependency = True)
12 changes: 9 additions & 3 deletions java/repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,13 @@ def rules_java_toolchains(name = "toolchains"):

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")
native.register_toolchains(
"//toolchains:all",
"@local_jdk//:runtime_toolchain_definition",
"@local_jdk//:bootstrap_runtime_toolchain_definition",
)
for name in REMOTE_JDK_REPOS:
native.register_toolchains("@" + name + "_toolchain_config_repo//:toolchain")
native.register_toolchains(
"@" + name + "_toolchain_config_repo//:toolchain",
"@" + name + "_toolchain_config_repo//:bootstrap_runtime_toolchain",
)
49 changes: 45 additions & 4 deletions toolchains/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,56 @@ filegroup(
srcs = glob(["*.bzl"]),
)

# Used to distinguish toolchains used for Java development, ie the JavaToolchainProvider.
# A single binary distribution of a JDK (e.g., OpenJDK 17 for Windows arm64) provides three
# different types of toolchains from the perspective of Bazel:

# The compilation toolchain, which provides the Java runtime used to execute the Java compiler, as
# well as various helper tools and settings.
#
# Toolchains of this type typically have constraints on the execution platform so that their Java
# runtime can run the compiler, but not on the target platform as Java compilation outputs are
# platform independent.
#
# Obtain the associated JavaToolchainInfo via:
# ctx.toolchains["@bazel_tools//tools/jdk:toolchain_type"].java
# 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.
# The Java runtime that executable Java compilation outputs (e.g., java_binary with
# create_executable = True) will run on.
#
# Toolchains of this type typically have constraints on the target platform so that the runtime's
# native 'java' binary can be run there, but not on the execution platform as building an executable
# Java target only requires copying or symlinking the runtime, which can be done on any platform.
#
# Obtain the associated JavaRuntimeInfo via:
# ctx.toolchains["@bazel_tools//tools/jdk:runtime_toolchain_type"].java_runtime
# TODO: migrate away from using @bazel_tools//tools/jdk:runtime_toolchain_type ?
# toolchain_type(name = "runtime_toolchain_type")

# The Java runtime to extract the bootclasspath from that is then used to compile Java sources.
#
# As the bootclasspath is platform independent, toolchains of this type may have no constraints.
# Purely as an optimization to prevent unnecessary fetches of remote runtimes for other
# architectures, toolchains of this type may have constraints on the execution platform that match
# those on the corresponding compilation toolchain.
#
# Toolchains of this type are only consumed internally by the bootclasspath rule and should not be
# accessed from Starlark.
# TODO: migrate away from using @bazel_tools//tools/jdk:bootstrap_runtime_toolchain_type ?
# toolchain_type(name = "bootstrap_runtime_toolchain_type")

# The Java runtime to extract the bootclasspath from that is then used to compile Java sources.
#
# As the bootclasspath is platform independent, toolchains of this type may have no constraints.
# Purely as an optimization to prevent unnecessary fetches of remote runtimes for other
# architectures, toolchains of this type may have constraints on the execution platform that match
# those on the corresponding compilation toolchain.
#
# Toolchains of this type are only consumed internally by the bootclasspath rule and should not be
# accessed from Starlark.
# toolchain_type(name = "bootstrap_runtime_toolchain_type")

# Points to toolchain[":runtime_toolchain_type"] (was :legacy_current_java_runtime)
java_runtime_alias(name = "current_java_runtime")

Expand Down Expand Up @@ -201,8 +243,7 @@ alias(
bootclasspath(
name = "platformclasspath",
src = "DumpPlatformClassPath.java",
host_javabase = ":current_java_runtime",
target_javabase = ":current_java_runtime",
java_runtime_alias = ":current_java_runtime",
)

default_java_toolchain(
Expand Down
27 changes: 13 additions & 14 deletions toolchains/default_java_toolchain.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,10 @@ def java_runtime_files(name, srcs):
tags = ["manual"],
)

_JAVA_BOOTSTRAP_RUNTIME_TOOLCHAIN_TYPE = Label("@bazel_tools//tools/jdk:bootstrap_runtime_toolchain_type")

def _bootclasspath_impl(ctx):
host_javabase = ctx.attr.host_javabase[java_common.JavaRuntimeInfo]
exec_javabase = ctx.attr.java_runtime_alias[java_common.JavaRuntimeInfo]

class_dir = ctx.actions.declare_directory("%s_classes" % ctx.label.name)

Expand All @@ -220,17 +222,15 @@ def _bootclasspath_impl(ctx):
args.add(ctx.file.src)

ctx.actions.run(
executable = "%s/bin/javac" % host_javabase.java_home,
executable = "%s/bin/javac" % exec_javabase.java_home,
mnemonic = "JavaToolchainCompileClasses",
inputs = [ctx.file.src] + ctx.files.host_javabase,
inputs = [ctx.file.src] + ctx.files.java_runtime_alias,
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")
Expand All @@ -240,16 +240,17 @@ def _bootclasspath_impl(ctx):
args.add("DumpPlatformClassPath")
args.add(bootclasspath)

any_javabase = ctx.toolchains[_JAVA_BOOTSTRAP_RUNTIME_TOOLCHAIN_TYPE].java_runtime
args.add(any_javabase.java_home)

system_files = ("release", "modules", "jrt-fs.jar")
system = [f for f in ctx.files.target_javabase if f.basename in system_files]
system = [f for f in any_javabase.files.to_list() 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)

inputs = depset([class_dir] + ctx.files.java_runtime_alias, transitive = [any_javabase.files])
ctx.actions.run(
executable = str(host_javabase.java_executable_exec_path),
executable = str(exec_javabase.java_executable_exec_path),
mnemonic = "JavaToolchainCompileBootClasspath",
inputs = inputs,
outputs = [bootclasspath],
Expand All @@ -267,7 +268,7 @@ def _bootclasspath_impl(ctx):
_bootclasspath = rule(
implementation = _bootclasspath_impl,
attrs = {
"host_javabase": attr.label(
"java_runtime_alias": attr.label(
cfg = "exec",
providers = [java_common.JavaRuntimeInfo],
),
Expand All @@ -276,10 +277,8 @@ _bootclasspath = rule(
cfg = "exec",
allow_single_file = True,
),
"target_javabase": attr.label(
providers = [java_common.JavaRuntimeInfo],
),
},
toolchains = [_JAVA_BOOTSTRAP_RUNTIME_TOOLCHAIN_TYPE],
)

def bootclasspath(name, **kwargs):
Expand Down
12 changes: 12 additions & 0 deletions toolchains/local_java_repository.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,12 @@ def local_java_runtime(name, java_home, version, runtime_name = None, visibility
toolchain_type = Label("@bazel_tools//tools/jdk:runtime_toolchain_type"),
toolchain = runtime_name,
)
native.toolchain(
name = "bootstrap_runtime_toolchain_definition",
target_settings = [":%s_settings_alias" % name],
toolchain_type = Label("@bazel_tools//tools/jdk:bootstrap_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):
Expand Down Expand Up @@ -253,6 +259,12 @@ toolchain(
toolchain_type = "@bazel_tools//tools/jdk:runtime_toolchain_type",
toolchain = ":jdk",
)
toolchain(
name = "bootstrap_runtime_toolchain_definition",
target_settings = [":localjdk_setting"],
toolchain_type = "@bazel_tools//tools/jdk:bootstrap_runtime_toolchain_type",
toolchain = ":jdk",
)
'''

_local_java_repository_rule = repository_rule(
Expand Down
10 changes: 10 additions & 0 deletions toolchains/remote_java_repository.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@ toolchain(
toolchain_type = "@bazel_tools//tools/jdk:runtime_toolchain_type",
toolchain = "{toolchain}",
)
toolchain(
name = "bootstrap_runtime_toolchain",
# These constraints are not required for correctness, but prevent fetches of remote JDK for
# different architectures. As every Java compilation toolchain depends on a bootstrap runtime in
# the same configuration, this constraint will not result in toolchain resolution failures.
exec_compatible_with = {target_compatible_with},
target_settings = [":version_or_prefix_version_setting"],
toolchain_type = "@bazel_tools//tools/jdk:bootstrap_runtime_toolchain_type",
toolchain = "{toolchain}",
)
""".format(
prefix = prefix,
version = version,
Expand Down

0 comments on commit ea0bd91

Please sign in to comment.