Zig build required option for a particular step

What is the right way to return an error to the user if they attempt to run a build step that requires a certain option to be non-null?

For example, I want:

zig build dist-fat -Dassets=/path/to/assets

to run that step with the provided option. If the option isn’t provided, the step should generate an error.

I’m sure there are better ways to achieve this but here you go :slight_smile:

    const mandatory_path = b.option([]const u8, "mandatory_path", "mandatory path required by <step>") orelse {
        std.log.err("the path is required to build the <step>. Please provide one.", .{});
        return;
    };

    const option = b.addOptions();
    option.addOption([]const u8, "mandatory_path", mandatory_path);

    const exe = b.addExecutable(.{
        .name = "temp",
        .root_source_file = b.path("src/main.zig"),
        .target = target,
        .optimize = optimize,
    });

    exe.root_module.addOptions("option", option);
    b.installArtifact(exe);

Thank you - I might not have explained it well, but I don’t think that solution works. The option is not required for the “install” step. It’s only required for the “dist-fat” step.

Currently my approach is to only define the dist-fat step if the option is supplied by the user. But this means zig build --help doesn’t show the dist-fat step.

What I would prefer is to define the dist-fat step but have it fail if the option is not supplied. You example will always fail if the option is not provided. An alternative I tried is to declare the step but have it do nothing if the option is null, but the problem is then we don’t get an error, so the user might thing the step succeeded.

I think the struggle is with the declarative nature of the build definitions. What I think I need is a way to declare that a step should return an error if an option is not provided. But other steps which don’t care about that option should be unaffected.

1 Like

if you replace the std.log.err by std.log.info it just prints the message without failing the compilation if it’s not provided, so you could put a message explaining to the user, that if he wants the “dist-fat” step to work he needs to provide this path ? but that doesn’t solve your problem of dependency

Mayvbe you can use the orelse to provide a path yourself (a fake one) and do a little strcmp on it and if it match your default string, you just print the message, indicating the information and don’t fail the step ? or maybe you can add two time the same step one dummy one that always succeed but do nothing just to provide the message, and one that actually do the thing ?

    const mandatory_path = b.option([]const u8, "mandatory_path", "mandatory path required by <step>") orelse blk: {
        std.log.info("the path is required to build the <step>. Please provide one.", .{});
        break :blk "Private/path/that/doesn't/exist";
    };

    _ = b.step("dummy_step_for_message", "if you want to use my step provide the option -Dmandatory_path=<your/path/to/the/thing>");

    const option = b.addOptions();
    option.addOption([]const u8, "mandatory_path", mandatory_path);

    const exe = b.addExecutable(.{
        .name = "temp",
        .root_source_file = b.path("src/main.zig"),
        .target = target,
        .optimize = optimize,
    });

    exe.root_module.addOptions("option", option);
    b.installArtifact(exe);

so running it does something like that :slight_smile:

❯ zb -h
info: the path is required to build the <step>. Please provide one.
Usage: /home/pollivie/zig/0.14.0-dev.1952+9f84f7f92/files/zig build [steps] [options]

Steps:
  install (default)            Copy build artifacts to prefix path
  uninstall                    Remove build artifacts from prefix path
  dummy_step_for_message       if you want to use my step provide the option -Dmandatory_path=<your/path/to/the/thing>
  run                          Run the app
  test                         Run unit tests

There’s actually an example of exactly what you’re looking for in Zig’s build.zig:

(and another here)

4 Likes

Excellent, addFail seems to be the thing. Thank you both.