Zig Build: Run Step with no output but should only run if input changes

I’m looking to run size on an ELF file only when it gets recompiled.

So far I’ve got

const elf: *Step.Compile;
// ...
const size_cmd = b.addSystemCommand(&.{"size"});
size_cmd.addArtifactArg(elf);

Of course Zig Build wants to see an output arg to determine that it doesn’t have side-effects and when the output needs to be regenerated.

The usual make/ninja hack of generating a dummy output file with psuedocode:

_ = size_cmd.addPrefixedOutputFileArg(" && touch ", "SIZED");

Technically doesn’t work because it’s not executing as a shell. I think I’d have to write a custom executable to interface between the Run Step, what it thinks its arguments are, the actual system command I want to run just once, and a dummy output for stale-checking.

Any ideas on how to idiomatically handle this use-case? I have a few other uses for this pattern of post-processing: scp binary to server when it changes, program MCU when firmware recompiles, etc.

I’m observing that zig build makes heavy use of output caching. So adding an output file would likely not work eitehr as the dummy output may get cached and fail to trigger a post-processing run even after source-code changes (change source to older git commit whose binary has already been cached).

I think you just need to set size_cmd.has_side_effects = false;.

my first guess would be that your size_cmp task is not being run because nothing else depends on it, but I would need to see more of the build script to say that for sure