My current interest circles around how to use Nix for Haskell development. The following links provide a very good overview:
In this blog post I want to investigate how Nix actually builds Haskell targets, i.e. what drops out of all the *.nix files.
Reading into all these files is quite a mouthful! But the nice thing is we don’t need to do that! The whole purpose of a Nix expression is to eventually produce a derivation that will be built. As an example the following line will drop us into a new shell environment with a ghc executable and the lens and mtl libraries installed:
Now we know where to find the derivation and we can print it to a file.
This is actually pretty straight forward to read. We can ignore the “inputDrvs” attribute, as it is mostly relevant for Nix, not to understand what’s going on. We want to look at “builder”, “args” and “env”. Nix will call the builder with the given arguments from “args” and inject the variables from “env” into the environment of the call to builder. Ignoring most of the environment variables and the exact paths this will more or less result in the following call:
All this script does is sym-linking every library in the output directory of the derivation in the Nix store and then create small wrapper scripts for all the necessary executables (ghc, runghc, etc.). Finally the packages are recached into the respective installation of GHC.
So we call the specified version of ghc, ghc-8.6.3 in this case, and tell it where to find its libraries. As it is typical for Nix the ghc executable is located in its respective location in the store and the environment is set up so that everything works together.