rules_rs is both a wrapper around rules_rust and an alternative implementation for selected parts of the Rust + Bazel stack.
It is designed to:
- Reuse stable
rules_rustfunctionality, such as the core compilation rules. - Provide alternative implementations where there is a benefit to be gained (
crate_universe-style dependency resolution and toolchain provisioning). - Let users migrate incrementally while still reusing selected
rules_rustcomponents (for example toolchains).
- Extremely fast (~200ms) incremental dependency resolution via Bazel downloader integration and lockfile facts. Uses your Cargo lockfile directly. No "Cargo workspace splicing", no Bazel-specific Cargo lockfile.
- Toolchains are more flexible, powerful, and lightweight. We don't register any toolchains by default, but with a 1-line
register_toolchainscall you can have a working setup for the entire cross-product of supported exec and target triples. The support matrix is wider than rules_rust, we support multiple ABIs per OS (-msvc, -gnu, and -gnullvm on Windows, -gnu and -musl on Linux). We bring fully hermetic-musl,-gnullvm, and OSX linker runtimes thanks to @llvm module, so you can do full cross builds from any host platform to any target platform, including with remote execution. (OSX host, linux remote executor, Windows gnullvm target works seamlessly). See PR #21 for more details. - The patched
rules_rustextension provides all underlying rules_rust functionality with many fixes applied (Windows linking works now, various rust-analyzer improvements, etc.)
bazel_dep(name = "rules_rs", version = "0.0.33")Recommended: use rules_rs rule wrappers.
You can still use rules_rust rule definitions while doing a gradual migration, but using
rules_rs all the way saves you from having to refer to both.
Example BUILD.bazel using rules_rs wrappers:
load("@rules_rs//rs:rust_library.bzl", "rust_library")
load("@rules_rs//rs:rust_binary.bzl", "rust_binary")
load("@crates//:defs.bzl", "aliases", "all_crate_deps")
rust_library(
name = "lib",
srcs = ["src/lib.rs"],
aliases = aliases(),
deps = all_crate_deps(normal = True),
)
rust_binary(
name = "app",
srcs = ["src/main.rs"],
deps = [":lib"],
)For migration details, see Migration.
Strongly recommended: use rules_rs toolchains.
You can still use rules_rust toolchains when doing a gradual migration, but that should be considered a compatibility on-ramp rather than the default.
toolchains = use_extension("@rules_rs//rs/experimental/toolchains:module_extension.bzl", "toolchains")
toolchains.toolchain(
edition = "2024",
version = "1.92.0",
)
use_repo(toolchains, "default_rust_toolchains")
register_toolchains("@default_rust_toolchains//:all")Make sure you set use_experimental_platforms = True in crate.from_cargo(...).
When using rules_rust toolchains with rules_rs, first provision rules_rust via the
rules_rs extension, then configure toolchains from @rules_rust:
rules_rust = use_extension("@rules_rs//rs/experimental:rules_rust.bzl", "rules_rust")
use_repo(rules_rust, "rules_rust")
rust = use_extension("@rules_rust//rust:extensions.bzl", "rust")
rust.toolchain(
edition = "2024",
versions = ["1.92.0"],
)
use_repo(rust, "rust_toolchains")
register_toolchains("@rust_toolchains//:all")In this mode, keep use_experimental_platforms = False (the default) in crate.from_cargo(...).
rules_rs uses its own crate_universe implementation through crate.from_cargo:
crate = use_extension("@rules_rs//rs:extensions.bzl", "crate")
crate.from_cargo(
name = "crates",
cargo_lock = "//:Cargo.lock",
cargo_toml = "//:Cargo.toml",
platform_triples = [
"aarch64-apple-darwin",
"aarch64-unknown-linux-gnu",
"x86_64-apple-darwin",
"x86_64-unknown-linux-gnu",
],
# True when using rules_rs experimental toolchains/platforms.
# False (default) when using rules_rust toolchains/platforms.
use_experimental_platforms = True,
)
use_repo(crate, "crates")crate.spec and vendoring mode are currently unsupported.
- Windows: the default Windows exec toolchain is MSVC-flavored. The upstream
gnullvmtoolchain dynamically linkslibunwind, which may not exist on a stock Windows machine. - If you target
*-pc-windows-gnullvm, resolve both triples in dependency resolution (crate.from_cargo): one MSVC triple for exec/build-script/proc-macro work and onegnullvmtriple for target artifacts. - Linux: similarly, when targeting
*-unknown-linux-musl, also include the corresponding*-unknown-linux-gnutriple for exec. Proc macros and build scripts run in exec configuration, and Linux exec toolchains are GNU. This is required because the@llvmtoolchain currently cannot produce musl-flavored proc-macro.soartifacts, and the proc macro ABI must match the rustc ABI.
Example platform_triples values:
# Windows gnullvm target with MSVC exec.
platform_triples = [
"x86_64-pc-windows-msvc", # exec
"x86_64-pc-windows-gnullvm", # target
]
# Linux musl target with GNU exec.
platform_triples = [
"x86_64-unknown-linux-gnu", # exec
"x86_64-unknown-linux-musl", # target
]TODO(zbarsky): Should we issue warnings if you configure the triples in an unexpected way?
rules_rs exports a rules_rust module extension you can use to provision the pinned rules_rust repo:
rules_rust = use_extension("@rules_rs//rs/experimental:rules_rust.bzl", "rules_rust")
# Optional: apply additional patches to the pinned rules_rust archive.
rules_rust.patch(
patches = ["//:my_rules_rust_fix.patch"],
strip = 1,
)
use_repo(rules_rust, "rules_rust")The core compilation rules (rust_library, rust_binary, rust_test, rust_proc_macro, rust_static_library, and rust_dynamic_library) can be loaded directly from @rules_rs//rs:*.bzl but clippy integration, protobuf, etc come from rules_rust for now.
If you import rules_rust via this extension, existing load("@rules_rust//...") statements can be kept as-is during migration.
Using this extension is STRONGLY ENCOURAGED because it carries fixes that improve Windows behavior, rust-analyzer integration, and related compatibility work.
In addition, when using the rules_rs toolchains, loading the compilation rules from @rules_rs directly and using the extension is REQUIRED for toolchain resolution to work correctly, at least until bazelbuild/rules_rust#3857 is accepted by rules_rust maintainers. See the Migration section for more info.
For reliable toolchain resolution, ABI choices should be explicit on every platform participating in your build, including the host platform.
Linux and Windows each have ABI variants that affect toolchain matching (gnu/musl on Linux, msvc/gnu/gnullvm on Windows). Implicit/default platforms lacking these constraints will result in toolchain resolution errors, as no toolchains will match.
At minimum, set an explicit --host_platform that adds your ABI constraint on top of @platforms//host:
.bazelrc:
common:linux --host_platform=//platforms:local_gnu
common:windows --host_platform=//platforms:local_windows_msvc
platforms/BUILD.bazel:
# Host platform with an explicit Linux GNU ABI choice.
platform(
name = "local_gnu",
parents = ["@platforms//host"],
constraint_values = [
"@llvm//constraints/libc:gnu.2.28",
],
)
# Host platform with an explicit Windows ABI choice.
platform(
name = "local_windows_msvc",
parents = ["@platforms//host"],
constraint_values = [
"@rules_rs//rs/experimental/platforms/constraints:windows_msvc",
],
)Set host ABI constraints to match your exec toolchain choice; handle target ABI differences via target platforms and platform_triples.
For remote execution platforms, you can inherit from a triple-based platform published in @rules_rs//rs/experimental/platforms and then layer exec properties:
platform(
name = "rbe_linux_amd64_gnu",
parents = ["@rules_rs//rs/experimental/platforms:x86_64-unknown-linux-gnu"],
exec_properties = {
"container-image": "docker://ghcr.io/example/rbe-linux-gnu:latest",
},
)If you import rules_rust via the extension above, you can keep existing @rules_rust loads unchanged.
For long-term hygiene, it is still recommended to migrate loads to @rules_rs//rs:* wrappers at some point.
A sample migration script is provided at scripts/rewrite_rules_rust_loads.sh. It rewrites common @rules_rust Rust loads to @rules_rs//rs:* wrappers and then formats with buildifier.
./scripts/rewrite_rules_rust_loads.sh- OpenAI Codex
- Aspect CLI
- Datadog Agent
- ZML
- rules_py
- JetBrains, used in closed sources of JetBrains Air especially
This ruleset collects limited usage data via tools_telemetry, which is reported to Aspect Build Inc and governed by their privacy policy.