当我使用nix时,有什么理由不使用stack --nix?

时间:2017-09-07 07:31:58

标签: haskell-stack nix

我在NixOS,但我认为此问题应适用于使用nix的任何平台。

我通过试验发现,stack可以与几个选项一起用于构建项目,但我不完全理解它们之间的区别,

  1. stack
  2. stack --system-ghc
  3. stack --nix
  4. 问题

    1. 如果我使用的是nix(在我的情况下是NixOS),我有什么理由不想使用--nix参数吗?
    2. 处理haskell项目的nix方式是什么,应该使用cabal(cabal2nix)代替stack
    3. 我发现堆栈正在重建已经由nix安装的大量库,这是什么原因?

1 个答案:

答案 0 :(得分:2)

  1. 据我了解,用于堆叠的--nix选项使用nix-shell来管理 non-Haskell 依赖项(而不是要求它们位于“全局”环境中)该堆栈是从中运行的)。如果要在nix上使用stack工具,这可能是个好主意。堆栈通常还安装自己的GHC:--system-ghc选项可防止这种情况,并要求它在运行它的“全局”环境中使用GHC。我相信有了--nixstack也会要求Nix处理GHC版本控制,因此在Nix系统上,我建议使用--nix而不使用--system-ghc
  2. 至少在我看来,使用Nix时最好避免使用堆栈工具。这是因为即使使用--nix运行时,堆栈也不会通知Nix它要构建的Haskell软件包:它会在~/.stack内部完全构建它们,而不与Nix共享它们。商店。如果您的项目是使用最新的nixpkgs版本的Haskell软件包或相对较少的简单覆盖构建的,cabal2nix是一个很好的解决方案,它将确保Haskell库仅被构建一次(由Nix进行) 。如果要确保使用与stack相同的软件包版本来构建项目,我建议使用stackage2nixstack2nix。我个人一直在使用nixpkgs-stackage覆盖层,该覆盖层与stackage2nix有关:这为您提供了nixpkgs中的LTS软件包集和nixpkgs.haskell.packages.stackage.lib.callStackage2nix,您可以在{{1}中使用它们} / default.nix像这样:shell.nix,无论callStackage2nix (baseNameOf ./.) (cleanSource ./.).${(baseNameOf ./.)}的定义如何适合您的项目(可以使用cleanSource删除一些实际上不应该包含在其中的文件项目,例如自动保存,构建目录等)。

    使用此设置,而不是使用filterSource工具,而是要在项目上进行交互式工作,您应该使用stack来设置一个环境,其中Nix已构建了项目的所有依赖项,并且“安装”。然后,您可以使用nix-shell仅构建您的项目,而不会出现任何依赖关系问题或(重新)构建依赖关系。

  3. 如上所述,cabal-install不与Nix协作,而是尝试在stack中构建每个Haskell依赖项。如果要在遵循与Stack相同的构建计划的同时将所有Haskell软件包保留在Nix商店中(我建议这样做),则需要使用其中一种链接工具或类似工具。