Build System

The Zig Build System lets you define how to build and test your code in one place. Let’s look at a simple example.

We have two source files and a “build file”.

maths.zig defines an add function:

const std = @import("std");
const expectEqual = std.testing.expectEqual;

pub fn add(a: u64, b: u64) u64 {
    return a + b;
}

test "add calculates the sum" {
    try expectEqual(3, add(1, 2));
}

main.zig defines a main function that uses add:

const std = @import("std");
const print = std.debug.print;

const maths = @import("maths.zig");

pub fn main() void {
    print("2 + 2 = {}\n", .{maths.add(2, 2)});
}

// This is a bit of a hack that lets us run all unit
// tests together:
test {
    std.testing.refAllDecls(@This());
}

build.zig contains Zig code that defines the build process:

const std = @import("std");

pub fn build(b: *std.Build) void {
    // The root source file contains 'main':
    const root_source_file = b.path("main.zig");

    // Standard options for the target and build mode:
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    // We define one executable to be built.
    const exe = b.addExecutable(.{
        .name = "addition",
        .root_module = b.createModule(.{
            .root_source_file = root_source_file,
            .target = target,
            .optimize = optimize,
        }),
    });
    b.installArtifact(exe);

    // Define a 'run' command to run the program.
    const run_step = b.step("run", "Run the program");
    const run_exe = b.addRunArtifact(exe);
    run_step.dependOn(&run_exe.step);

    // And a 'test' command that runs all unit tests.
    const test_step = b.step("test", "Run unit tests");
    const unit_tests = b.addTest(.{
        .root_module = b.createModule(.{
            .root_source_file = root_source_file,
            .target = target,
        }),
    });
    const run_unit_tests = b.addRunArtifact(unit_tests);
    test_step.dependOn(&run_unit_tests.step);
}

zig build builds the executable and puts it under zig-out.

$ zig build
$ ls zig-out/bin
addition

We can use -Dtarget and -Doptimize to select target and build mode.

$ zig build -Dtarget=x86_64-windows
$ ls zig-out/bin
addition.exe
addition.pdb

zig build run runs the program directly.

$ zig build run
2 + 2 = 4

zig build test runs the unit tests. (There’s no output if all tests succeeded.)

$ zig build test

Next example: Using C.