Hi all, I recently ran into a package (nss) which failed to compile on my laptop, but succeeded on my desktop.
Now, you would think this must be because some dependency/setting is different on these machines, meaning the nix-store hash of the result would end up differently, but this was not the case. I used nix-copy-closure to copy the result from my desktop to my laptop. I tried to rebuild again, and it accepted the result that was in store, and continued building. Then I saw this commit come along [1]. Indeed the only difference I can think of between these machines are the kernel version and the hardware itself. As nss doesn't depend on the kernel, its store path ends up the same, but during compilation, different choices are made. Probably other differences can occur as well. Let's assume some package checks for availability of SSE4 instructions on the cpu at compile-time to decide optimizations to use. Then we end up with a store path which isn't portable, but no way to detect this. This is very impure! I think I've seen tricks used by CLFS (cross linux from scratch) or gentoo some years back, which had some system call (or even the proc filesystem) respond with custom answers like a hard-coded kernel version, or cpu type. Of course packages can still make stupid compile-time choices by inspecting other things (leave out functionality if disk space is low, or even more contrived examples), but I don't think they occur much. I also can't think of a package that makes compile-time choices for cpu, but at least for the kernel version some examples reveal themselves. (like nss, but python as well, try to build kdeadmin on a machine running kernel 3.2 which built its own python, it will fail to find pykde4 because of choices made by python) Now, of course we can try to fix every package that doesn't understand linux3's version numbering yet, but that leaves the problem that packages _do_ contain internal differences we cannot detect (by looking at the store path) depending on what machine built them. I think there are 2 solutions: - record some kernel version number in the store hash. Of course we don't want the full version number, as that would lead to rebuilding your entire system if you upgrade kernels. There are no real differences between 3.0 and 3.2 (not like 2.4 and 2.6 differed), so I don't know what number to look for. - trick builders to think they execute on a specific kernel version, probably the version of kernel headers used for glibc. Maybe by just faking 'uname', or some underlying system call that gets used. Maybe it's not that big a problem, but it's clear that purity is affected. What do you all think? Mathijs [1] https://nixos.org/repos/nix/nixpkgs/trunk@32834 _______________________________________________ nix-dev mailing list [email protected] http://lists.science.uu.nl/mailman/listinfo/nix-dev
