nixOS:如何从同一包、同一版本的两个实例之间的冲突中恢复
nixOS: how to recover from collision between two instances of same package, same version
这是我的 nixos
版本:
$ nixos-version
16.09pre85931.125ffff (Flounder)
这是我的 shell 脚本:
$ 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>
但是因为包名和版本都一样,不知道怎么办
我该如何恢复?
ghcWithPackages
有效地创建了一个全新的 GHC 发行版,经过定制以包含您列出的软件包。那是和pkgs.ghc
不一样的东西,不仅仅是依赖它的东西;将两者安装到同一环境中没有意义。我认为您不小心提到了两者,这就是导致冲突的原因。
首先,您制作自己的 GHC 并将其作为名称 ghc
纳入范围,使用 let
。
在你说的let
范围内:
buildInputs = with pkgs; [
ghc
];
with
将 pkgs
的每个属性都纳入以下表达式的范围。 pkgs
有一个 ghc
属性,而 with
作用域是包含 ghc
绑定的最内层作用域,因此它优先于 ghc
来自 let
.
另一方面,您的 shellHook
在 with
的范围之外。所以 ${ghc}
是对你的 let-bound ghc
的引用。这使得您的推导也依赖于此。
如果这是正确的,解决方案将是:
- 删除
with
,因此构建输入列表与您的其余代码看到相同的 ghc
(对您未包含的 pkgs
中的任何其他内容使用合格的引用这里)
- 将
with
移到 let
之外,因此您的 ghc
版本是最内层的绑定(但随后您用 [=17] 中的所有内容污染了整个文件的名称空间=],当它变得更复杂时会变得混乱)
- 在你的
let
中使用不同的变量名称(myghc
或其他名称)并在任何地方引用它
当试图在 nixpkgs commit 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
(撰写本文时为 master),该更改仍然有效。到那时我可以重现你的错误。
似乎存在的问题是,diagrams
和 diagrams-pgf
作为单独的软件包,取决于 optparse-applicative
的不同版本。包 diagrams-pgf
的整个范围都被新版本覆盖,这意味着它还引入了不同版本的 diagrams
和其他依赖项。这似乎导致了碰撞。
一个简单的解决方法应该是只依赖于你的 nix-shell 中的 diagrams-pgf
。大多数图表将作为 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
引入的包 diagrams-svg
无法使用新版本 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)
'';
}
这是我的 nixos
版本:
$ nixos-version
16.09pre85931.125ffff (Flounder)
这是我的 shell 脚本:
$ 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>
但是因为包名和版本都一样,不知道怎么办
我该如何恢复?
ghcWithPackages
有效地创建了一个全新的 GHC 发行版,经过定制以包含您列出的软件包。那是和pkgs.ghc
不一样的东西,不仅仅是依赖它的东西;将两者安装到同一环境中没有意义。我认为您不小心提到了两者,这就是导致冲突的原因。
首先,您制作自己的 GHC 并将其作为名称 ghc
纳入范围,使用 let
。
在你说的let
范围内:
buildInputs = with pkgs; [
ghc
];
with
将 pkgs
的每个属性都纳入以下表达式的范围。 pkgs
有一个 ghc
属性,而 with
作用域是包含 ghc
绑定的最内层作用域,因此它优先于 ghc
来自 let
.
另一方面,您的 shellHook
在 with
的范围之外。所以 ${ghc}
是对你的 let-bound ghc
的引用。这使得您的推导也依赖于此。
如果这是正确的,解决方案将是:
- 删除
with
,因此构建输入列表与您的其余代码看到相同的ghc
(对您未包含的pkgs
中的任何其他内容使用合格的引用这里) - 将
with
移到let
之外,因此您的ghc
版本是最内层的绑定(但随后您用 [=17] 中的所有内容污染了整个文件的名称空间=],当它变得更复杂时会变得混乱) - 在你的
let
中使用不同的变量名称(myghc
或其他名称)并在任何地方引用它
当试图在 nixpkgs commit 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
(撰写本文时为 master),该更改仍然有效。到那时我可以重现你的错误。
似乎存在的问题是,diagrams
和 diagrams-pgf
作为单独的软件包,取决于 optparse-applicative
的不同版本。包 diagrams-pgf
的整个范围都被新版本覆盖,这意味着它还引入了不同版本的 diagrams
和其他依赖项。这似乎导致了碰撞。
一个简单的解决方法应该是只依赖于你的 nix-shell 中的 diagrams-pgf
。大多数图表将作为 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
引入的包 diagrams-svg
无法使用新版本 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)
'';
}