Search code examples
haskellnixosnixpkgs

nixOS: how to recover from collision between two instances of same package, same version


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?


Solution

  • 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)
      '';
    }