🎓 A1Learner
🔍
0 of 46 lessons completed

Zig Custom Build Steps

A custom build step is a step you add to build.zig that runs a command or a program during the build. It lets one command prepare, check, or report before the main program runs.

Run a system command

This build file runs echo as its run step. The command prints its own line to the terminal.

const std = @import("std");
pub fn build(b: *std.Build) void {
    const echo_cmd = b.addSystemCommand(&.{ "echo", "hello-from-step" });
    echo_cmd.stdio = .inherit;
    const run_step = b.step("run", "Run the step");
    run_step.dependOn(&echo_cmd.step);
}

Capture a command result

The echo step saves its output instead of printing it. A second command then prints the saved text.

const std = @import("std");
pub fn build(b: *std.Build) void {
    const echo_cmd = b.addSystemCommand(&.{ "echo", "captured-hello" });
    const captured = echo_cmd.captureStdOut();
    const show = b.addSystemCommand(&.{ "cat" });
    show.addFileArg(captured);
    show.stdio = .inherit;
    const run_step = b.step("run", "Show captured output");
    run_step.dependOn(&show.step);
}

Run a command before the program

The program step depends on the echo step. The echo line therefore prints before the program line.

const std = @import("std");
pub fn build(b: *std.Build) void {
    const exe = b.addExecutable(.{ .name = "app", .root_source_file = b.path("src/main.zig"), .target = b.standardTargetOptions(.{}), .optimize = b.standardOptimizeOption(.{}) });
    b.installArtifact(exe);
    const echo_cmd = b.addSystemCommand(&.{ "echo", "step-ready" });
    const run = b.addRunArtifact(exe);
    run.step.dependOn(&echo_cmd.step);
    const run_step = b.step("run", "Run the app");
    run_step.dependOn(&run.step);
}

Example

const std = @import("std");
pub fn build(b: *std.Build) void {
    const exe = b.addExecutable(.{ .name = "app", .root_source_file = b.path("src/main.zig"), .target = b.standardTargetOptions(.{}), .optimize = b.standardOptimizeOption(.{}) });
    b.installArtifact(exe);
    const echo_cmd = b.addSystemCommand(&.{ "echo", "preparing" });
    const run = b.addRunArtifact(exe);
    run.step.dependOn(&echo_cmd.step);
    const run_step = b.step("run", "Run the app");
    run_step.dependOn(&run.step);
}

Key points

  • System command: a system command is a command the build runs, such as echo.
  • Build step: a build step is a named unit of work in build.zig.
  • Step dependency: a step dependency is a link that makes one step run before another step.
  • Captured output: captured output is text a step saves instead of printing it at once.
  • Inherited output: inherited output is text a step prints straight to the terminal.
  • Run step: a run step is the top-level step named run that zig build run executes.

The echo step is created first and the program step depends on it. That link forces the echo line to print first. The run step then runs the program step, so the program line prints second.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

What does addSystemCommand add to a build?