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
, Это также делает ваш вывод зависимым.
Если это правильно, решение будет либо:
- Удалить
with
так что список входов сборки видит то же самоеghc
как остальная часть вашего кода (используя квалифицированные ссылки для чего-либо еще отpkgs
ты не включил сюда) - Переместить
with
внеlet
так твоя версияghc
является внутренним связыванием (но тогда вы загрязняете пространство имен всего вашего файла всемpkgs
что сбивает с толку, когда становится все сложнее) - В вашем
let
использовать другое имя переменной (myghc
или что-то) и ссылаться на это везде