We all know that a the default target for zig build is the install step, but there is also a default uninstall step that I don’t often see used. Its purpose seems pretty obvious, but (as far as I can see after scouring the std docs) there doesn’t appear to be a way to remove files from the installation prefix. Looking at other projects’ build.zig files, it looks like most of the search hits for b.getUninstallStep are from forks of the std library, and the rest all call some variation of b.addSystemCommand("rm", "foo").
Is this really the only way to uninstall files from the prefix?
I’ve racked my brain for what the “correct” way to delete artefacts would be and the only solution that I can think of, that doesn’t rely on the end user’s system, is to write a small implementation of rm and build it just in time to use it to delete the artefacts and then itself. But then I’d need to either re-write rm.zig in every project, or have a dependency just to cleanly uninstall?
I feel like I must be missing something? There isn’t b.addUninstallFile(path) or something similar that I just couldn’t find?
The reason the feature has been such low priority is that it’s kind of a nonsense feature to begin with. By definition, unless you install into an isolated directory that would be trivial to remove all together, then you are potentially destroying information during the installation process by overwriting an existing file or configuration, and an uninstall step cannot possibly revert the system state to how it was before. This is why, when you install things by hand using zig build, it is indeed best practice to install them to an isolated directory in your home folder, and when using zig build in a system package, the system package manager will manage the installation and uninstallation for end users.
That said, maybe there’s still room to implement the feature after all, but you can see why it’s not exactly a top priority.
To add one other “mitigation”, you can encourage users who might zig build install themselves with an external --prefix to use --verbose and perhaps a | tee install.log. In the very least this’ll allow retro-active manual cleanup.
Personally, I often use uninstall (but in a Makefile tbh) a lot during development:
I have the released version of the project binaries installed using homebrew.
I use install to install the dev binaries in ~/.local/bin
My PATH includes ~/.local/bin before other paths.
This way I can use install/uninstall during development and have scripts, tools, etc that use either the production or the development binaries, which is very handy.
I’ve been thinking about this, is there ever a case when the zig build uninstall command should do anything other than the inverse of zig build install?
If might be reasonable for the uninstall steps to automatically remove (maybe preserving backups in the cache) all the installation files that were added by the install step. So e.g. b.addExecutable(....) implicitly also does b.getUnintallStep().dependsOn(&b.deleteExecutable(....).Step), or something similar?