Using stack on NixOS

I’ve got myself a new laptop recently and decided to try NixOS. It’s
been a great experience so far, but there are some rough edges. One
of them is stack not completely working out of the box for my
projects.

The reason is that some Haskell packages depend on system C libraries,
but neither stack nor Cabal-the-library are able to find them on
NixOS. As an example, you won’t find /usr/lib/libz.so on my system.
Instead, right now it’s at
/nix/store/2zmlykvqx69q5bh1l3jqyhrj2493vqdx-zlib-1.2.8/lib/libz.so.

Being a NixOS newbie, I’ve tried some solutions but none of them
worked. I’ve then asked for Peter Simon’s help, which he gladly and
swiftly provided (thanks, Peter!). For my use case, I’ve adapted his
suggestions into the following script:

#!/usr/bin/env bash
ZLIB="$(nix-build --no-out-link "<nixpkgs>" -A zlib)"
PSQL="$(nix-build --no-out-link "<nixpkgs>" -A postgresql)"
exec stack                                                             \
     --extra-lib-dirs=${ZLIB}/lib --extra-include-dirs=${ZLIB}/include \
     --extra-lib-dirs=${PSQL}/lib --extra-include-dirs=${PSQL}/include \
     $*

My transitive dependencies need zlib and postgresql libraries, so I
use nix-build to find out where these packages are and pass their
directories to stack explicitly.

This solution is not without drawbacks. The biggest one is that your
built Haskell libraries will be hardcoded to these C libraries, but
NixOS doesn’t know anything about this dependency. If you upgrade
your system and garbage collect the old C libraries, you’ll have to
recompile the Haskell libraries (probably with rm -R
~/.stack/snapshots). However, I quite like its conciseness, and one
doesn’t need to understand much about NixOS’s internals to use it.

At the moment this hack is serving me well. If you’re reading this
blog post more than a couple of months after I wrote it, take a look
around to see if a better solution has been developed in the mean time :).

This entry was posted in Uncategorized. Bookmark the permalink.

4 Responses to Using stack on NixOS

  1. Luca Bruno says:

    Instead of –no-out-link you can –out-link zlib and –out-link postgresql, and they will not be garbage collected until you delete the symlinks.

    • Felipe Lessa says:

      Luca, what would happen if the system’s zlib was upgraded and the nix-build command was executed again? Wouldn’t it return the new zlib’s path and overwrite the zlib symlink created by the previous –out-link?

  2. Luca Bruno says:

    Yes, unless you don’t run nix-build when the symlink is already existing.

    • Felipe Lessa says:

      Hmmm… Well, I guess I prefer just having to be careful about Nix garbage collections (which don’t have to be frequent anyway, thanks to nix-store –optimize) and not having to worry about when nix-build was safe to be used again. But thanks a lot for your suggestion! :)

Leave a Reply to Felipe Lessa Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>