rules_graalvm

GraalVM Rules for Bazel

CI Contributor Covenant Bazel 7 Bzlmod


Latest release: 0.12.0

Important Currently in beta. Feedback welcome but will probably break your build.

Use GraalVM from Bazel, with support for:

Installation

API docs for graalvm_repository

Via WORKSPACE.bazel:

Artifact SHA256
rules_graalvm-0.12.0.zip ``
rules_graalvm-0.12.0.tgz ``
http_archive(
    name = "rules_graalvm",
    sha256 = "",
    strip_prefix = "rules_graalvm-0.12.0",
    urls = [
        "https://github.com/sgammon/rules_graalvm/releases/download/v0.12.0/rules_graalvm-0.12.0.zip",
    ],
)
load("@rules_graalvm//graalvm:workspace.bzl", "register_graalvm_toolchains", "rules_graalvm_repositories")

rules_graalvm_repositories()

register_graalvm_toolchains()
load("@rules_graalvm//graalvm:repositories.bzl", "graalvm_repository")
graalvm_repository(
    name = "graalvm",
    distribution = "ce",  # `oracle`, `ce`, or `community`
    java_version = "23",  # `17`, `20`, `22`, `23`, etc.
    version = "23.0.0",  # pass graalvm or specific jdk version supported by gvm
)

Or, via MODULE.bazel:

Artifact Integrity value
rules_graalvm-0.12.0.zip ``
rules_graalvm-0.12.0.tgz ``
bazel_dep(name = "rules_graalvm", version = "0.12.0")
gvm = use_extension("@rules_graalvm//:extensions.bzl", "graalvm")

gvm.graalvm(
    name = "graalvm",
    version = "23.0.0",  # pass graalvm or specific jdk version supported by gvm
    distribution = "ce",  # `oracle`, `ce`, or `community`
    java_version = "23",  # `17`, `20`, `22`, `23`, etc.
)
use_repo(gvm, "graalvm")
register_toolchains("@graalvm//:jvm")
register_toolchains("@graalvm//:sdk")

Usage

These rules are documented; you can find important docs at these links:

Java Toolchains

You can use the graalvm_repository as a Java toolchain, by registering it like below:

From WORKSPACE.bazel:

# graalvm_repository(...)
load("@rules_graalvm//graalvm:workspace.bzl", "register_graalvm_toolchains", "rules_graalvm_repositories")
rules_graalvm_repositories()

register_graalvm_toolchains()

To use the toolchain, add this to your .bazelrc:

build --extra_toolchains=@graalvm//:toolchain
build --java_runtime_version=graalvm_20

Read more in the Toolchain Guide.

Build a native binary on Bazel 6+

API docs for native_image

In a BUILD.bazel file:

load("@rules_java//java:defs.bzl", "java_library")
load("@rules_graalvm//graalvm:defs.bzl", "native_image")

java_library(
    name = "main",
    srcs = glob(["Main.java"]),
)

native_image(
    name = "main-native",
    deps = [":main"],
    main_class = "Main",
    native_image_tool = "@graalvm//:native-image",
)

Native image toolchains

It is supported to specify the native-image tool as above, using the native_image_tool attribute on your target. In fact, you must do this unless you register the GraalVM toolchains as shown in the installation instructions.

When using toolchains, the native_image_tool attribute can be omitted, which delegates to Bazel’s toolchain system to resolve the tool:

Resolve via toolchains:

native_image(
    name = "main-native",
    deps = [":main"],
    main_class = "Main",
)

Or point to a specific native-image tool:

native_image(
    name = "main-native",
    deps = [":main"],
    main_class = "Main",
    native_image_tool = "@graalvm//:native-image",
)

Build a native binary on Bazel 4 and Bazel 5

API docs for legacy native_image rule

In a BUILD.bazel file:

load("@rules_java//java:defs.bzl", "java_library")
load("@rules_graalvm//graal:graal.bzl", "native_image")

java_library(
    name = "main",
    srcs = glob(["Main.java"]),
)

native_image(
    name = "main-native",
    deps = [":main"],
    main_class = "Main",
)

Note: In the legacy rules, you don’t have to specify native_image_tool, but on the other hand, the default target @graalvm//:native-image is hard-coded in. If you use a different repository name make sure to add the native_image_tool attribute to point to @yourrepo//:native-image.

Examples

See the list of examples, which are used as continuous integration tests. Examples are available for Bazel 4-7.

Hermeticity / strictness

These rules attempt to strike as optimal a balance as possible between older Bazel support (starting at Bazel 4) and the maximum possible strictness/hermeticity for action execution.

Bazel Toolchains are used to resolve the C++ compiler which is provided to native-image. Toolchains are additionally used within the rules to provide and resolve tools from GraalVM itself.

For information about strictness tuning on each operating system, see the hermeticity guide.

GraalVM toolchain type

The GraalVM-specific toolchain type is available at:

@rules_graalvm//graalvm/toolchain:toolchain_type

If you install GraalVM at a repository named @graalvm, the toolchain targets are:

Java toolchain:

@graalvm//:jvm

GraalVM toolchain:

@graalvm//:sdk

The default WORKSPACE and Bzlmod installation instructions register both types of toolchains. The GraalVM toolchain is required to perform builds with native-image (or you must provide a native_image_tool target).

Acknowledgements

Built on top of @andyscott’s fantastic work with rules_graal.