Перейти к содержимому

Bazel

Компилируйте, тестируйте и форматируйте Java и Kotlin в Bazel с rules_elide, замените билдер rules_kotlin или вызывайте elide javac и elide kotlinc как постоянные воркеры из своих правил.

На этой странице

rules_elide — модуль Bazel с правилами для Java и Kotlin, которые компилируют через elide javac и elide kotlinc, запущенные как постоянные воркеры. Он сам скачивает Elide; ни JDK, ни инструментарий Kotlin не нужны.

Требования

Версия
Bazel8 или 9, с Bzlmod
rules_elide0.7.0
Elide1.6.0-rc.2 (по умолчанию)
ПлатформыLinux x86_64 и arm64, macOS arm64

Установка

# 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() скачивает выпуск Elide для хоста и сверяет его с закреплённым хешем; version должна быть из списка модуля. Чтобы использовать Elide, установленный вами:

elide.use(local_path = "/opt/elide")

Правила

Загружайте их из @rules_elide//elide:defs.bzl.

ПравилоЧто делает
elide_java_libraryКомпилирует исходники .java в JAR
elide_java_binaryБиблиотека плюс лаунчер (bazel run)
elide_java_testБиблиотека плюс лаунчер JUnit Platform (bazel test)
elide_kotlin_libraryКомпилирует исходники .kt и смешанные .kt/.java
elide_kotlin_binary, elide_kotlin_testКак варианты для Java, но для Kotlin
elide_formatЦель для bazel run, которая форматирует исходники на месте (Java или Kotlin, один язык на цель)
elide_native_imageНативный бинарный файл из целей JVM

Каждое правило компиляции возвращает JavaInfo, поэтому цели java_library, kt_jvm_library и rules_jvm_external свободно смешиваются в deps. Правилам тестов нужен org.junit.platform:junit-platform-console-standalone в runtime_deps.

Полный справочник атрибутов: документация rules_elide.

Пример

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_test
INFO: 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.

Постоянные воркеры

Правила компиляции запускают elide javac --persistent_worker и elide kotlinc --persistent_worker: один прогретый процесс на инструмент обслуживает все действия компиляции, принимает параллельные запросы и компилирует их по одному. bazel shutdown их останавливает.

Чтобы компилировать каждую цель в новом процессе (например, при удалённом выполнении):

bazel build --@rules_elide//elide:use_workers=false //...

Воркеры из своих правил

Без rules_elide любое правило может запускать Elide как воркер. Bazel сам добавляет --persistent_worker; правило передаёт аргументы в файле параметров:

# 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 //:hello
Target //:hello up-to-date:
  bazel-bin/hello_classes
INFO: 2 processes: 1 internal, 1 worker.

Для javac передайте ["javac", "--classpath-cache", args], чтобы повторно использовать разобранные JAR из classpath между запросами. Правило для kotlinc устроено так же, но без --classpath-cache.

Сохранение целей kt_jvm_*

register_elide_kotlin_toolchain из @rules_elide//elide/kotlin:toolchain.bzl заменяет билдер в инструментарии rules_kotlin, поэтому существующие цели kt_jvm_library, kt_jvm_binary и kt_jvm_test компилируются с Elide без изменений в файлах BUILD. Цели с процессорами аннотаций возвращаются к стандартному билдеру rules_kotlin. Настройка: прослойка KotlinBuilder.

OpenRewrite и запросы к зависимостям

Для проектов с elide.pkl см. OpenRewrite и Индекс кода зависимостей. Эти команды не используют JavaInfo из Bazel и его граф целей, а перечисленные выше правила не добавляют целей для рефакторинга или индекса кода. Прежде чем использовать их рядом с Bazel, прочитайте о границе настройки проекта.

Ограничения

  • Windows не поддерживается.
  • elide.install принимает только версии из списка модуля; для остальных используйте elide.use.
  • Плагины компилятора Kotlin из внешних JAR (атрибут plugins правил elide_kotlin_*), кроме all-open, no-arg, sam-with-receiver, assignment и Lombok, завершаются ошибкой компилятора.

Была ли эта страница полезной?