Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is reason not to use stack --nix when I using nix?

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,

  1. stack
  2. stack --system-ghc
  3. stack --nix

Question :

  1. If I am using nix (NixOS in my case), is there any reason I will want to not use --nix argument?
  2. What is the nix way to deal with haskell project, should cabal (cabal2nix) be used in stead of stack?
  3. I found that stack is rebuilding lots of libraries that already installed by nix, what is the reason of that?
like image 685
wizzup Avatar asked Oct 17 '22 06:10

wizzup


1 Answers

  1. 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

  2. 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.

  3. 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.

like image 95
Peter Amidon Avatar answered Oct 21 '22 07:10

Peter Amidon