Skip to content

Commit 769bdf7

Browse files
committed
Add NixOS and Nix flake section
1 parent 5b14489 commit 769bdf7

File tree

1 file changed

+76
-3
lines changed

1 file changed

+76
-3
lines changed

doc/nix_integration.md

Lines changed: 76 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55
(since 0.1.10.0)
66

77
When using the Nix integration, Stack handles Haskell dependencies as usual
8-
while Nix handles _non-Haskell_ dependencies needed by these Haskell packages.
8+
while the Nix handles _non-Haskell_ dependencies needed by these Haskell packages.
99
So Stack downloads Haskell packages from [Stackage](https://www.stackage.org/lts)
1010
and builds them locally but uses Nix to download
1111
[Nix packages][nix-search-packages] that provide the GHC compiler and
1212
external C libraries that you would normally install manually.
13-
You can install Nix with all the necessary commandline tools from the
14-
[Nix download page](http://nixos.org/nix/download.html).
13+
You can install the Nix package manager with all the necessary commandline tools
14+
from the [Nix download page](http://nixos.org/nix/download.html).
1515

1616
`stack` can automatically create a Nix build environment in the background
1717
using `nix-shell`, similar to building inside an isolated
@@ -289,6 +289,79 @@ The `stack build` command will behave exactly the same as above. Note
289289
that specifying both `packages:` and a `shell-file:` results in an
290290
error. (Comment one out before adding the other.)
291291

292+
## Stack on NixOS
293+
294+
When using Stack on NixOS, you have no choice but to use Stack's Nix integration to
295+
install GHC, because external C libraries in NixOS are not installed in the usual
296+
distro folders. So a GHC compiler installed through Stack (without Nix) can't find
297+
those libraries and therefore can't build most projects. GHC provided through Nix
298+
is patched in a way that it finds the external C libraries listed and provided through Nix.
299+
A detailed tutorial on how to configure Stack so that it supports NixOS and non-Nix users
300+
can be found [here](https://www.tweag.io/blog/2022-06-02-haskell-stack-nix-shell/). A corresponding
301+
example project can be found [here](https://github.com/tweag/haskell-stack-nix-example).
302+
303+
If you're already using Nix flakes, here's an adaption of that example:
304+
Add the following `flake.nix` file to your project.
305+
306+
```nix
307+
{
308+
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
309+
inputs.flake-utils.url = "github:numtide/flake-utils";
310+
311+
outputs = { self, nixpkgs, flake-utils }:
312+
flake-utils.lib.eachDefaultSystem (system:
313+
let
314+
pkgs = nixpkgs.legacyPackages.${system};
315+
# Wrap Stack to configure Nix integration and target the correct Stack-Nix file
316+
#
317+
# - nix: Enable Nix support
318+
# - no-nix-pure: Pass environment variables, like `NIX_PATH`
319+
# - nix-shell-file: Specify the Nix file to use (otherwise it uses `shell.nix` by default)
320+
stack-wrapped = pkgs.symlinkJoin {
321+
name = "stack";
322+
paths = [ pkgs.stack ];
323+
buildInputs = [ pkgs.makeWrapper ];
324+
postBuild = ''
325+
wrapProgram $out/bin/stack \
326+
--add-flags "\
327+
--nix \
328+
--no-nix-pure \
329+
--nix-shell-file=flake-stack-integration.nix \
330+
"
331+
'';
332+
};
333+
in {
334+
devShells.default = pkgs.mkShell {
335+
buildInputs = [ stack-wrapped ];
336+
337+
# Configure the Nix path to our own pinned package set, to ensure Stack uses the same one rather than another global <nixpkgs> when looking for the right `ghc` argument to pass in `flake-stack-integration.nix`
338+
# See https://nixos.org/nixos/nix-pills/nix-search-paths.html for more information
339+
NIX_PATH = "nixpkgs=" + pkgs.path;
340+
};
341+
});
342+
}
343+
344+
```
345+
346+
Then also add the following `flake-stack-integration.nix` file to your project:
347+
348+
```nix
349+
{ ghc }:
350+
with (import <nixpkgs> { });
351+
352+
haskell.lib.buildStackProject {
353+
inherit ghc;
354+
name = "haskell-stack-flake-nix";
355+
buildInputs = [ zlib glpk pcre ];
356+
}
357+
358+
```
359+
360+
Commit both files to Git, run `nix develop` (it searches for `flake.nix` by default),
361+
and you'll find a new `flake.lock` file that pins the precise nixpkgs package set.
362+
Commit this file to Git as well so that every developer of your project will use precisely
363+
the same package set.
364+
292365
[nix-manual-exprs]: http://nixos.org/nix/manual/#chap-writing-nix-expressions
293366
[nixpkgs-manual-haskell]: https://nixos.org/nixpkgs/manual/#users-guide-to-the-haskell-infrastructure
294367
[nix-search-packages]: https://nixos.org/nixos/packages.html

0 commit comments

Comments
 (0)