4
4
5
5
(since 0.1.10.0)
6
6
7
- When using the Nix integration, Haskell dependencies are handled as usual: They
8
- are downloaded from Stackage and built locally by Stack. Nix is used by Stack to
9
- provide the _ non-Haskell_ dependencies needed by these Haskell packages.
10
-
11
- ` stack ` can automatically create a build environment (the equivalent
12
- of a "container" in Docker parlance) using ` nix-shell ` , provided Nix
13
- is already installed on your system. To do so, please visit the
14
- [ Nix download page] ( http://nixos.org/nix/download.html ) .
15
-
16
- There are two ways to create a build environment:
17
-
18
- - providing a list of packages (by "attribute name") from
19
- [ Nixpkgs] ( http://nixos.org/nixos/packages.html ) , or
20
- - providing a custom ` shell.nix ` file containing a Nix expression that
21
- determines a * derivation* , i.e. a specification of what resources
22
- are available inside the shell.
23
-
24
- The second requires writing code in Nix's custom language. So use this
25
- option only if you already know Nix and have special requirements,
7
+ When using the Nix integration, Stack handles Haskell dependencies as usual
8
+ while the Nix handles _ non-Haskell_ dependencies needed by these Haskell packages.
9
+ So Stack downloads Haskell packages from [ Stackage] ( https://www.stackage.org/lts )
10
+ and builds them locally but uses Nix to download
11
+ [ Nix packages] [ nix-search-packages ] that provide the GHC compiler and
12
+ external C libraries that you would normally install manually.
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 ) .
15
+
16
+ ` stack ` can automatically create a Nix build environment in the background
17
+ using ` nix-shell ` , similar to building inside an isolated
18
+ [ Docker] ( https://www.docker.com/ ) container.
19
+ There are two options to create such a build environment:
20
+
21
+ - provide a list of [ Nix packages] [ nix-search-packages ]
22
+ - provide a ` shell.nix ` file that gives you more control
23
+ of what libraries and tools are available inside the shell.
24
+
25
+ The second requires writing code in
26
+ [ Nix's custom language] [ nix-language ] .
27
+ So use this option only if you already know Nix and have special requirements,
26
28
such as using custom Nix packages that override the standard ones or
27
29
using system libraries with special requirements.
28
30
@@ -38,34 +40,47 @@ You should either run `source ~/.nix-profile/etc/profile.d/nix.sh` manually
38
40
every time you open a terminal and need Nix or add this command to your
39
41
` ~/.bashrc ` or ` ~/.bash_profile ` .
40
42
41
- ### Additions to your ` stack.yaml `
43
+ ### External C libraries through Nix packages
42
44
43
- Add a section to your ` stack.yaml ` as follows:
45
+ To let Nix manage external C libraries by default
46
+ add the following section to your ` stack.yaml ` file:
44
47
``` yaml
45
48
nix :
46
49
enable : true
47
- packages : [glpk, pcre]
50
+ packages : [zlib, glpk, pcre]
48
51
` ` `
49
52
50
53
This will instruct ` stack` to build inside a local build environment
51
- that will have the `glpk` and `pcre` libraries installed and
52
- available. Further, the build environment will implicitly also include
53
- a version of GHC matching the configured resolver. Enabling Nix
54
- support means packages will always be built using a GHC available
55
- inside the shell, rather than your globally installed one if any.
56
-
57
- Note that in this mode `stack` can use only GHC versions that have
54
+ that will have the Nix packages
55
+ [zlib](https://search.nixos.org/packages?query=zlib),
56
+ [glpk](https://search.nixos.org/packages?query=glpk) and
57
+ [pcre](https://search.nixos.org/packages?query=pcre)
58
+ installed, which provide the C libraries of the same names.
59
+ Further, the build environment will implicitly also download and use
60
+ a [GHC Nix package](https://search.nixos.org/packages?query=haskell.compiler.ghc)
61
+ matching the required version of the configured
62
+ [Stack resolver](https://docs.haskellstack.org/en/stable/GUIDE/#resolvers-and-changing-your-compiler-version).
63
+ So, enabling Nix support means that packages will always be built using the
64
+ local GHC from Nix inside your shell, rather than your
65
+ globally installed system GHC if any.
66
+
67
+ Note that *in this mode every developer of your project needs to have Nix installed*,
68
+ but also gets all external libraries automatically*. Quite convenient.
69
+ If some developers don't have or want Nix, there's a nice tutorial on
70
+ [how to add Nix integration optionally](https://www.tweag.io/blog/2022-06-02-haskell-stack-nix-shell/).
71
+
72
+ Also note that `stack` can use only GHC versions that have
58
73
already been mirrored into the Nix package repository.
59
74
The [Nixpkgs master branch](https://github.com/NixOS/nixpkgs/tree/master/pkgs/development/haskell-modules)
60
75
usually picks up new versions quickly, but it takes two or three
61
76
days before those updates arrive in the `unstable` channel. Release
62
- channels, like `nixos-15.09 `, receive those updates only
77
+ channels, like `nixos-22.05 `, receive those updates only
63
78
occasionally -- say, every two or three months --, so you should not
64
79
expect them to have the latest compiler available. Fresh NixOS installs
65
80
use a release version by default.
66
81
67
82
To know for sure whether a given compiler is available on your system,
68
- you can use the command
83
+ you can use the Nix command
69
84
70
85
` ` ` sh
71
86
$ nix-env -f "<nixpkgs>" -qaP -A haskell.compiler.ghc801
@@ -110,7 +125,7 @@ the `include/` folder. If you're dealing with a package that doesn't
110
125
follow this standard layout, you'll have to deal with that using
111
126
a custom shell file (see below).
112
127
113
- # ## Use stack as normal
128
+ # ## Using Stack with Nix enabled
114
129
115
130
With Nix enabled, `stack build` and `stack exec` will automatically
116
131
launch themselves in a local build environment (using `nix-shell`
@@ -122,15 +137,16 @@ happen when running `stack build` if no setup has been performed
122
137
before. Therefore it is no longer necessary to run `stack setup` unless you
123
138
want to cache a GHC installation before running the build.
124
139
125
- If `enable:` is omitted or set to `false`, you can still build in a nix-shell by
126
- passing the `--nix` flag to stack, for instance `stack --nix build`. Passing
127
- any `--nix*` option to the command line will do the same.
140
+ If `enable:` is omitted or set to `false` in your `stack.yaml` file,
141
+ you can still build within a nix-shell by
142
+ overriding Stack through the `--nix` flag, for instance `stack --nix build`.
143
+ Passing any `--nix*` option to the command line will do the same.
128
144
129
145
**Known limitation on macOS:** currently, `stack --nix ghci` fails on
130
146
macOS, due to a bug in GHCi when working with external shared
131
147
libraries.
132
148
133
- # ## The Nix shell
149
+ # ## Pure and impure Nix shell
134
150
135
151
By default, stack will run the build in a *pure* Nix build environment (or
136
152
*shell*), which means two important things:
@@ -151,12 +167,20 @@ due soon to be resolved locale issues. So on macOS you'll need to be
151
167
a bit more careful to check that you really have listed all
152
168
dependencies.
153
169
154
- # ## Package sources
170
+ # ## Nix package sources
155
171
156
- By default, `nix-shell` will look for the nixpkgs package set located
157
- by your `NIX_PATH` environment variable.
172
+ Nix organizes its packages in snapshots of packages (each snapshot being
173
+ a "package set")
174
+ similar to how Stackage organizes Haskell packages.
175
+ By default, `nix-shell` will look for the "nixpkgs" package set located
176
+ by your `NIX_PATH` environment variable. This package set can be different
177
+ depending on when you installed Nix and which nixpkgs channel you're using
178
+ (similar to the LTS channel for stable packages and the nightly channel for bleeding
179
+ edge packages in [Stackage](https://www.stackage.org/)).
180
+ This is bad for reproducibilty so that nixpkgs should be pinned, i.e.,
181
+ set to the same package set for every developer of your project.
158
182
159
- You can override this by passing
183
+ You can set or override the Nix package set by passing
160
184
` --nix-path="nixpkgs=/my/own/nixpkgs/clone"` to ask Nix to use your
161
185
own local checkout of the nixpkgs repository. You could in this way
162
186
use a bleeding edge nixpkgs, cloned from the
@@ -168,19 +192,21 @@ nix:
168
192
path: [nixpkgs=/my/own/nixpkgs/clone]
169
193
` ` `
170
194
171
- in your `stack.yaml` will do the same.
195
+ in your `stack.yaml` will do the same.
196
+ [This example repository](https://github.com/tweag/haskell-stack-nix-example)
197
+ shows how you can pin a package set.
172
198
173
199
# # Command-line options
174
200
175
201
The configuration present in your `stack.yaml` can be overridden on the
176
202
command-line. See `stack --nix-help` for a list of all Nix options.
177
203
178
- # # Configuration
204
+ # # Configuration options
179
205
180
- ` stack.yaml` contains a `nix:` section with Nix settings.
181
- Without this section, Nix will not be used.
206
+ ` stack.yaml` contains a `nix:` section for Nix settings.
207
+ Without this section, Nix won't be used.
182
208
183
- Here is a commented configuration file, showing the default values :
209
+ Here's a working configuration file with all settings, mentioning default values :
184
210
185
211
` ` ` yaml
186
212
nix:
189
215
# NixOS where it is enabled by default (see #3938). You can set set it in your
190
216
# `$HOME/.stack/config.yaml` to enable Nix for all your projects without having
191
217
# to repeat it
192
- # enable: true
218
+ enable : true
193
219
194
220
# true by default. Tells Nix whether to run in a pure shell or not.
195
221
pure : true
@@ -221,15 +247,14 @@ nix:
221
247
add-gc-roots : false
222
248
` ` `
223
249
224
- ## Using a custom shell.nix file
250
+ ## External C libraries through shell.nix
225
251
226
- Nix is also a programming language, and as specified
227
- [here](#nix-integration) if you know it you can provide to the shell
228
- a fully customized derivation as an environment to use. Here is the
229
- equivalent of the configuration used in
230
- [this section](#additions-to-your-stackyaml), but with an explicit
231
- ` shell.nix` file (make sure you're using a nixpkgs version later than
232
- 2015-03-05) :
252
+ There's also the [Nix programming language][nix-language]
253
+ to provide a fully customized derivation as an environment to use.
254
+ Here's the equivalent of the configuration used in the
255
+ [previous example](#external-c-libraries-through-nix-packages),
256
+ but with an explicit ` shell.nix` file
257
+ (make sure you're using a nixpkgs version later than 2015-03-05) :
233
258
234
259
` ` ` nix
235
260
{ghc}:
@@ -238,19 +263,19 @@ with (import <nixpkgs> {});
238
263
haskell.lib.buildStackProject {
239
264
inherit ghc;
240
265
name = "myEnv";
241
- buildInputs = [ glpk pcre ];
266
+ buildInputs = [ zlib glpk pcre ];
242
267
}
243
268
` ` `
244
269
245
- Defining manually a `shell.nix` file gives you the possibility to override some
270
+ Defining a `shell.nix` file manually gives you the possibility to override some
246
271
Nix derivations ("packages"), for instance to change some build options of the
247
272
libraries you use, or to set additional environment variables. See the
248
273
[Nix manual][nix-manual-exprs] for more. The `buildStackProject` utility
249
274
function is documented in the [Nixpkgs manual][nixpkgs-manual-haskell]. In such
250
- case, stack expect this file to define a function of exactly one argument that
275
+ case, stack expects this file to define a function of exactly one argument that
251
276
should be called `ghc` (as arguments within a set are non-positional), which you
252
- should give to `buildStackProject`. This is the ghc from the resolver you set in
253
- the `stack.yaml`.
277
+ should give to `buildStackProject`. This is a GHC Nix package in the version as
278
+ defined in the resolver you set in the `stack.yaml` file .
254
279
255
280
And now for the `stack.yaml` file :
256
281
@@ -264,5 +289,86 @@ The `stack build` command will behave exactly the same as above. Note
264
289
that specifying both `packages:` and a `shell-file:` results in an
265
290
error. (Comment one out before adding the other.)
266
291
292
+ # # Stack and developer tools 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. However, GHC provided through Nix
298
+ can be modified to find the external C libraries provided through Nix.
299
+
300
+ A detailed tutorial on how to configure Stack so that it supports NixOS and non-Nix users
301
+ can be found [here](https://www.tweag.io/blog/2022-06-02-haskell-stack-nix-shell/). A corresponding
302
+ example project can be found [here](https://github.com/tweag/haskell-stack-nix-example).
303
+
304
+ If you're already using Nix flakes, here's an adaptation of that example extended with typical developer
305
+ tools like the [Haskell Language Server](https://haskell-language-server.readthedocs.io/en/latest/what-is-hls.html) :
306
+ Add the following `flake.nix` file to your project.
307
+
308
+ ` ` ` nix
309
+ {
310
+ description = "my project description";
311
+ inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
312
+ inputs.flake-utils.url = "github:numtide/flake-utils";
313
+
314
+ outputs = { self, nixpkgs, flake-utils }:
315
+ flake-utils.lib.eachDefaultSystem (system:
316
+ let
317
+ pkgs = nixpkgs.legacyPackages.${system};
318
+
319
+ hPkgs =
320
+ pkgs.haskell.packages."ghc8107"; # need to match Stackage LTS version from stack.yaml resolver
321
+
322
+ myDevTools = [
323
+ hPkgs.ghc # GHC compiler in the desired version (will be available on PATH)
324
+ hPkgs.ghcid # Continous terminal Haskell compile checker
325
+ hPkgs.ormolu # Haskell formatter
326
+ hPkgs.hlint # Haskell codestyle checker
327
+ hPkgs.hoogle # Lookup Haskell documentation
328
+ hPkgs.haskell-language-server # LSP server for editor
329
+ hPkgs.implicit-hie # auto generate LSP hie.yaml file from cabal
330
+ hPkgs.retrie # Haskell refactoring tool
331
+ # hPkgs.cabal-install
332
+ stack-wrapped
333
+ pkgs.zlib # External C library needed by some Haskell packages
334
+ ];
335
+
336
+ # Wrap Stack to work with our Nix integration. We don't want to modify stack.yaml so non-Nix users don't notice anything.
337
+ # - no-nix: We don't want Stack's way of integrating Nix.
338
+ # --system-ghc # Use the existing GHC on PATH (will come from this Nix file)
339
+ # --no-install-ghc # Don't try to install GHC if no matching GHC found on PATH
340
+ stack-wrapped = pkgs.symlinkJoin {
341
+ name = "stack"; # will be available as the usual ` stack` in terminal
342
+ paths = [ pkgs.stack ];
343
+ buildInputs = [ pkgs.makeWrapper ];
344
+ postBuild = ''
345
+ wrapProgram $out/bin/stack \
346
+ --add-flags "\
347
+ --no-nix \
348
+ --system-ghc \
349
+ --no-install-ghc \
350
+ "
351
+ '';
352
+ };
353
+ in {
354
+ devShells.default = pkgs.mkShell {
355
+ buildInputs = myDevTools;
356
+
357
+ # Make external Nix c libraries like zlib known to GHC, like pkgs.haskell.lib.buildStackProject does
358
+ # https://github.com/NixOS/nixpkgs/blob/d64780ea0e22b5f61cd6012a456869c702a72f20/pkgs/development/haskell-modules/generic-stack-builder.nix#L38
359
+ LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath myDevTools;
360
+ };
361
+ });
362
+ }
363
+ ```
364
+
365
+ Commit this file to Git, run `nix develop` (it searches for `flake.nix` by default),
366
+ and you'll find a new `flake.lock` file that pins the precise nixpkgs package set.
367
+ Commit this file to Git as well so that every developer of your project will use precisely
368
+ the same package set.
369
+
267
370
[nix-manual-exprs]: http://nixos.org/nix/manual/#chap-writing-nix-expressions
268
371
[nixpkgs-manual-haskell]: https://nixos.org/nixpkgs/manual/#users-guide-to-the-haskell-infrastructure
372
+ [nix-search-packages]: https://nixos.org/nixos/packages.html
373
+ [nix-language]: https://nixos.wiki/wiki/Nix_Expression_Language
374
+
0 commit comments