问题
I am on NixOS
but I think this question should apply to any platform that use nix
.
I found by trial that stack
can be used with couple options to build a project but I don't fully understand difference among them,
stack
stack --system-ghc
stack --nix
Question :
- If I am using nix (NixOS in my case), is there any reason I will want to not use
--nix
argument? - What is the
nix
way to deal with haskell project, shouldcabal
(cabal2nix) be used in stead ofstack
? - I found that stack is rebuilding lots of libraries that already installed by
nix
, what is the reason of that?
回答1:
- As I understand it, the
--nix
option to stack uses anix-shell
to manage non-Haskell dependencies (instead of requiring them to be in the "global" environment that stack is run from). This is probably a good idea if you want to use thestack
tool on nix. Stack also usually installs its own GHC: the--system-ghc
option prevents this, and asks it to use the GHC in the "global" environment from which it is run. I believe that with--nix
,stack
will ask Nix to handle GHC versioning as well, so on a Nix system, I would recommend building with--nix
and without--system-ghc
At least in my opinion, it is better to avoid the stack tooling when working with Nix. This is because stack, even when run with
--nix
, does not inform Nix about the Haskell packages that it wants to build: it builds them all itself inside~/.stack
, and doesn't share them with the Nix store. If your project builds with the latestnixpkgs
versions of Haskell packages, or with relatively few simple overrides on those,cabal2nix
is a great solution that will make sure that Haskell libraries only get built once (by Nix). If you want to make sure that you are building your project with the same package versions asstack
would, I would recommend stackage2nix or stack2nix. I personally have been using the nixpkgs-stackage overlay, which is related tostackage2nix
: this gives you both LTS package sets in nixpkgs, andnixpkgs.haskell.packages.stackage.lib.callStackage2nix
, which you can use in yourdefault.nix
/shell.nix
like so:callStackage2nix (baseNameOf ./.) (cleanSource ./.).${(baseNameOf ./.)}
, with whatever definition ofcleanSource
fits your project (this can usefilterSource
to remove some files which shouldn't really be considered part of the project, like autosaves, build directories, etc.).With this setup, instead of using the
stack
tooling, for interactive work on the project you should usenix-shell
to set up an environment where Nix has built all of the dependencies of your project and "installed" them. Then you can just usecabal-install
to build just your project, without any dependency issues or (re)building dependencies.- As mentioned above,
stack
does not coordinate with Nix, and tries to build every Haskell dependency itself in~/.stack
. If you want to keep all of your Haskell packages in the Nix store (which I would recommend) while following the same build plans as Stack, you will need to use one of the linked tools, or something similar.
来源:https://stackoverflow.com/questions/46090460/what-is-reason-not-to-use-stack-nix-when-i-using-nix