By default I build my project without nix
, and executable is linked statically. But when building with nix
, I want to link it dynamically instead. So I added a switch to myproj.cabal
:
flag dynamic
description: Build only dynamic binaries
default: False
executable RunMe
ghc-options: -O2 -Wall
if !flag(dynamic)
ghc-options: -optl-static -static
Now I can build the project with
stack --nix --nix-packages=zlib install --flag myproj:dynamic
To avoid passing command line options every time, I created shell.nix
:
{ghc}:
with (import <nixpkgs> {});
haskell.lib.buildStackProject {
inherit ghc;
name = "myproj";
buildInputs = [ zlib ];
}
Now, I don't know how to pass flag to cabal from nix file. Based on buildStackProject
definition, I tried setting buildPhase
, e.g.
haskell.lib.buildStackProject {
...
buildPhase = "stack build --flag=myproj:dynamic";
}
but it doesn't seem to change anything. How can I pass the flag to cabal from the nix
file?
Unfortunately, the stack nix integration is rather backwards. It doesn't use nix to build your package (despite the very misleadingbuildStackPackage
), just to create an environment with GHC and native dependencies. You have to use stack
itself to build the project, and since stack
will run cabal
, it should still work with the flag. The stack nix integration will not generate a .nix
file with the dependencies resolved by stack, so you can't build your project with nix-build
and there's no point in entering nix-shell
. You would have to use a tool like stack2nix
or stackage2nix
for that.
So to recap. The shell.nix
above looks fine. Add this to your stack.yaml
:
nix:
shell-file: shell.nix
And build the project with stack:
stack --nix --flag myproj:dynamic
That should build the project with the flag as usual, but use GHC and zlib from nix
.