Sh4d1/zut

★ 0Forks 0ZigGitHub ↗Compare

README

zut

A hermetic, incremental, content-addressed build system in Zig —
with Rust and Zig as first-class languages.

CI Docs License


⚠️ Early and experimental. The design is settled; APIs, the Starlark dialect, and the CLI still change. Not yet production-ready.

zut is a from-scratch build system in the spirit of Bazel and Buck2 — its own Starlark front-end, content-addressed store, sandboxed executor, and incremental engine — built in Zig 0.16. A rust_binary can depend on a zig_library and vice versa, linked over the C ABI, built hermetically and cached per action.

Why

  • Correct by construction — a build's output is a pure function of its declared inputs. Undeclared inputs are made physically unavailable by the sandbox, so "works on my machine" becomes a build error, not a mystery.
  • Fine-grained incrementality — the cache unit is the action, not the target. Change one file, rebuild exactly what depended on it.
  • Content-addressed caching — identical work never runs twice, locally or across a team via a shared remote cache (S3 / GCS / a shared dir / your own).
  • Rust & Zig as peers — neither is a second-class bolt-on.
  • Remote-ready — the execution path is shaped like the Bazel Remote Execution API, so remote caching (today) and remote execution (later) drop in.
  • Extensible — rules like rust_binary are Starlark definitions over primitives, not hardcoded into the engine.

Quick start

Requires Zig 0.16.0.

$ git clone https://github.com/Sh4d1/zut && cd zut
$ zig build -Doptimize=ReleaseFast      # → zig-out/bin/zut
$ zig build test --summary all          # run the test suite

A minimal workspace — a Rust binary linking a Zig static library:

# BUILD
load("@builtin//:rust.bzl", "rust_binary")
load("@builtin//:zig.bzl", "zig_library")

zig_library(name = "greet", src = "greet.zig", libname = "greet")

rust_binary(
    name = "hello",
    crate_root = "src/main.rs",
    srcs = ["src/main.rs"],
    edition = "2021",
    out = "hello",
    native_deps = [":greet"],
)
$ zut build //:hello       # builds into ./zut-out/, caches every action
$ zut test  //:hello_test  # runs the test binary as a cached action
$ zut fetch Cargo.lock     # vendor crates.io deps into the CAS (the only networked step)

See the zut Book for the full guide: getting started, configuration, remote caching, sandboxing, and writing BUILD files.

Remote caching

Back the local caches with a shared store — --remote-cache=<spec> or remote-cache = <spec> in .zutrc:

Spec Backend
fs:///mnt/cache a shared directory (NFS, local)
s3://bucket?region=eu-west-3 native S3 / S3-compatible (MinIO, R2) — hand-rolled SigV4
gs://bucket native Google Cloud Storage (OAuth2 bearer)
cmd:/path/to/helper bring your own store via a get|put|has helper

The S3 and GCS clients are standalone in-tree Zig SDKs — no AWS/GCP SDK or CLI dependency. Details: remote caching.

Documentation

Contributing

Contributions are welcome — see CONTRIBUTING.md. In short: build with zig build, keep zig build test --summary all green, use the internal logger (never std.debug.print), and read docs/ARCHITECTURE.md first.

License

Licensed under either of

at your option. Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Contributors

Sh4d1

Issues