rules_elide is a Bazel module with Java and Kotlin rules that compile through elide javac and elide kotlinc
running as persistent workers. It downloads Elide itself; no JDK or Kotlin toolchain is needed.
Requirements
| Version | |
|---|---|
| Bazel | 8 or 9, with Bzlmod |
rules_elide | 0.7.0 |
| Elide | 1.6.0-rc.2 (the default) |
| Platforms | Linux x86_64 and arm64, macOS arm64 |
Install
# MODULE.bazel
bazel_dep(name = "rules_elide", version = "0.7.0")
elide = use_extension("@rules_elide//elide:extensions.bzl", "elide")
elide.install(version = "1.6.0-rc.2")
use_repo(elide, "elide_toolchains")
register_toolchains("@elide_toolchains//:all")elide.install() downloads the Elide release for the host and checks it against a pinned hash; version must be one
the module lists. To use an Elide you installed yourself:
elide.use(local_path = "/opt/elide")Rules
Load from @rules_elide//elide:defs.bzl.
| Rule | Does |
|---|---|
elide_java_library | Compiles .java sources into a JAR |
elide_java_binary | Library plus a launcher (bazel run) |
elide_java_test | Library plus a JUnit Platform launcher (bazel test) |
elide_kotlin_library | Compiles .kt and mixed .kt/.java sources |
elide_kotlin_binary, elide_kotlin_test | As the Java variants, for Kotlin |
elide_format | bazel run target that formats sources in place (Java or Kotlin, one per target) |
elide_native_image | Native binary from JVM targets |
Every compile rule returns JavaInfo, so java_library, kt_jvm_library and rules_jvm_external targets mix freely
in deps. Test rules need org.junit.platform:junit-platform-console-standalone in runtime_deps.
Full attribute reference: rules_elide docs.
Example
MODULE.bazel
BUILD.bazel
src/Greeter.java
src/App.kt
src/GreeterTest.java# MODULE.bazel
module(name = "hello")
bazel_dep(name = "rules_elide", version = "0.7.0")
bazel_dep(name = "rules_jvm_external", version = "7.1")
elide = use_extension("@rules_elide//elide:extensions.bzl", "elide")
elide.install(version = "1.6.0-rc.2")
use_repo(elide, "elide_toolchains")
register_toolchains("@elide_toolchains//:all")
maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")
maven.install(
artifacts = [
"org.junit.jupiter:junit-jupiter-api:5.13.4",
"org.junit.platform:junit-platform-console-standalone:1.13.4",
],
)
use_repo(maven, "maven")# BUILD.bazel
load("@rules_elide//elide:defs.bzl", "elide_java_library", "elide_java_test", "elide_kotlin_binary")
elide_java_library(
name = "greeter",
srcs = ["src/Greeter.java"],
)
elide_kotlin_binary(
name = "app",
srcs = ["src/App.kt"],
main_class = "AppKt",
deps = [":greeter"],
)
elide_java_test(
name = "greeter_test",
srcs = ["src/GreeterTest.java"],
test_class = "GreeterTest",
runtime_deps = ["@maven//:org_junit_platform_junit_platform_console_standalone"],
deps = [
":greeter",
"@maven//:org_junit_jupiter_junit_jupiter_api",
],
)bazel build //...
bazel run //:app
bazel test //:greeter_testINFO: 35 processes: 12 internal, 16 linux-sandbox, 7 worker.
INFO: Build completed successfully, 35 total actions
Hello, Bazel
//:greeter_test PASSED in 2.0s
Executed 1 out of 1 test: 1 test passes.Persistent workers
The compile rules run elide javac --persistent_worker and elide kotlinc --persistent_worker: one warm process per
tool serves every compile action, accepting concurrent requests and compiling them one at a time. bazel shutdown
stops them.
To compile each target in a new process (for example under remote execution):
bazel build --@rules_elide//elide:use_workers=false //...Workers from your own rules
Without rules_elide, any rule can run Elide as a worker. Bazel adds --persistent_worker itself; the rule passes
arguments in a parameter file:
# elide.bzl
def _elide_javac_impl(ctx):
out = ctx.actions.declare_directory(ctx.label.name + "_classes")
args = ctx.actions.args()
args.add("-d", out.path)
args.add_all(ctx.files.srcs)
args.use_param_file("@%s", use_always = True)
args.set_param_file_format("multiline")
ctx.actions.run(
executable = ctx.executable._elide,
arguments = ["javac", args],
inputs = ctx.files.srcs,
outputs = [out],
mnemonic = "ElideJavac",
execution_requirements = {"supports-workers": "1", "supports-multiplex-workers": "1"},
)
return [DefaultInfo(files = depset([out]))]
elide_javac = rule(
implementation = _elide_javac_impl,
attrs = {
"srcs": attr.label_list(allow_files = [".java"]),
"_elide": attr.label(default = "//tools:elide", executable = True, cfg = "exec", allow_single_file = True),
},
)# BUILD.bazel
load(":elide.bzl", "elide_javac")
elide_javac(
name = "hello",
srcs = glob(["src/*.java"]),
)mkdir -p tools && ln -s "$(command -v elide)" tools/elide
echo 'exports_files(["elide"])' > tools/BUILD.bazel
bazel build //:helloTarget //:hello up-to-date:
bazel-bin/hello_classes
INFO: 2 processes: 1 internal, 1 worker.For javac, pass ["javac", "--classpath-cache", args] to reuse parsed classpath JARs between requests. A kotlinc
rule takes the same form, without --classpath-cache.
Keep kt_jvm_* targets
register_elide_kotlin_toolchain from @rules_elide//elide/kotlin:toolchain.bzl replaces the builder of a
rules_kotlin toolchain, so existing kt_jvm_library, kt_jvm_binary and kt_jvm_test targets compile with Elide
without BUILD changes. Targets with annotation processors fall back to the stock rules_kotlin builder. Setup:
KotlinBuilder shim.
OpenRewrite and dependency queries
For projects with an elide.pkl, see OpenRewrite and
Dependency code index. These commands do not consume Bazel’s JavaInfo or its target
graph, and the rules listed above do not add a rewrite or code-index target. See
the project setup boundary before using them alongside Bazel.
Limits
- Windows is not supported.
elide.installaccepts only versions listed in the module; useelide.usefor others.- Kotlin compiler plugins from external JARs (the
pluginsattribute ofelide_kotlin_*rules) other than all-open, no-arg, sam-with-receiver, assignment and Lombok fail with a compiler error.