पाठ 19 / 25
build.zig: Builds as Zig Code
Define executables, libraries, steps and options in build.zig.
No Make, no CMake: just Zig
A Zig project's build is described by build.zig, a Zig program whose build function receives a *std.Build and declares a graph of steps. You create modules (b.createModule with a root source file, target and optimisation mode), then artifacts: b.addExecutable, b.addLibrary (static or dynamic) and b.addTest. b.installArtifact copies outputs to zig-out/. Steps (b.step("run", ...)) appear as commands: zig build run, zig build test. b.standardTargetOptions and b.standardOptimizeOption add the -Dtarget and -Doptimize flags, and b.option defines custom options (-Dwith-metrics=true) that can be passed to code through build options modules. Builds are cached and parallel, and steps can run arbitrary tools, generate code, or compile C sources (addCSourceFiles). Because it is real code, conditional logic and reuse are easy, and the same build works on every platform without external tools. The build API changes between releases (for example, executables now take a root_module), so start from the template zig init produces for your version.
The build graph
build.zig declares steps; zig build runs the ones you ask for, in dependency order.
A build.zig with run and test steps
Zig 0.15-style build script with a custom option.
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const enable_metrics = b.option(bool, "metrics", "Enable metrics collection") orelse false;
const options = b.addOptions();
options.addOption(bool, "enable_metrics", enable_metrics);
const exe_module = b.createModule(.{
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
exe_module.addOptions("build_options", options); // @import("build_options") in code
const exe = b.addExecutable(.{
.name = "invoices",
.root_module = exe_module,
});
b.installArtifact(exe); // zig-out/bin/invoices
const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| run_cmd.addArgs(args); // zig build run -- --month 9
const run_step = b.step("run", "Run the invoice tool");
run_step.dependOn(&run_cmd.step);
const unit_tests = b.addTest(.{ .root_module = exe_module });
const run_tests = b.addRunArtifact(unit_tests);
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&run_tests.step);
}
// zig build -Dmetrics=true -Doptimize=ReleaseSafe
// in src/main.zig: const build_options = @import("build_options");
// if (build_options.enable_metrics) { ... }Regenerate the template after upgrading
When moving to a new Zig version, compare your build.zig with a fresh zig init template. Build API changes are the most common upgrade breakage, and the template shows the current idioms.
त्वरित जाँच: What is build.zig?
- A Zig program that declares the build graph using std.Build
- A configuration file in YAML
- A Makefile
- A list of compiler flags
Answer
A Zig program that declares the build graph using std.Build — Builds are written in Zig itself, so they are portable and programmable.