使用 nix 时不使用 stack --nix 的原因是什么?
What is reason not to use stack --nix when I using nix?
我在 NixOS
但我认为这个问题应该适用于任何使用 nix
.
的平台
我通过试验发现stack
可以与几个选项一起使用来构建一个项目,但我不完全理解它们之间的区别,
stack
stack --system-ghc
stack --nix
问题:
- 如果我使用的是 nix(在我的例子中是 NixOS),我有什么理由不想使用
--nix
参数吗?
- 处理haskell项目的
nix
方法是什么,应该用cabal
(cabal2nix)代替stack
吗?
- 我发现堆栈正在重建许多
nix
已经安装的库,这是什么原因?
据我了解,堆栈的--nix
选项使用nix-shell
来管理非Haskell依赖项(而不是要求它们处于堆栈 运行 来自的“全局”环境中)。如果您想在 nix 上使用 stack
工具,这可能是个好主意。 Stack 通常还会安装自己的 GHC:--system-ghc
选项会阻止这种情况,并要求它在 运行 所在的“全局”环境中使用 GHC。我相信使用 --nix
,stack
也会要求 Nix 处理 GHC 版本控制,所以在 Nix 系统上,我建议使用 --nix
构建而不使用 --system-ghc
至少在我看来,在使用 Nix 时最好避免堆栈工具。这是因为堆栈,即使 运行 和 --nix
,也不会通知 Nix 它想要构建的 Haskell 包:它在 ~/.stack
中自行构建它们,并且不与 Nix 商店共享它们。如果您的项目使用 Haskell 包的最新 nixpkgs
版本构建,或者对这些包进行相对较少的简单覆盖,cabal2nix
是一个很好的解决方案,可以确保 Haskell 库只构建一次(由 Nix)。如果你想确保你正在使用与 stack
相同的包版本构建你的项目,我会推荐 stackage2nix or stack2nix. I personally have been using the nixpkgs-stackage overlay,它与 stackage2nix
相关:这为你提供了 LTS nixpkgs 和 nixpkgs.haskell.packages.stackage.lib.callStackage2nix
中的软件包集,您可以像这样在 default.nix
/shell.nix
中使用它们:callStackage2nix (baseNameOf ./.) (cleanSource ./.).${(baseNameOf ./.)}
,无论 cleanSource
的定义是否适合您的项目(这可以使用 filterSource
删除一些不应该真正被视为项目一部分的文件,如自动保存、构建目录等)。
使用此设置,而不是使用 stack
工具,对于项目的交互式工作,您应该使用 nix-shell
来设置一个环境,Nix 已经在其中构建了项目的所有依赖项并“安装”它们。然后你可以只使用 cabal-install
来构建你的项目,没有任何依赖性问题或(重新)构建依赖性。
如上所述,stack
不与 Nix 协调,并试图在 ~/.stack
中构建每个 Haskell 依赖本身。如果您想将所有 Haskell 包保留在 Nix 商店(我会推荐),同时遵循与 Stack 相同的构建计划,您将需要使用其中一种链接工具或类似工具。
我在 NixOS
但我认为这个问题应该适用于任何使用 nix
.
我通过试验发现stack
可以与几个选项一起使用来构建一个项目,但我不完全理解它们之间的区别,
stack
stack --system-ghc
stack --nix
问题:
- 如果我使用的是 nix(在我的例子中是 NixOS),我有什么理由不想使用
--nix
参数吗? - 处理haskell项目的
nix
方法是什么,应该用cabal
(cabal2nix)代替stack
吗? - 我发现堆栈正在重建许多
nix
已经安装的库,这是什么原因?
据我了解,堆栈的
--nix
选项使用nix-shell
来管理非Haskell依赖项(而不是要求它们处于堆栈 运行 来自的“全局”环境中)。如果您想在 nix 上使用stack
工具,这可能是个好主意。 Stack 通常还会安装自己的 GHC:--system-ghc
选项会阻止这种情况,并要求它在 运行 所在的“全局”环境中使用 GHC。我相信使用--nix
,stack
也会要求 Nix 处理 GHC 版本控制,所以在 Nix 系统上,我建议使用--nix
构建而不使用--system-ghc
至少在我看来,在使用 Nix 时最好避免堆栈工具。这是因为堆栈,即使 运行 和
--nix
,也不会通知 Nix 它想要构建的 Haskell 包:它在~/.stack
中自行构建它们,并且不与 Nix 商店共享它们。如果您的项目使用 Haskell 包的最新nixpkgs
版本构建,或者对这些包进行相对较少的简单覆盖,cabal2nix
是一个很好的解决方案,可以确保 Haskell 库只构建一次(由 Nix)。如果你想确保你正在使用与stack
相同的包版本构建你的项目,我会推荐 stackage2nix or stack2nix. I personally have been using the nixpkgs-stackage overlay,它与stackage2nix
相关:这为你提供了 LTS nixpkgs 和nixpkgs.haskell.packages.stackage.lib.callStackage2nix
中的软件包集,您可以像这样在default.nix
/shell.nix
中使用它们:callStackage2nix (baseNameOf ./.) (cleanSource ./.).${(baseNameOf ./.)}
,无论cleanSource
的定义是否适合您的项目(这可以使用filterSource
删除一些不应该真正被视为项目一部分的文件,如自动保存、构建目录等)。使用此设置,而不是使用
stack
工具,对于项目的交互式工作,您应该使用nix-shell
来设置一个环境,Nix 已经在其中构建了项目的所有依赖项并“安装”它们。然后你可以只使用cabal-install
来构建你的项目,没有任何依赖性问题或(重新)构建依赖性。如上所述,
stack
不与 Nix 协调,并试图在~/.stack
中构建每个 Haskell 依赖本身。如果您想将所有 Haskell 包保留在 Nix 商店(我会推荐),同时遵循与 Stack 相同的构建计划,您将需要使用其中一种链接工具或类似工具。