Nix is a lie, and that’s ok
20 points by ambiso
20 points by ambiso
Very clickbaity title (and is that image AI gen?) but I found the issue interesting nonetheless.
I'm not sure if this is really an impurity? The binary should still be reproducible.
It's impurity in the sense of "built derivation's closure is not self-contained" – the binary depends on something that's not in its dependencies.
We might need a better term for incompletely captured/specified runtime dependencies.
I agree this is a fair way to think about it, but calling this runtime stuff an impurity also dilutes the value of the term for understanding what can/can't be allowed in the build sandbox?
Some threads that cross bits of this territory:
I think it's important to differentiate Nix and NixOS here. Nix doesn't make this trickery impossible, and NixOS takes advantage of it. It causes a ton of problems, with the hope that it eliminates more. It's not an unreasonable idea, despite the escape hatch it's taking.
I'd like to blame NVIDIA for this, because with all other GPUs it's perfectly possible to just include some version of Mesa and it will most likely be compatible with the kernel.
What about NixOS? Surely, we know what kernel and drivers we have there!? 🤔
Well, if we modified every derivation to include the correct libGL.so it would cause massive rebuilds for every user and make the NixOS cache effectively useless.
Even then you wouldn't really know. In the past the directory holding libGL.so or libcuda.so would sometimes accidentally get added to RPATH because not every contributor would know about the driver library issue/mechanism and it slipped through review (partly, because some committers also did not have correct understanding).
It would still break things left and right for NixOS users. It turns out that (at least back then) there quite a lot of users that use NixOS stable, but cherry pick some applications from NixOS unstable because they need a newer version. Then the unstable library/app would use a newer driver library, which was incompatible with the actual kernel driver in stable.
Nix does not have any concept of depending on an abstract interface with multiple implementations?
Yes at build time: you can replace any input for a package with a compatible one. No at runtime: you built it for a specific version of specific implementation of libfoo and that's what you'll always get. Which works for almost everything, apart from GL drivers. (And compiled plugins are a bit weird)
Docker has the same class of problems. Some dependencies are inherently host-bound. In his example, libGL.so is tied to the host kernel module and the actual GPU, so you cannot fully precompute it into a portable artifact. The Docker runtime will inject whatever GPU driver into the container and if the container runs a different version of Glibc, it's also a problem.
One of the classic new end user headaches and largely what compelled me to go all in on daily driving NixOS after sampling the gateway drug of Home Manager.