The Zig Build System
36.1 A Basic build.zig (0.15 Style)
The build graph is made of steps (compile, run, install, write files, custom). zig build --help lists steps and options.
The build runner itself is a Zig program compiled from build.zig.
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{}); // -Dtarget=...
const optimize = b.standardOptimizeOption(.{}); // -Doptimize=...
// Library module (reusable / importable)
const lib_mod = b.addModule("mylib", .{
.root_source_file = b.path("src/root.zig"),
.target = target,
});
// Executable
const exe = b.addExecutable(.{
.name = "myapp",
.root_module = b.createModule(.{
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
.imports = &.{.{ .name = "mylib", .module = lib_mod }},
}),
});
b.installArtifact(exe); // zig-out/bin/myapp
// `zig build run -- args`
const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| run_cmd.addArgs(args);
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
// `zig build test`
const lib_tests = b.addTest(.{ .root_module = lib_mod });
const exe_tests = b.addTest(.{ .root_module = exe.root_modul
…36.2 Build Options
const enable_logging = b.option(bool, "logging", "Enable logging") orelse false;
const version = b.option([]const u8, "version", "App version") orelse "dev";
const options = b.addOptions();
options.addOption(bool, "logging", enable_logging);
options.addOption([]const u8, "version", version);
exe.root_module.addOptions("build_options", options);// in code
const build_options = @import("build_options");
if (build_options.logging) std.log.info("version {s}", .{build_options.version});zig build -Dlogging=true -Dversion=1.2.336.3 Libraries and C Sources
const lib = b.addLibrary(.{
.name = "mylib",
.linkage = .static, // or .dynamic
.root_module = b.createModule(.{
.root_source_file = b.path("src/root.zig"),
.target = target,
.optimize = optimize,
}),
});
b.installArtifact(lib);
exe.root_module.addCSourceFiles(.{
.files = &.{ "vendor/sqlite3.c", "src/helper.c" },
.flags = &.{ "-std=c99", "-O2", "-DSQLITE_THREADSAFE=1" },
});
exe.root_module.addIncludePath(b.path("vendor"));
exe.root_module.link_libc = true; // or exe.linkLibC()
exe.root_module.linkSystemLibrary("z", .{}); // system zlib (pkg-config when available)
exe.root_module.linkLibrary(lib);
exe.root_module.addCMacro("DEBUG", "1");36.4 Generated Files, Custom Steps and Install
const gen = b.addWriteFiles();
const generated = gen.add("version.zig", "pub const v = \"1.0\";\n");
exe.root_module.addAnonymousImport("version", .{ .root_source_file = generated });
const tool = b.addExecutable(.{ .name = "codegen", .root_module = b.createModule(.{
.root_source_file = b.path("tools/codegen.zig"), .target = b.graph.host,
}) });
const run_tool = b.addRunArtifact(tool);
run_tool.addFileArg(b.path("schema.json"));
const out = run_tool.addOutputFileArg("schema.zig"); // a generated file used as a module
exe.root_module.addAnonymousImport("schema", .{ .root_source_file = out });
b.installFile("README.md", "share/README.md");
b.installDirectory(.{ .source_dir = b.path("assets"), .install_dir = .prefix, .install_subdir = "assets" });
const fmt_step = b.addFmt(.{ .paths = &.{ "src", "build.zig" }, .check = true });
b.step("fmt", "Check formatting").dependOn(&fmt_step.step);
const docs = b.addInstallDirectory(.{
.source_dir = lib.getEmittedDocs(),
.install_dir = .prefix,
.install_subdir = "docs",
});
b.step("docs", "Generate docs").dependOn(&docs.step);36.5 Useful zig build Flags
zig build --summary all # step tree summary
zig build -Dtarget=aarch64-linux-musl -Doptimize=ReleaseSmall
zig build --watch # rebuild on file changes
zig build --watch -fincremental # incremental compilation (experimental, much faster rebuilds)
zig build --prefix /usr/local install
zig build -j4 # parallelism
zig build --verbose # show commands
zig build --fetch # fetch dependencies only
zig build --release=fast # respect the project's preferred release mode