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 :
--nix
argument?nix
way to deal with haskell project, should cabal
(cabal2nix) be used in stead of stack
? nix
, what is the reason of that?As I understand it, the --nix
option to stack uses a nix-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 the stack
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 latest nixpkgs
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 as stack
would, I would recommend stackage2nix or stack2nix. I personally have been using the nixpkgs-stackage overlay, which is related to stackage2nix
: this gives you both LTS package sets in nixpkgs, and nixpkgs.haskell.packages.stackage.lib.callStackage2nix
, which you can use in your default.nix
/shell.nix
like so: callStackage2nix (baseNameOf ./.) (cleanSource ./.).${(baseNameOf ./.)}
, with whatever definition of cleanSource
fits your project (this can use filterSource
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 use nix-shell
to set up an environment where Nix has built all of the dependencies of your project and "installed" them. Then you can just use cabal-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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With