Make a `make-release` step in build.zig

I have a default build.zig which currently builds my application with zig build. However I want to create an another step make-release to build release binaries for all the platforms that my program supports. Here’s what I wrote

const targets: []const std.Target.Query = &.{
    .{ .cpu_arch = .x86_64, .os_tag = .macos },
    .{ .cpu_arch = .aarch64, .os_tag = .macos },

    .{ .cpu_arch = .aarch64, .os_tag = .linux },
    .{ .cpu_arch = .x86_64, .os_tag = .linux, .abi = .gnu },
    .{ .cpu_arch = .x86, .os_tag = .linux, .abi = .gnu },

    .{ .cpu_arch = .x86_64, .os_tag = .windows },
    .{ .cpu_arch = .x86, .os_tag = .windows },

const default_exe = b.addExecutable(.{
   .name = "zigvm",
   .root_source_file = b.path("src/main.zig"),
   .target = target,
   .optimize = optimize,
// ...
// ...
const release_step = b.step("make-release", "Create binaries for releasing");
for (targets) |t| {
    const name = try std.mem.concat(b.allocator, u8, &.{ "zigvm-", try t.zigTriple(b.allocator) });
    const exe = b.addExecutable(.{
        .name = name,
        .root_source_file = b.path("src/main.zig"),
        .target = b.resolveTargetQuery(t),
        .optimize = .ReleaseSafe,

    const target_output = b.addInstallArtifact(exe, .{});

    /// ....


But this is causing weird behavior, like calling zig build also builds all the release binaries and calliing zig build make-release causes the default binary to be built along with the release binaries. So how do I fix it?

Any help is appreciated. Thanks in advance.

b.getInstallStep().dependOn(&target_output.step); in the loop, means that install step depends on each of the target output steps.
Note that install is the default step, used when calling zig build.

What you want is the release_step to depend on all of the target output steps:

To solve the problem simply replace b.getInstallStep().dependOn with release_step.dependOn.

release_step.dependOn(b.getInstallStep()); means that release_step also depends on the install step (that builds you default_exe); you might want this but it is not necessary.


Thanks that did the trick. Marking your post as the solution.