Zig builds programs with Zig code. The build script is named:
build.zigRun it with:
zig buildA build script defines steps. A step may compile an executable, run tests, install an artifact, run a program, or perform another build action.
E.1 Minimal Build Script
const std = @import("std");
pub fn build(b: *std.Build) void {
const exe = b.addExecutable(.{
.name = "hello",
.root_source_file = b.path("src/main.zig"),
.target = b.standardTargetOptions(.{}),
.optimize = b.standardOptimizeOption(.{}),
});
b.installArtifact(exe);
}Project layout:
hello/
build.zig
src/
main.zigBuild:
zig buildRun the installed executable:
./zig-out/bin/helloE.2 The Build Function
Every build script exports a build function.
pub fn build(b: *std.Build) void {
...
}The argument b is the build graph object. It creates compile steps, run steps, install steps, options, modules, and dependencies.
E.3 Target and Optimize Options
Most build scripts begin with the standard target and optimization options.
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});Use them in artifacts:
const exe = b.addExecutable(.{
.name = "app",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});Then the user can choose:
zig build -Dtarget=x86_64-linux
zig build -Doptimize=ReleaseFastCommon optimize modes:
Debug
ReleaseSafe
ReleaseFast
ReleaseSmallE.4 Executables
Create an executable:
const exe = b.addExecutable(.{
.name = "app",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});Install it:
b.installArtifact(exe);Add imports or link libraries before installing.
E.5 Libraries
Static library:
const lib = b.addStaticLibrary(.{
.name = "mylib",
.root_source_file = b.path("src/lib.zig"),
.target = target,
.optimize = optimize,
});Shared library:
const lib = b.addSharedLibrary(.{
.name = "mylib",
.root_source_file = b.path("src/lib.zig"),
.target = target,
.optimize = optimize,
});Install:
b.installArtifact(lib);E.6 Modules
A module is an importable unit of Zig code.
const mod = b.createModule(.{
.root_source_file = b.path("src/lib.zig"),
.target = target,
.optimize = optimize,
});Import it into an executable:
exe.root_module.addImport("mylib", mod);Then in Zig code:
const mylib = @import("mylib");E.7 Tests
Create a test artifact:
const tests = b.addTest(.{
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});Create a run step for it:
const run_tests = b.addRunArtifact(tests);Expose it as a named build step:
const test_step = b.step("test", "Run tests");
test_step.dependOn(&run_tests.step);Run:
zig build testE.8 Run Steps
Run an executable from the build graph.
const run_cmd = b.addRunArtifact(exe);Make it depend on installation if needed:
run_cmd.step.dependOn(b.getInstallStep());Expose it:
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);Run:
zig build runPass arguments after --.
if (b.args) |args| {
run_cmd.addArgs(args);
}Command:
zig build run -- input.txt output.txtE.9 Build Options
Define a boolean option:
const enable_log = b.option(
bool,
"log",
"Enable logging",
) orelse false;Create an options module:
const options = b.addOptions();
options.addOption(bool, "enable_log", enable_log);Import it into the program:
exe.root_module.addOptions("build_options", options);Use it:
const build_options = @import("build_options");
if (build_options.enable_log) {
// logging code
}Command:
zig build -Dlog=trueE.10 Dependencies
Fetch dependencies with zig fetch, then import them in build.zig.zon.
A build script reads a dependency by name.
const dep = b.dependency("example", .{
.target = target,
.optimize = optimize,
});Import one of its modules:
exe.root_module.addImport(
"example",
dep.module("example"),
);Then in source:
const example = @import("example");E.11 Linking C
Link libc:
exe.linkLibC();Add C source files:
exe.addCSourceFile(.{
.file = b.path("src/add.c"),
.flags = &.{ "-std=c99" },
});Add include path:
exe.addIncludePath(b.path("include"));Link a system library:
exe.linkSystemLibrary("m");E.12 Installing Files
Install an artifact:
b.installArtifact(exe);Install a file:
b.installFile("README.md", "share/app/README.md");Install a directory:
b.installDirectory(.{
.source_dir = b.path("assets"),
.install_dir = .prefix,
.install_subdir = "share/app/assets",
});E.13 Custom Steps
Create a named step:
const docs = b.step("docs", "Build documentation");Make it depend on another step:
docs.dependOn(&some_other_step.step);A custom step is useful when a project has several tasks:
zig build test
zig build docs
zig build runE.14 Common Build Script
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const exe = b.addExecutable(.{
.name = "app",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
b.installArtifact(exe);
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);
const tests = b.addTest(.{
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
const run_tests = b.addRunArtifact(tests);
const test_step = b.step("test", "Run tests");
test_step.dependOn(&run_tests.step);
}This build script supports:
zig build
zig build run
zig build test
zig build -Doptimize=ReleaseFast
zig build -Dtarget=aarch64-linuxA Zig build script is an ordinary Zig program. Keep it plain. Create artifacts, connect steps, expose the few commands the project needs.