Looks like the recent build system changes are hitting me too… the parts of the sokol-zig build system which install the Emscripten SDK into the package cache and need to look up paths in the installed Emscripten SDK, e.g.:
Also similar problem in the sokol shader compiler package where I need to extract LazyPaths as string to setup the arguments for addSystemCommand:
Is there a better/modern way to do this? It basically comes down to looking up the absolute paths of files in non-zig build.zig.zon dependencies and then running existing cmdline tools in that directory (which in turn may need to pass absolute paths to locations in the package cache as cmdline args when the system-command executes).
I have hit similar issues porting something using meson relying external paths. For me what has worked is moving the needed build functionality into tools and spawning those from the build.zig.
I’m not sure that is the correct answer though so am curious on other feedback here. I do like the idea that the build enforces its own self-contained-ness, but it does seem frustrating to have to wrap it and/or break out to do other common installation/configuration steps.
I’ve been toying with a fork of sokol-zig that handles the latest build system changes - you can replace addSystemCommand() with addRunFile() so that your argv0 can be a LazyPath.
I then inlined optsToArgs() so that it is directly adding arguments to the std.Build.Step.Run.
The only thing I haven’t managed to migrate nicely yet is the “file-exists” check
Ah nice, we can probably skip the file-exists thing if we make the emsdk installation an explicit step (e.g. you’d need to run zig build install-emsdk or something…
Do you want to provide a PR (or two I guess? one for sokol-zig and one for sokol-tools-bin)? Even if it is incomplete we could then discuss solutions there, or I can take over from there.
I think for me the issue is less about integrating and more about expectations, as many cases that “break out” from these custom tools will still appear to the user as a regular zig build.
What this means is the “zig build only operates in the prefix” is an internal fact about std.Build, but not an external fact about performing a build of a zig project itself.
Obviously this is true regardless - the build can execute arbitrary code, but I do think it may be continuous point of friction in the future that could be solved by something out of the box.
I think your build.zig could provide emsdk as a run step. You can provide api to run emsdk and other functionality from your build.zig. In these apis you can find the dependency for “self” using the following function:
b.dependencyFromBuildZig(@This(), .{
.target = b.graph.host,
// ... any build options you want to use by default, or provide from caller
});
Where b is provided as a argument from the caller.
Sorry for dumping lots of build.zig code that may be unrelated, but I do lots of similar things by providing whole libc/libc++ toolchain from build.zig (arguably there’s some hacks here, because the way libc files work through std.Build api is not perfect), and the code for all that is here, you may find it helpful or not: https://zigbin.io/cf76a1