NixOS / nix

Nix, the purely functional package manager
https://nixos.org/
GNU Lesser General Public License v2.1
12.81k stars 1.52k forks source link

Different package hashes on x86_64-darwin and aarch64-darwin when building for x86_64 #11554

Open konradmalik opened 1 month ago

konradmalik commented 1 month ago

Recently I was investigating why, even though my cachix has packages for x86_64-darwin, my local machine still builds them from scratch.

Then I noticed that my github runner was running macos-latest, which now defaults to aarch64-darwin but was able to build packages for x86_64-darwin due to rosetta (my assumption).

The problem is that packages build for x86_64-darwin on rosetta are different than those built on native x86_64-darwin (intel) and that's why I had all those cache misses.

The fix was to revert to macos-13 runner which still runs native x86_64-darwin.

The question - is this a bug? Lack of proper sandboxing on darwin? Can this somehow be fixed with proper nix.conf entries?

FYI: this was the fix https://github.com/konradmalik/nixpkgs-extra/commit/e69eb43d9b0fba84d7982d31fb0add12445cda24

The nix I use is installed using cachix/install-nix-action@V28 and the version is nix-2.24.6

roberth commented 1 month ago

I suppose you're referring to the store path hashes, and not necessarily the content hashes (although those are affected whenever you have a reference to another store path). If only the content hash is different, then the problem is a build impurity, which are usually unnoticeable due to the result being equivalent. So I'll assume we are talking about an evaluation impurity, which reveals itself through different derivation hashes and different store path hashes as a result (unless you're using CA derivations, in which case you may only see some rebuilds).

To get to the bottom of this, I'd recommend to push the .drv files to your cache, so that you can substitute them to your local store for comparison with nix-diff. .drv files are normally not pushed, although I'm not sure about cachix in watch mode, which I think your CI setup is using. You can achieve this by calling nix-instantiate instead of nix-build, or something like nix eval --raw .#pkg.drvPath | cachix push <cache>.