I was doing something a bit off-piste in one of my build.zig file, and I’m trying to work out how to do it in 0.16. Basically I want the program to be able to report how it was built (for bug reproduction reasons), and so I capture the command line arguments and pass them as a string to the program.
pub fn build(b: *std.Build) !void {
var argv: [][]const u8 = try b.allocator.alloc([]const u8, std.os.argv.len);
defer b.allocator.free(argv);
// Convert each argument into a slice
for (std.os.argv, 0..) |x, i| {
argv[i] = std.mem.span(x);
}
// The interesting arguments seem to start at number 9.
// Join them into a single string for simplicity.
const build_cmd: []const u8 = try std.mem.join(b.allocator, " ", argv[9..]);
const options = b.addOptions();
options.addOption([]const u8, "COMPILER_FLAGS", build_cmd);
...
}
It’s hacky, but it did the job. I then can print them out at run-time:
I’m suspecting that now arguments are part of std.Process.Init.Minimal,std.os.argv no longer exists, and std.Build doesn’t contain a std.Io or a std.Process.Init… this isn’t going to be easy.
Any suggestions on how I can embed how the executable was built inside the executable?
You probably can’t capture all build arguments exactly as passed to zig build.
But @import("builtin") gives you access to compile-time variables (target, optimize mode, etc.), which might be enough depending on what you need.
The b.graph.io field may be useful here, since it gives you access to I/O in the build context.
The goal is to be able to reproduce a build as precisely as I can from the information logged. I’d have the compiler version, and the code version (Git hash + whether it was modified). Certainly the information in builtin need to be part of the set, but if (for example) somebody has specified --fork to override a dependency then I’d like to capture that. If I could get the command line then that is guaranteed to get everything.
I think this makes sense for knowing the provenance of the software when issues get reported (which may have been built from source or misconfigured upstream). I can easily see how it would be super useful for diagnosing and reproducing issues.
It could be easy for a reporter miss or mess up this information when reporting a bug, but the logs are (hopefully) more automatic, trustworthy, and authoritative.