Zig is great. But its aggressive minimum Linux kernel support policy—only supporting versions newer than the current Debian LTS kernel, 5.10—makes it unusable on older systems like Kindles, Termux on Android, and old servers.
This guide introduces a simple, minimally invasive patch for the standard library to maximize compatibility with these older devices.
The specific syscall that's breaking compatibility with old kernels is statx, which was introduced in Zig 0.14 (replacing POSIX's fstat).
It appears to be called in only two places in the standard library, both of which are guarded by an os == .linux check.
- The latest version of Zig is installed and in your
PATH(i.e.,zigruns correctly). - You are on Linux.
- You have
jqinstalled for parsing JSON.
- Download
zigw.bashto your project root, for example, as./zigw. - Run
./zigwonce from your project root. This will create apatched_std_libdirectory containing the standard library. - Modify the standard library in this directory as needed.
- From now on, use
./zigwas a drop-in replacement forzig. For example, run./zigw buildto compile your program.
A pre-made patch for statx compatibility is provided in the statx.diff file below. You can apply it with patch -p2 < statx.diff. Activate it by using a target triplet with a lower min version specifier:
$ ./zigw build -Dtarget=arm-linux.4.1Q: Why modify a copy in the project directory instead of the original std lib?
A: Patches should be project-specific and not alter the system-wide std lib directly.
Q: Why use a bind mount to remap the std lib path instead of a portable argument like --zig-lib-dir ./patched_lib?
A: (1) I only discovered this flag in zig build --help after I had already written the script and was too lazy to refactor it. (2) A bind mount theoretically offers better compatibility.