The built-in prelude
zut ships a set of canonical Rust and Zig rules inside the binary. Load them
from the @builtin// namespace — no files to vendor, and a workspace file named
rust.bzl can never shadow the built-in one:
load("@builtin//:rust.bzl", "rust_binary", "rust_library", "rust_test")
load("@builtin//:zig.bzl", "zig_library")
These rules are ordinary Starlark (see the source:
src/rules/rust.bzl,
src/rules/zig.bzl)
— read them as worked examples of writing rules. The
host toolchain comes from ctx.toolchain.rust / ctx.toolchain.zig.
Rust rules
rust_library
Compiles an .rlib and propagates the transitive rlib/dylib closure for
downstream linking.
| Attribute | Meaning |
|---|---|
crate_name | the crate’s import name |
crate_root | entry .rs compiled by rustc |
srcs | all source files (materialized so mod resolves) |
edition | e.g. "2021" |
deps | other rust_library targets (linked via --extern + transitive rlibs) |
macros | rust_proc_macro targets (loaded at compile time) |
native_deps | zig_library (or similar) targets, linked as static libs |
build_script | optional rust_build_script (its cfg directives + OUT_DIR codegen) |
rust_binary
Same dependency model as rust_library, plus an out attribute for the
executable name. Returns DefaultInfo.
rust_test
Like rust_binary but compiled with --test; run as a cached action by
zut test.
Vendored crates.io rules
crate_library and crate_proc_macro are what zut fetch
generates into //crates/BUILD. Their source comes from a checksum-pinned CAS
Tree grafted with src_tree = crate_tree("<name> <ver>", mount), and features
become --cfg feature="x". You normally depend on these (//crates:serde)
rather than writing them by hand.
Zig rules
zig_library
Builds a static library (lib<name>.a) with zig build-lib -fPIC, ready for a
rust_binary to link via native_deps.
| Attribute | Meaning |
|---|---|
src | the Zig root source file |
libname | base name (→ lib<libname>.a, linked as -l static=<libname>) |
A combined example
load("@builtin//:rust.bzl", "rust_binary")
load("@builtin//:zig.bzl", "zig_library")
zig_library(name = "mathz", src = "math.zig", libname = "mathz")
rust_binary(
name = "app",
crate_root = "src/main.rs",
srcs = ["src/main.rs"],
edition = "2021",
out = "app",
native_deps = [":mathz"], # Rust ↔ Zig via the C ABI
deps = ["//crates:serde"], # a fetched crates.io dependency
)
This is the headline feature: Rust and Zig composed as peers in one graph, built hermetically and cached per action.