4

Here is my nixos version:

$ nixos-version 
16.09pre85931.125ffff (Flounder)

Here is my shell script:

$ cat test.nix 
{ nixpkgs ? import <nixpkgs> {
}, compiler ? "ghc801" }:

let
  inherit (nixpkgs) pkgs;
  ghc = pkgs.haskell.packages.${compiler}.ghcWithPackages (ps: with ps; [
    diagrams
    diagrams-pgf
  ]);
in
pkgs.stdenv.mkDerivation {
  name = "test";
  buildInputs = with pkgs; [
    ghc
  ];
  shellHook = ''
    eval $(egrep ^export ${ghc}/bin/ghc)
  '';
}

Here is the problem. Note that there is a collision between two instances of the same version of the same package:

$ nix-shell --pure test.nix 
these derivations will be built:
  /nix/store/r6080kvlvdb16c1frz8alnm14xjizkf5-ghc-8.0.1.drv
building path(s) ‘/nix/store/1129nds6xhq6hqawdd2s9z9n6va57jgl-ghc-8.0.1’
collision between `/nix/store/amdnmbd8p52d49bqmphv9f7ly7lf7pkk-active-0.2.0.10/share/doc/x86_64-linux-ghc-8.0.1/active-0.2.0.10/html/Data-Active.html' and `/nix/store/yniw6akz2ldimdlj9yq968ldaf4j18h1-active-0.2.0.10/share/doc/x86_64-linux-ghc-8.0.1/active-0.2.0.10/html/Data-Active.html'
builder for ‘/nix/store/r6080kvlvdb16c1frz8alnm14xjizkf5-ghc-8.0.1.drv’ failed with exit code 255
error: build of ‘/nix/store/r6080kvlvdb16c1frz8alnm14xjizkf5-ghc-8.0.1.drv’ failed
/run/current-system/sw/bin/nix-shell: failed to build all dependencies

I know that if the packages had different versions then I could do something like this:

$ nix-env --set-flag priority 15 <package>-<version>

But since the package names and versions are the same, I don't know what to do.

How can I recover from this?

helpwithhaskell
  • 538
  • 4
  • 12

2 Answers2

2

ghcWithPackages effectively creates a brand new distribution of GHC, customised to include the packages you've listed. That is a different thing from pkgs.ghc, not just a thing that depends on it; it doesn't make sense to install both into the same environment. I think you've accidentally referred to both, and that's what's causing the collision.

First you make your personal GHC and bring it into scope as the name ghc, using let.

Inside the scope of the let you say:

buildInputs = with pkgs; [
  ghc
];

The with brings every attribute of pkgs into scope for the following expression. pkgs has a ghc attribute, and the with scope is the innermost scope containing a ghc binding, so that takes precedence over the ghc from the let.

Your shellHook on the other hand is outside the scope of the with. So the ${ghc} is a reference to your let-bound ghc. This makes your derivation depend on that, too.

If that's correct, the solution would be either:

  1. Remove the with, so the build inputs list sees the same ghc as the rest of your code (using qualified references for anything else from pkgs you haven't included here)
  2. Move the with outside the let, so your version of ghc is the innermost binding (but then you pollute the namespace of your whole file with everything from pkgs, which gets confusing when it gets more complicated)
  3. In your let use a different variable name (myghc or something) and refer to that everywhere
Ben
  • 56,956
  • 19
  • 113
  • 151
  • @helpwithhaskell Ah, I might have been wrong about the cause then. I'm on my phone atm, which sadly doesn't run nix, so I can't debug right now. – Ben Oct 19 '16 at 06:20
2

When trying to reproduce your issue at nixpkgs commit 125ffff, I get a different error. Namely:

src/System/Texrunner/Online.hs:45:1: warning: [-Wunused-imports]
    The import of ‘Control.Applicative’ is redundant
      except perhaps to import instances from ‘Control.Applicative’
    To import instances alone, use: import Control.Applicative()
[3 of 3] Compiling System.Texrunner ( src/System/Texrunner.hs, dist/build/System/Texrunner.o )

src/System/Texrunner.hs:18:1: warning: [-Wunused-imports]
    The import of ‘Control.Applicative’ is redundant
      except perhaps to import instances from ‘Control.Applicative’
    To import instances alone, use: import Control.Applicative()
Preprocessing test suite 'tests' for texrunner-0.0.1.1...
[1 of 2] Compiling Tex.PDF          ( tests/Tex/PDF.hs, dist/build/tests/tests-tmp/Tex/PDF.dyn_o )
[2 of 2] Compiling Main             ( tests/Tests.hs, dist/build/tests/tests-tmp/Main.dyn_o )

tests/Tests.hs:5:1: error:
    Failed to load interface for ‘Tex.LogParse’
    Use -v to see a list of the files searched for.
builder for ‘/nix/store/g3mwscrvwsr9zrr5h14d59w7nh06qmsw-texrunner-0.0.1.1.drv’ failed with exit code 1
cannot build derivation ‘/nix/store/9las78qbxqrlhakhdiqwc2jf7g6i5688-ghc-8.0.1.drv’: 1 dependencies couldn't be built
error: build of ‘/nix/store/9las78qbxqrlhakhdiqwc2jf7g6i5688-ghc-8.0.1.drv’ failed

This leads me to believe that <nixpkgs> points to a different commit on your machine. The above issue was fixed at commit 7c7417. As of commit 80224e (master at the time of writing) that change is still active. At that point I can reproduce your error.

The issue there seems to be, that diagrams and diagrams-pgf, as separate packages, depend on different versions of optparse-applicative. The package diagrams-pgf has its whole scope overriden with the newer version, meaning that it also introduces different versions of diagrams and other dependencies. That seems to cause the collision.

A simple fix for you should be to only depend on diagrams-pgf in your nix-shell. Most of diagrams will be pulled in as a dependency of diagrams-pgf and will therefore still be available.

{ nixpkgs ? import <nixpkgs> {
}, compiler ? "ghc801" }:

let
  inherit (nixpkgs) pkgs;
  ghc = pkgs.haskell.packages.${compiler}.ghcWithPackages (ps: with ps; [
    diagrams-pgf # <--- HERE
  ]);
in
pkgs.stdenv.mkDerivation {
  name = "test";
  buildInputs = with pkgs; [
    ghc
  ];
  shellHook = ''
    eval $(egrep ^export ${ghc}/bin/ghc)
  '';
}

As confirmed by ghc --show-packages:

$ ghc --show-packages | grep 'name: diagrams'
name: diagrams-lib
name: diagrams-solve
name: diagrams-core
name: diagrams-pgf

Unfortunately, the package diagrams-svg, which is pulled in by diagrams, fails to build with the new version of optparse-applicative. So, it is currently not possible to build an environment with both diagrams and diagrams-pgf without patching some of these packages.

If you need diagrams-contrib, then the following should do the trick:

{ nixpkgs ? import ~/src/nixpkgs {}
, compiler ? "ghc801" }:

let
  inherit (nixpkgs) pkgs;
  ghc = pkgs.haskell.packages.${compiler}.ghcWithPackages (ps: with ps; [
    (diagrams-contrib.overrideScope (self: super: {
      optparse-applicative = self.optparse-applicative_0_13_0_0;
    })) # <--- HERE
    diagrams-pgf
  ]);
in
pkgs.stdenv.mkDerivation {
  name = "test";
  buildInputs = with pkgs; [
    ghc
  ];
  shellHook = ''
    eval $(egrep ^export ${ghc}/bin/ghc)
  '';
}
Lemming
  • 3,445
  • 3
  • 18
  • 32