I made the following small Nix derivation to locally build the Zig toolchain from source for me to use locally as part of a Nix shell.
with import (fetchTarball {
url = "https://github.com/nixos/nixpkgs/tarball/b139b6056c8ad4ef7e0cffb81304d59cf077589b";
sha256 = "0sn9l19ckvdh227n0rfxk1cjnslhb5hr3g8czf3a436zkyfdl3if";
}) {};
let
zig = stdenv.mkDerivation rec {
name = "zig";
src = fetchFromGitHub {
owner = "ziglang";
repo = "zig";
rev = "476bdc8b0b02cbd09f6a856aa7dc548dea565109";
hash = "sha256-VdMNzvoWNGvVFiblE7vajOetmHa0hyUWw5tWWVZjKEs=";
};
nativeBuildInputs = [
cmake
llvmPackages_15.llvm.dev
];
buildInputs = [
libxml2
zlib
] ++ (with llvmPackages_15; [
libclang
lld
llvm
]);
preBuild = ''
export HOME=$TMPDIR;
'';
doCheck = false;
};
in
mkShell {
nativeBuildInputs = [
zig
];
}
My intent is that of improving my knowledge of Nix while also following the recommendation from the Zig getting started page:
It’s fine to evaluate Zig using a tagged version, but if you decide that you like Zig and want to dive deeper, we encourage you to upgrade to a nightly build, mainly because that way it will be easier for you to get help: most of the community and sites like ziglearn.org track the master branch for the reasons stated above.
This works fine on my MacBook Pro (macOS Ventura 13.1.1 on M1 Pro), but when I try to build it on my Linux laptop (Ubuntu 22.04 on Lenovo T480) when the build is at the stage3 phase (IIUC that's when you have a fully bootstrapped Zig compiler which builds "itself") I get a lot of the following errors:
warning: Encountered error: FileNotFound, falling back to default ABI and dynamic linker.
Once the build is done, trying to run any zig subcommand (e.g. running zig version) causes a No such file or directory error to pop up. If I run ldd $(which zig) I see the following output:
linux-vdso.so.1 (0x00007ffd05bfb000)
libclang-cpp.so.15 => /nix/store/lchazlk4r4rb1qgifxx7w8fsqgwwd835-clang-15.0.7-lib/lib/libclang-cpp.so.15 (0x00007f5e99600000)
libstdc++.so.6 => /nix/store/k88zxp7cvd5gpharprhg9ah0vhz2asq7-gcc-12.2.0-lib/lib/libstdc++.so.6 (0x00007f5e99200000)
libLLVM-15.so => /nix/store/yvcnhajqbwcq35vpnsm1waw557dxcn5v-llvm-15.0.7-lib/lib/libLLVM-15.so (0x00007f5e91200000)
libz.so.1 => /nix/store/9dz5lmff9ywas225g6cpn34s0wbldnxa-zlib-1.2.13/lib/libz.so.1 (0x00007f5e9d291000)
libc.so.6 => /nix/store/lqz6hmd86viw83f9qll2ip87jhb7p1ah-glibc-2.35-224/lib/libc.so.6 (0x00007f5e90e00000)
/lib/ld-musl-x86_64.so.1 => /nix/store/lqz6hmd86viw83f9qll2ip87jhb7p1ah-glibc-2.35-224/lib64/ld-linux-x86-64.so.2 (0x00007f5e9d2b1000)
libm.so.6 => /nix/store/lqz6hmd86viw83f9qll2ip87jhb7p1ah-glibc-2.35-224/lib/libm.so.6 (0x00007f5e9d1af000)
libgcc_s.so.1 => /nix/store/lqz6hmd86viw83f9qll2ip87jhb7p1ah-glibc-2.35-224/lib/libgcc_s.so.1 (0x00007f5e9d195000)
libffi.so.8 => /nix/store/bmnh7b67zx6l5wi6vgjvsfwrzw7ivfph-libffi-3.4.4/lib/libffi.so.8 (0x00007f5e9d188000)
librt.so.1 => /nix/store/lqz6hmd86viw83f9qll2ip87jhb7p1ah-glibc-2.35-224/lib/librt.so.1 (0x00007f5e9d181000)
libdl.so.2 => /nix/store/lqz6hmd86viw83f9qll2ip87jhb7p1ah-glibc-2.35-224/lib/libdl.so.2 (0x00007f5e9d17c000)
libncursesw.so.6 => /nix/store/35s126gfkfrwbiv49kv9kxqdpd9zvcvm-ncurses-6.4/lib/libncursesw.so.6 (0x00007f5e9d108000)
libxml2.so.2 => /nix/store/yz7qfy85damywy6397vp7nqly0y4qm2r-libxml2-2.10.3/lib/libxml2.so.2 (0x00007f5e9949a000)
The problematic line seems to be the following, where there seems to be a mismatch:
/lib/ld-musl-x86_64.so.1 => /nix/store/lqz6hmd86viw83f9qll2ip87jhb7p1ah-glibc-2.35-224/lib64/ld-linux-x86-64.so.2 (0x00007f5e9d2b1000)
Running sudo patchelf --set-interpreter /lib64/ld-linux-x86-64.so.2 $(which zig) patches the problem, but I'd like to get to a clean solution whereby the right linker is found and used and the derivation works across operating systems.
I tried to add musl to the build inputs for the Zig compiler derivation but it started throwing a lot of compilation errors and I quickly backed off.
Assuming I need to point the Zig compiler to the right linker, how can I do that? If I'm wrong in my assumption, how can I solve this problem?