Running zig build run dosen't take options into account

Hi,
I was trying to play around with optimizations done in different compilation optimization modes, like the fact that the compiler optimize away certain calls to std.debug.assert.

But when I setup the project, I can’t find a way to use the command zig build -Doptimize=ReleaseFast run with the run step taking into account the executable generated with -Doptimize=ReleaseFast.

I have a very little example to show my problem:

main.zig:

const std = @import("std");

pub fn main() !void {
    positive(-1);
}

fn positive(i: i64) void {
    std.debug.assert(i > 0);
}

build.zig

const std = @import("std");

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    const exe = b.addExecutable(.{
        .name = "various",
        .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());

    const run_step = b.step("run", "Run the app");
    run_step.dependOn(&run_cmd.step);
}

When I run zig build -Doptimize=ReleaseFast and then manually executing it with zig-out/bin/various.exe I have no error, showing that the call to assert isn’t part of the exe.

But when I run zig build -Doptimize=ReleaseFast run, I have the following:

run
└─ run various failure
error: the following command exited with error code 3:
\Zig\Tests\various\zig-out\bin\various.exe 
Build Summary: 3/5 steps succeeded; 1 failed (disable with --summary none)
run transitive failure
└─ run various failure

To my understanding, the fact that the second one ends in an error at the run step means that the executable used isn’t compiled with -Doptimze=ReleaseFast, otherwise I should not see anything as the call to assert should not part of the executable in this optimization mode.

What’s wrong with this simple setup? How can make the run step to use the executable compiled with -Doptimize=ReleaseFast?

I think you might be mistaken about this. What is the exit code when you run the program manually? For me, both running manually and via zig build run -Doptimize=ReleaseFast crash, but the crash is only apparent when looking at the exit code.

> .\zig-out\bin\various.exe

%errorlevel% -2147483645

As for why it’s crashing, note that assert is implemented like so:

pub fn assert(ok: bool) void {
    if (!ok) unreachable; // assertion failure
}

so you’re telling the compiler that you know i > 0 will always be true, and the compiler is allowed to make optimizations under that assumption (see the unreachable documentation). I’m not sure exactly what the compiler is deciding to do here, but you are essentially telling the compiler that it is allowed to treat i <= 0 as undefined behavior, and then you are invoking undefined behavior by passing -1 as i.

Oh you’re wright. I’m really not used to work on a Windows machine but when I print this variable in power shell: echo $LASTEXITCODE (equivalent of $? I guess), I have indeed the same code error as you.
Thanks for the time you took to try it yourself and answer!

1 Like