代码之家  ›  专栏  ›  技术社区  ›  Jonathan

如何在Nix中创建Haskell开发环境?

  •  0
  • Jonathan  · 技术社区  · 6 年前

    我试图为一个web项目创建一个Haskell开发环境 hakyll , blaze ,和 clay . 只是,克莱似乎没有建好,抱怨说 Setup: Encountered missing dependencies: hspec >=2.2.0 && <2.6, hspec-discover >=2.2.0 && <2.6 ,而我似乎无法克服这一点。

    我试过跑步 cabal2nix . --shell > shell.nix 在这个阴谋集团档案上:

    name:               open-editions
    version:            0.1.0.0
    build-type:         Simple
    cabal-version:      >= 1.10
    
    executable site
      main-is:          site.hs
      build-depends:    base == 4.*
                      , blaze-html
                      , clay
                      , hakyll == 4.12.*
      ghc-options:      -threaded
      default-language: Haskell2010
    

    但是我遇到了缺少依赖关系的问题。有什么想法吗?

    编辑:这是我用cabal2nix从上面生成的shell.nix:

    { nixpkgs ? import <nixpkgs> {}, compiler ? "default", doBenchmark ? false }:
    
    let
    
      inherit (nixpkgs) pkgs;
    
      f = { mkDerivation, base, blaze-html, clay, hakyll, stdenv }:
          mkDerivation {
            pname = "open-editions";
            version = "0.1.0.0";
            src = ./.;
            isLibrary = false;
            isExecutable = true;
            executableHaskellDepends = [ base blaze-html clay hakyll ];
            license = "unknown";
            hydraPlatforms = stdenv.lib.platforms.none;
          };
    
      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 {});
    
    in
    
      if pkgs.lib.inNixShell then drv.env else drv
    

    下面是我试图修改它,使其覆盖粘土的方法:

    { haskellLib, super, nixpkgs ? import <nixpkgs> {}, compiler ? "default", doBenchmark ? false }:
    
    let
    
      inherit (nixpkgs) pkgs;
    
      clay = haskellLib.doJailbreak super.clay;
    
      f = { mkDerivation, base, blaze-html, clay, hakyll, stdenv }:
          mkDerivation {
            pname = "open-editions";
            version = "0.1.0.0";
            src = ./.;
            isLibrary = false;
            isExecutable = true;
            executableHaskellDepends = [ base blaze-html clay hakyll ];
            license = "unknown";
            hydraPlatforms = stdenv.lib.platforms.none;
          };
    
      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 {});
    
    in
    
      if pkgs.lib.inNixShell then drv.env else drv
    

    但我显然做错了,因为我得到了: error: cannot auto-call a function that has an argument without a default value ('haskellLib') .

    0 回复  |  直到 6 年前
        1
  •  2
  •   Jan Tojnar    6 年前

    这通常是由于一个包固定了旧版本的依赖项(在nixpkgs中不可用)造成的。彼得是 correct 那块粘土需要撞击 hspec version .

    但是,您可以尝试通过在nixpkgs中越狱包(删除版本界限)来临时修复它,请参见:

    https://github.com/NixOS/nixpkgs/blob/cc98350d55522ebb2b7d35db32bc7c2fc5b8b273/pkgs/development/haskell-modules/configuration-common.nix#L1088-L1089

    如果包不是用较新版本的hspec构建的,则可以尝试将旧版本添加到包集中并重写包以使用它:

    https://github.com/NixOS/nixpkgs/blob/cc98350d55522ebb2b7d35db32bc7c2fc5b8b273/pkgs/development/haskell-modules/configuration-common.nix#L1170

    但这需要重新生成 hackage-packages.nix 所以我不推荐。

    最好对包进行修补以支持更新版本的依赖项,并将修补程序添加到覆盖:

    https://github.com/NixOS/nixpkgs/blob/cc98350d55522ebb2b7d35db32bc7c2fc5b8b273/pkgs/development/haskell-modules/configuration-common.nix#L1187-L1190

    也不要忘了在上游打开一个问题——我看到你了 already did 或者是一个请求。

        2
  •  1
  •   InvisiblePanda    5 年前

    可能已经不太相关了,但是我遇到了同样的问题 clay .

    我使用覆盖来修改(Haskell)包集。看起来像这样 overlays.nix ):

    let
      customHaskellPackages = self: super: {
        haskellPackages = super.haskellPackages.override {
          overrides = hself: hsuper: {
            # Since clay is not really maintained any longer, the upper
            # version bounds have gone stale.
            # Everything works fine; we just need to free it from its
            # too-tight chains.
            clay =
              super.haskell.lib.doJailbreak
                hsuper.clay;
    
            # Other packages would go here, too
            some-foo-package =
              super.haskell.lib.dontCheck
                (hself.callPackage ./some-foo-package.nix {});
          };
        };
      };
    in
    [ customHaskellPackages ]
    

    我的 default.nix 是由 cabal2nix . > default.nix 从我的密谋文件中,它依次指定 黏土 作为一种依赖。

    在a中(非常简单) release.nix 文件可以按如下方式使用覆盖:

    let
      overlays = import ./nix/overlays.nix;
      # I might have needed this for clay, but it might have been sth else
      config = { allowBroken = true; };
      pkgs = import <nixpkgs> { inherit config; inherit overlays; };
    in
    pkgs.haskellPackage.myApplication
    # Or use haskellPackages.callPackage ./something.nix {} here if you didn't
    # add your project to haskellPackages in the overlay
    

    之后, nix-build release.nix 工作得很好。 我不使用 --shell 创建 shell.nix 文件,但自己创建并导入 release.nix版本 文件。然后我通过添加一些构建工具来丰富我的shell环境。这也和预期的一样。