ziglang/zig
Build system
Active contributors: andrewrk, mlugg, alexrp, jakub-konka
Purpose
Zig's build system is implemented entirely in Zig, lives inside the standard library at lib/std/Build.zig and lib/std/Build/, and is consumed by every project's build.zig. The zig binary embeds a build runner (lib/compiler/build_runner.zig, ~78 KB) that, for zig build, compiles the project's build.zig against std.Build and runs the resulting graph.
Directory layout
lib/std/Build.zig # `std.Build` (~101 KB) — the user-facing API
lib/std/Build/
├── Cache.zig # content-addressed build cache (~61 KB)
├── Cache/ # cache helpers
├── Fuzz.zig # fuzzer integration (~22 KB)
├── Module.zig # the `Module` type (~27 KB)
├── Step.zig # the `Step` base + tags (~38 KB)
├── Step/ # concrete step types
├── Watch.zig # filesystem watcher for `--watch`
├── WebServer.zig # the `zig build --listen` HTTP server
└── abi.zig # ABI helpers consumed by Module
lib/compiler/build_runner.zig # the program embedded in `zig build`
lib/compiler/test_runner.zig # the program embedded by `zig test`Key abstractions
| Type | File | Description |
|---|---|---|
Build |
lib/std/Build.zig |
The root context: knows the host/target, options, install prefix, and the step graph. |
Step |
lib/std/Build/Step.zig |
A unit of work in the graph. Subtypes live in lib/std/Build/Step/ (e.g. Compile, Run, WriteFile, Fmt, InstallArtifact, InstallFile, Options, CheckObject, ConfigHeader). |
Module |
lib/std/Build/Module.zig |
A compilable Zig module with imports, target, optimize mode, and link options. |
Cache |
lib/std/Build/Cache.zig |
Content-addressed cache. Hashes inputs to a manifest; reuses outputs across runs. |
Watch |
lib/std/Build/Watch.zig |
OS-level filesystem watcher used by zig build --watch. |
Fuzz |
lib/std/Build/Fuzz.zig |
Integration with the in-tree fuzzer (lib/fuzzer.zig). |
WebServer |
lib/std/Build/WebServer.zig |
HTTP UI for zig build --listen (used to drive watch mode and emit progress). |
Flow of a zig build
sequenceDiagram
actor User
User->>+zig: zig build <step>
zig->>+build_runner: spawn (compiled with project build.zig)
build_runner->>+std.Build: b = Build.create(...)
build_runner->>+project: build.zig:build(b)
project-->>-std.Build: registers Steps, Modules, Options
build_runner->>+std.Build.Cache: hash(inputs)
std.Build.Cache-->>-build_runner: cache hit/miss
alt cache miss
build_runner->>+std.Build.Step: run requested step
std.Build.Step->>+zig: invoke `zig` for compile/test/fmt/...
zig-->>-std.Build.Step: artifact
end
std.Build.Step-->>-build_runner: success
build_runner-->>-User: exit codebuild_runner is itself a Zig program. When you run zig build, the compiler:
- Compiles
build.zigtogether withlib/compiler/build_runner.ziginto a transient executable. - Invokes that executable with the user's CLI arguments.
- The runner constructs a
std.Buildand calls the project'sbuild(b: *std.Build). - The runner walks the step graph, hashing each step's inputs through
std.Build.Cache. - Cache misses are run; cache hits are reused. Watch mode and the web server keep this loop running on file events.
Step types (selected)
lib/std/Build/Step/ contains:
Compile.zig— produce an executable, library, or object.Run.zig— run a binary (often a previousCompile's output).WriteFile.zig— write generated files into the build cache.Fmt.zig— runzig fmt.Options.zig— surface user options as a generated Zig source file.InstallArtifact.zig,InstallFile.zig,InstallDir.zig— install into the prefix.CheckObject.zig— assert on object-file structure (used bytest/link/).ConfigHeader.zig— generateconfig.h-style files.RemoveDir.zig,Translate-C.zig,ObjCopy.zig,CheckFile.zig— assorted utilities.
The complete list lives in the directory. Step.zig enumerates the tag union.
Cache
std.Build.Cache content-addresses every step's inputs (source files, env, options, dependent steps). The cache directory is what zig env reports as cache_dir. Hits skip work entirely; misses recompile.
Watch and listen
--watchuseslib/std/Build/Watch.zig(kqueue/inotify/Windows) to re-run affected steps on file change.--listenexposeslib/std/Build/WebServer.zig, which streams progress and lets a UI (or the editor) drive rebuilds.
Integration points
- Compiler. Each
Compilestep shells out to the samezigbinary, which takes the same path aszig build-exeetc. - Test runner.
zig testis implemented bylib/compiler/test_runner.zig, invoked byStep.Run. - Package manager. Dependencies in
build.zig.zonare fetched once into the global cache and exposed asModules throughb.dependency(...). - Fuzzer.
Fuzz.zigwires steps tolib/fuzzer.zig.
Entry points for modification
- New step type. Add
lib/std/Build/Step/<Name>.zig, register the tag inlib/std/Build/Step.zig, and expose a constructor onstd.Build. - New build option. Add it to
std.Build.standard*Optionsinlib/std/Build.zig. - Watch behavior.
lib/std/Build/Watch.zigis the OS-level entry point. - Cache key.
lib/std/Build/Cache.zigand theStep.ManifestAPI.
Key source files
| File | Purpose |
|---|---|
lib/std/Build.zig |
The std.Build root API. |
lib/std/Build/Step.zig |
Base Step and step tag union. |
lib/std/Build/Step/ |
All concrete step types. |
lib/std/Build/Module.zig |
The Module type. |
lib/std/Build/Cache.zig |
Content-addressed cache. |
lib/std/Build/Watch.zig |
File watcher for --watch. |
lib/std/Build/WebServer.zig |
--listen HTTP server. |
lib/std/Build/Fuzz.zig |
Fuzzing integration. |
lib/compiler/build_runner.zig |
The runner embedded in zig build. |
lib/compiler/test_runner.zig |
The runner embedded in zig test. |
build.zig |
The Zig project's own build.zig (a heavy real-world example). |
See also Package manager for how dependencies feed into the build graph.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.