Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New per-machine nixpkgs merge causes pkgs.pkgsi686Linux to be cross-compiled #68

Closed
delroth opened this issue Sep 8, 2019 · 1 comment · Fixed by #70

Comments

@delroth
Copy link

commented Sep 8, 2019

Test case: have a morph deployment with hardware.pulseaudio.support32Bit = true;

Current behavior: morph build cross-builds half of the world to build an i686 alsa-plugins package.

Expected behavior: morph build does not do that, which is what happens with e.g. nixops or nixos-rebuild on the same config.

Can be easily repro'd by trying to build anything from pkgsi686Linux:

nix-build eval-machines.nix -A 'nodes.mynode.pkgs.pkgsi686Linux.alsaPlugins' --arg networkExpr mynet.nix

cc @Shados

@Shados

This comment has been minimized.

Copy link
Contributor

commented Sep 8, 2019

Ugh, I dug into this one and figured it out, it's a result of the definition of pkgsi686Linux (and also at least pkgsMusl) implicitly relying on nixpkgs being imported impurely (via pkgs/top-level/impure.nix rather than pkgs/top-level/default.nix). morph does import it impurely, but explicitly setting crossSystem breaks a subtle assumption later in nixpkgs' eval machinery.

Details:
In the definition of pkgsi686Linux, it uses a check on stdenv.hostPlatform and stdenv.buildPlatform being equivalent (which is typically the case), in order to determine whether to override localSystem or crossSystem in its call to nixpkgsFun (which hackily re-evaluates nixpkgs).
https://github.com/NixOS/nixpkgs/blob/e82b8fa7f7890e819bb4de6ce1f8e20d5a5a4c53/pkgs/top-level/stage.nix#L183-L193

The issue here is that it leaves the other localSystem/crossSystem argument unset, and if you look at the definition of that here you can see that means it defaults to whatever arguments were given to nixpkgs originally and captured by the args @-pattern.

Normally, crossSystem is defaulted to null when evaluating nixpkgs impurely, then that null is passed on to the pure eval machinery, within which it is defaulted to localSystem if it is null.

See the problem? If we let the impure null crossSystem default be passed on to the pure eval machinery, then nixpkgsFun captures that null, and i686PkgsLinux later re-evaluates nixpkgs with a modifed localSystem and a null crossSystem, which then results in crossSystem within that re-eval being defaulted to the modified localSystem.

If instead we explicitly pass crossSystem originally, then crossSystem within the i686PkgsLinux re-eval is not defaulted to the i686 localSystem, and cross-compiling occurs.

We could "fix" this in morph by changing the nixpkgs.pkgs default to only set crossSystem if localSystem != crossSystem, and we probably should... but I also think this represents an upstream bug in nixpkgs. pkgsi686Linux shouldn't be reliant on a detail of how the default impure nixpkgs eval expression functions =/.

Shados added a commit to Shados/morph that referenced this issue Sep 8, 2019

@johanot johanot closed this in #70 Sep 9, 2019

johanot added a commit that referenced this issue Sep 9, 2019
Merge pull request #70 from Shados/fix-issue-68
Workaround/fix for issue #68

@johanot johanot added this to the 1.3.1 milestone Sep 9, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.