【问题标题】:nixOS: how to recover from collision between two instances of same package, same versionnixOS:如何从相同包,相同版本的两个实例之间的冲突中恢复
【发布时间】:2017-02-28 13:41:00
【问题描述】:

这是我的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>

但是由于包名和版本都一样,不知道怎么办。

我该如何恢复?

【问题讨论】:

    标签: haskell nixos nixpkgs


    【解决方案1】:

    ghcWithPackages 有效地创建了一个全新的 GHC 发行版,定制为包含您列出的软件包。这与pkgs.ghc 不同,不仅仅是依赖它的东西;将两者安装到同一个环境中是没有意义的。我认为您不小心提到了两者,这就是造成冲突的原因。

    首先,您创建您的个人 GHC 并将其作为名称 ghc 引入范围,使用 let

    let你说的范围内:

    buildInputs = with pkgs; [
      ghc
    ];
    

    withpkgs 的每个属性都带入以下表达式的范围。 pkgs 有一个ghc 属性,而with 范围是包含ghc 绑定的最内层范围,因此优先于let 中的ghc

    另一方面,您的shellHook 不在with 的范围内。所以${ghc} 是对你的let-bound ghc 的引用。这使得你的推导也依赖于此。

    如果正确,解决方案是:

    1. 删除with,因此构建输入列表会看到与您的其余代码相同的ghc(使用来自pkgs 的任何其他内容的合格引用,您未在此处包含)
    2. with 移到let 之外,因此您的ghc 版本是最里面的绑定(但随后您会使用pkgs 中的所有内容污染整个文件的命名空间,当它变得更多时会变得混乱复杂)
    3. 在您的 let 中使用不同的变量名称(myghc 或其他名称)并在任何地方引用它

    【讨论】:

    • @helpwithhaskell 啊,那我可能搞错了原因。我在我的手机 atm 上,遗憾的是它没有运行 nix,所以我现在无法调试。
    【解决方案2】:

    当尝试在 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
    

    这让我相信&lt;nixpkgs&gt; 指向您机器上的不同提交。 上述问题已在提交 7c7417 处得到修复。截至提交80224e(撰写本文时的主人),该更改仍然有效。那时我可以重现你的错误。

    似乎存在的问题是,diagramsdiagrams-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 构建。因此,目前无法在不修补其中一些软件包的情况下构建同时具有diagramsdiagrams-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)
      '';
    }
    

    【讨论】:

      猜你喜欢
      • 2012-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-14
      • 2014-11-17
      • 2012-08-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多