I want to write a tiny program in Zig today, such that, without any maintenance, I could come back to it in five years, and still be able to compile & run it. As Zig isn’t stable yet, this means I need to pin a specific version of Zig compiler.
What’s the best way to do that? I could use various Zig version managers, but I can’t be 100% sure that they themselves would be around 5 years down the line.
I could use shell.nix with a pinned version of nixpkgs. For that, I am pretty sure it will be there many years down the line, but that sounds like “you wanted a banana, you got yourself a banana, a gorilla holding the banana, and half of the rest of the jungle”.
I guess I could manually download specific Zig version from the website. Does Zig guarantee that download URLs are stable even for per 1.0 Zig versions? If I go that way, what’s the canonical download script to copy paste?
From my experience the download urls are pretty stable, but I wouldn’t bet on it. Who knows what could happen within 5 years.
The safest way to guarantee that it still works in 5 years would be to package a copy of the compiler with the source code. It is just 40 MB (per supported platform) after all.
I use this wrapper script (as ./zig) in all my projects to pin the version of zig last used to successfully build it. ./build.zig.version and ./zig are then checked in and ./zig is used to build. This allows me to have some projects really up-to-date and others possibly lagging quite a bit.
#!/bin/bash
set -e
ARCH=$(uname -m)
BASEDIR="$(cd "$(dirname "$0")" && pwd)"
ZIGDIR=$BASEDIR/.cache/zig
VERSION=$(< build.zig.version)
ZIGVER="zig-linux-$ARCH-$VERSION"
ZIG=$ZIGDIR/$ZIGVER/zig
if [ "$1" == "update" ] ; then
curl -L --silent https://ziglang.org/download/index.json | jq -r '.master | .version' > build.zig.version
NEWVERSION=$(< build.zig.version)
if [ "$VERSION" != "$NEWVERSION" ] ; then
echo zig updated to $NEWVERSION
exit 0
fi
echo zig version $VERSION is up-to-date
exit 0
fi
(
mkdir -p "$ZIGDIR"
cd "$ZIGDIR"
TARBALL="https://ziglang.org/builds/$ZIGVER.tar.xz"
if [ ! -d "$ZIGVER" ] ; then
curl "$TARBALL" | tar -xJ
fi
)
exec $ZIG "$@"