nixOS: как восстановиться после столкновения двух экземпляров одного и того же пакета одной и той же версии

Вот мой nixos версия:

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

Вот мой сценарий оболочки:

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

Здесь проблема. Обратите внимание, что существует конфликт между двумя экземплярами одной и той же версии одного и того же пакета:

$ 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

Я знаю, что если бы пакеты имели разные версии, я мог бы сделать что-то вроде этого:

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

Но так как имена пакетов и версии совпадают, я не знаю, что делать.

Как я могу оправиться от этого?

2 ответа

Решение

При попытке воспроизвести вашу проблему на коммите nixpkgs 125ffffЯ получаю другую ошибку. А именно:

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

Это заставляет меня верить, что <nixpkgs> указывает на другой коммит на вашей машине. Вышеуказанная проблема была исправлена ​​при коммите 7c7417, По состоянию на коммит 80224e (мастер на момент написания), что изменение все еще активно. В этот момент я могу воспроизвести вашу ошибку.

Кажется, проблема в том, что diagrams а также diagrams-pgf, как отдельные пакеты, зависят от разных версий optparse-applicative, Посылка diagrams-pgf имеет всю область действия, переопределяемую более новой версией, что означает, что он также вводит различные версии diagrams и другие зависимости. Это, кажется, вызывает столкновение.

Простое решение для вас должно зависеть только от diagrams-pgf в твоей nix-оболочке. Большинство диаграмм будут отображаться как зависимость diagrams-pgf и, следовательно, все еще будет доступен.

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

Как подтверждено ghc --show-packages:

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

К сожалению, пакет diagrams-svg, который затягивается diagramsне в состоянии построить с новой версией optparse-applicative, Таким образом, в настоящее время невозможно создать среду с обоими diagrams а также diagrams-pgf без исправления некоторых из этих пакетов.

Если тебе надо diagrams-contrib, то следующее должно сделать трюк:

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

ghcWithPackages эффективно создает новый дистрибутив GHC, настроенный для включения в список пакетов, которые вы перечислили. Это отличается от pkgs.ghcне просто вещь, которая от этого зависит; нет смысла устанавливать оба в одной среде. Я думаю, что вы случайно упомянули оба, и именно это и стало причиной столкновения.

Сначала вы делаете свой личный GHC и вводите его в сферу как имя ghc, с помощью let,

Внутри сферы let ты говоришь:

buildInputs = with pkgs; [
  ghc
];

with приносит каждый атрибут pkgs в область видимости для следующего выражения. pkgs имеет ghc атрибут, а with область является самой внутренней областью, содержащей ghc обязательна, так что имеет приоритет над ghc от let,

Ваш shellHook с другой стороны, выходит за рамки with, Итак ${ghc} это ссылка на ваш дай-привязанный ghc, Это также делает ваш вывод зависимым.

Если это правильно, решение будет либо:

  1. Удалить withтак что список входов сборки видит то же самое ghc как остальная часть вашего кода (используя квалифицированные ссылки для чего-либо еще от pkgs ты не включил сюда)
  2. Переместить with вне letтак твоя версия ghc является внутренним связыванием (но тогда вы загрязняете пространство имен всего вашего файла всем pkgsчто сбивает с толку, когда становится все сложнее)
  3. В вашем let использовать другое имя переменной (myghc или что-то) и ссылаться на это везде
Другие вопросы по тегам