为n个不同版本构建haskell软件包

时间:2018-07-02 05:03:39

标签: haskell nix

我正在尝试构建bytestring,但由于与quickcheck相关的错误而失败。经过快速检查(不需要双关语)之后,我发现字节串与版本为>= 2.4 && < 2.10的快速检查有关,默认情况下,nix的构建版本为2.10.1

现在阅读this后,我知道可以切换快速检查的版本了。

shell.nix:

{ compiler ? "default", doBenchmark ? false }:

let

config = { packageOverrides = pkgs: rec {
             haskellPackages = pkgs.haskellPackages.override {
               overrides = haskellPackagesNew: haskellPackagesOld: rec {
                 myproject = haskellPackagesNew.callPackage ./default.nix { };
                 QuickCheck = haskellPackagesNew.callPackage ./quickcheck.nix { };
               };
             };
           };
         };

  pkgs = (import <nixpkgs> { inherit config; }).pkgs;

  f = import ./default.nix;

  haskellPackages = if compiler == "default"
                       then pkgs.haskellPackages
                       else pkgs.haskell.packages.${compiler};

  variant = if doBenchmark then pkgs.haskell.lib.doBenchmark else pkgs.lib.id;

  drv = variant (haskellPackages.callPackage f { development = true;});

in

{myproject = if pkgs.lib.inNixShell then drv.env else drv;}

default.nix和quickcheck.nix是使用cabal2nix生成的。

现在,它引发了一个不同的错误,即某些软件包缺少其依赖项,可以通过版本>=2.10进行快速检查。

如何分辨只有字节串会使用自定义版本?

编辑:quickcheck的版本已切换为2.9.2

1 个答案:

答案 0 :(得分:2)

覆盖对单个程序包的依赖性

问题是该软件包集是使用原始的Quickcheck版本创建的。在全球范围内覆盖这样一个经常使用的软件包必然会引起问题。

相反,您可以覆盖依存关系图中的特定边,例如this

myproject.overrideScope (self: super: {
    QuickCheck = haskellPackagesNew.callPackage ./quickcheck.nix { };
  });

可组合性

使用haskellPackages.extend代替overrides可以进一步改善您的示例。在您扩展了软件包集之后,这将为您提供进一步扩展的自由。

您可以进行的另一项更改是在覆盖和覆盖的定义中避免使用rec递归属性集。通常最好改用self。参见此blog post on flyingcircus.io

packageOverrides切换到overlays也是一个好主意。

这些事情可能暂时不会引起问题,但是会导致大型项目出现意外,因此最好首先避免它们。

最终结果

我希望我做对了,因为我没有完整的示例。

{ compiler ? "default", doBenchmark ? false }:

let

  overlays = [(pkgs: super: {
             haskellPackages = super.haskellPackages.extend ( hself: hsuper: {
                 myproject = (hself.callPackage ./default.nix {}).overrideScope (pself: psuper: {
                     QuickCheck = pself.QuickCheck_2_9;
                   });
                 QuickCheck_2_9 = hself.callPackage ./quickcheck.nix { };
               };
             );
           };
         )];

  pkgs = (import <nixpkgs> { inherit overlays; }).pkgs;

  f = import ./default.nix;

  haskellPackages = if compiler == "default"
                       then pkgs.haskellPackages
                       else pkgs.haskell.packages.${compiler};

  variant = if doBenchmark then pkgs.haskell.lib.doBenchmark else pkgs.lib.id;

  drv = variant (haskellPackages.callPackage f { development = true;});

in

{myproject = if pkgs.lib.inNixShell then drv.env else drv;}