Confusion about Run step arguments

Hello,

I have recurring troubles with the build system API. I understand the high level ideas (which I find spectacularly brilliant) but I keep loosing myself in the multiple similar functions and writing build.zig feels more like magic incantations than coding.

So, with #35428 landed, I’m trying to take some time to fill the blanks a bit better.

Right now, I’m stuck with things related to std.Build.Step.Run, specifically with addFileArg and addFileInput.

I fail to see the difference between theses two functions. Both call a addStepDependencies on the lazy path, but one the former appends to run.argv while the latter to run.file_input.
I’ve looked a bit in the maker’s related code, but I confess it’s a bit over my head.

Can somebody help me understand this difference ?

Somewhat uneducated guess (for addFileInput) but addFileArg adds the file to the command line args:

run.addArgs(&.{"--input"});
run.addFileArg(b.path(opts.input));

…when this file is dirty it triggers executing the command line tool.

…while addFileInput seems to be an implicit input file which is not added to the command line args but still triggers an execution when the file is dirty (e.g. most simple example would be a command line tool which always reads a hardwired input.txt file without the ability to override the filename via a cmdline arg - the build system still needs to know about this file in order to trigger the command execution when the file is dirty).

FWIW I only used addFileArg (along with addOutputFileArg) so far and had no need for addFileInput.

…also AFAIK the reason why there are special addFile... functions instead of just addArg is that the LazyPath args which ‘encode’ the file location need to be ‘resolved’ lazily during the build phase (e.g. think of a lazy path as some sort of a dynamic path alias).

PS: the one tricky and confusing thing about the Zig build system is that the code in build.zig only constructs the ‘build graph’ but doesn’t perform the build, this happens in a separate ‘build phase’ which evaluates the previously constructed build graph.

This makes it tricky to inject custom behaviour into the build, since all code you write into build.zig is running in the ‘graph construction phase’, and which then leads to somewhat confusing names and behaviours like ‘LazyPath’, and the advice to bake custom build functionality into an adhoc-built command line tool instead of being able to put that custom code directly into build.zig.