git.iko.soy/typeable/cabal2nix
on master help sign in
doc: more user-guide.md
commit012a0c0fd19183087b82192c4fe2ad0efdcd0885 authorPeter Simons <simons@cryp.to> dateMon 1 Jun 2015, 17:15 (11 years ago) parent513a5fc
1 file changed+146−113
doc/user-guide.md+146−113
doc/user-guide.md+146−113
@@ -1,14 +1,14 @@
11---
22title: User's Guide for Haskell in Nixpkgs
3−author: Peter Simons \<simons@cryp.to\>
4−date: 2015-05-21
3+author: Peter Simons
4+date: 2015-06-01
55---
66
77# How to install Haskell packages
88
99Nixpkgs distributes build instructions for all Haskell packages registered on
10−Hackage[^Hackage], but strangely enough normal Nix package lookups don't seem
11−to discover any of them:
10+[Hackage](http://hackage.haskell.org/), but strangely enough normal Nix package
11+lookups don't seem to discover any of them:
1212
1313 $ nix-env -qa cabal-install
1414 error: selector ‘cabal-install’ matches no derivations
@@ -39,8 +39,10 @@ attribute path (first column):
3939
4040The attribute path of any Haskell packages corresponds to the name of that
4141particular package on Hackage: the package `cabal-install` has the attribute
42−`haskellPackages.cabal-install`, and so
43−on.[^names-that-cannot-be-mapped-to-attributes]
42+`haskellPackages.cabal-install`, and so on. (Actually, this convention causes
43+trouble with packages like `3dmodels` and `4Blocks`, because these names are
44+invalid identifiers in the Nix language. The issue of how to deal with these
45+rare corner cases is currently unresolved.)
4446
4547Haskell packages who's Nix name (second column) begins with a `haskell-` prefix
4648are packages that provide a library whereas packages without that prefix
@@ -164,7 +166,29 @@ configure` inside of a new `nix-shell` environment.
164166
165167## How to install a compiler with libraries
166168
167−Edit the file `~/.nixpkgs/config.nix`:
169+GHC expects to find all installed libraries inside of its own `lib` directory.
170+This approach works fine on traditional Unix systems, but it doesn't work for
171+Nix, because GHC's store path is immutable once it's built. We cannot install
172+additional libraries into that location. As a consequence, our copies of GHC
173+don't know any packages except their own core libraries, like `base`,
174+`containers`, `Cabal`, etc.
175+
176+We can register additional libraries to GHC, however, using a special build
177+function called `ghcWithPackages`. That function expects one argument: a
178+function that maps from an attribute set of Haskell packages to a list of
179+packages, which determines the libraries known to that particular version of
180+GHC. For example, the Nix expression `ghcWithPackages (pkgs: [pkgs.mtl])`
181+generates a copy of GHC that has the `mtl` library registered in addition to
182+its normal core packages:
183+
184+ $ nix-shell -p "haskellPackages.ghcWithPackages (pkgs: [pkgs.mtl])"
185+
186+ [nix-shell:~]$ ghc-pkg list mtl
187+ /nix/store/zy79...-ghc-7.10.1/lib/ghc-7.10.1/package.conf.d:
188+ mtl-2.2.1
189+
190+This function allows users to define their own development environment by means
191+of an override. After adding the following snippet to `~/.nixpkgs/config.nix`,
168192
169193 {
170194 packageOverrides = super: let self = super.pkgs; in
@@ -179,80 +203,111 @@ Edit the file `~/.nixpkgs/config.nix`:
179203 };
180204 }
181205
182−Now installl with `nix-env -f "<nixpkgs>" -iA myHaskellEnv`.
206+it's possible to install that compiler with `nix-env -f "<nixpkgs>" -iA
207+myHaskellEnv`. If you'd like to switch that development environment to a
208+different version of GHC, just replace the `ghc7101` bit in the previous
209+definition with the appropriate name. Of course, it's also possible to define
210+any number of these development environments! (You can't install two of them
211+into the same profile at the same time, though, because that would result in
212+file conflicts.)
183213
184214The generated `ghc` program is a wrapper script that re-directs the real
185−`ghc` to use a "libdir" with all the specified packages installed:
186−
187− #! /nix/store/xlxjcjbnbwnz...-bash-4.3-p33/bin/bash -e
188− realGhc=/nix/store/zzhasddj77xhwdban95...-ghc-7.10.1
189− ghcEnv=/nix/store/cgddwzz9hkdgprvbymph...-ghc-7.10.1
190− export NIX_GHC=$ghcEnv/bin/ghc
191− export NIX_GHCPKG=$ghcEnv/bin/ghc-pkg
192− export NIX_GHC_DOCDIR=$ghcEnv/share/doc/ghc/html
193− export NIX_GHC_LIBDIR=$ghcEnv/lib/ghc-7.10.1
194− exec $realGhc/bin/ghc "-B$NIX_GHC_LIBDIR" "${extraFlagsArray[@]}" "$@"
195−
196−
197−Define the same environment variables in your `~/.bashrc`:
198−
199− NIX_GHC="$HOME/.nix-profile/bin/ghc"
200− ghcVersion=$($NIX_GHC --numeric-version)
201− NIX_GHCPKG="$HOME/.nix-profile/bin/ghc-pkg"
202− NIX_GHC_DOCDIR="$HOME/.nix-profile/share/doc/ghc/html"
203− NIX_GHC_LIBDIR="$HOME/.nix-profile/lib/ghc-$ghcVersion"
204− export NIX_GHC NIX_GHCPKG NIX_GHC_DOCDIR NIX_GHC_LIBDIR
205− unset ghcVersion
206−
207−Or:
208−
209− if [ -e ~/.nix-profile/bin/ghc ]; then
210− eval $(grep export ~/.nix-profile/bin/ghc)
211− fi
212−
213−## Ad hoc environments
214−
215−Save as `shell.nix`:
216−
217− with (import <nixpkgs> {}).pkgs;
218− let
219− ghc = haskell.packages.ghc7101.ghcWithPackages
220− (pkgs: with pkgs; [ aeson lens monad-par ]);
221− in
222− stdenv.mkDerivation {
223− name = "my-haskell-env-0";
224− buildInputs = [ ghc ];
225− shellHook = "eval $(grep export ${ghc}/bin/ghc)";
226− }
227−
228−Now run `nix-shell`, or even `nix-shell --pure`.
229−
230−To parameterize the compiler version, edit the file as follows:
231−
232− { compiler ? "ghc7101" }:
233−
234− with (import <nixpkgs> {}).pkgs;
235− let
236− ghc = haskell.packages.${compiler}.ghcWithPackages
237− (pkgs: with pkgs; [ aeson lens monad-par ]);
238− in
239− [...]
240−
241−Now run "`nix-shell --argstr compiler ghc784`" to select a different
242−compiler.
243−
244−Every Haskell package has an `env` attribute that provides a temporary
245−shell environment in which that package can be built:
215+GHC executable to use a new `lib` directory --- one that we specifically
216+constructed to contain all those packages the user requested:
217+
218+ $ cat $(type -p ghc)
219+ #! /nix/store/xlxj...-bash-4.3-p33/bin/bash -e
220+ export NIX_GHC=/nix/store/19sm...-ghc-7.10.1/bin/ghc
221+ export NIX_GHCPKG=/nix/store/19sm...-ghc-7.10.1/bin/ghc-pkg
222+ export NIX_GHC_DOCDIR=/nix/store/19sm...-ghc-7.10.1/share/doc/ghc/html
223+ export NIX_GHC_LIBDIR=/nix/store/19sm...-ghc-7.10.1/lib/ghc-7.10.1
224+ exec /nix/store/j50p...-ghc-7.10.1/bin/ghc "-B$NIX_GHC_LIBDIR" "$@"
225+
226+The variables `$NIX_GHC`, `$NIX_GHCPKG`, etc. point to the *new* store path
227+`ghcWithPackages` constructed specifically for this environment. The last line
228+of the wrapper script then executes the real `ghc`, but passes the path to the
229+new `lib` directory using GHC's `-B` flag.
230+
231+The purpose of those environment variables is to work around an impurity in the
232+popular [ghc-paths](http://hackage.haskell.org/package/ghc-paths) library. That
233+library promises to give its users access to GHC's installation paths. Only,
234+the library can't possible know that path when it's compiled, because the path
235+GHC considers its own is determined only much later, when the user configures
236+it through `ghcWithPackages`. So we [patched
237+ghc-paths](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/haskell-modules/ghc-paths-nix.patch)
238+to return the paths found in those environment variables at run-time rather
239+than trying to guess them at compile-time.
240+
241+To make sure that mechanism works properly all the time, we recommend that you
242+set those variables to meaningful values in your shell environment, too, i.e.
243+by adding the following code to your `~/.bashrc`:
244+
245+ if type >/dev/null 2>&1 -p ghc; then
246+ eval "$(egrep ^export "$(type -p ghc)")"
247+ fi
248+
249+If you are certain that you'll use only one GHC environment which is located in
250+your user profile, then you can use the following code, too, which has the
251+advantage that it doesn't contain any paths from the Nix store, i.e. those
252+settings always remain valid even if a `nix-env -u` operation updates the GHC
253+environment in your profile:
254+
255+ if [ -e ~/.nix-profile/bin/ghc ]; then
256+ export NIX_GHC="$HOME/.nix-profile/bin/ghc"
257+ export NIX_GHCPKG="$HOME/.nix-profile/bin/ghc-pkg"
258+ export NIX_GHC_DOCDIR="$HOME/.nix-profile/share/doc/ghc/html"
259+ export NIX_GHC_LIBDIR="$HOME/.nix-profile/lib/ghc-$($NIX_GHC --numeric-version)"
260+ fi
261+
262+## How to create ad hoc environments for `nix-shell`
263+
264+The easiest way to create an ad hoc development environment is to run
265+`nix-shell` with the appropriate GHC environment given on the command-line:
266+
267+ nix-shell -p "haskellPackages.ghcWithPackages (pkgs: with pkgs; [mtl pandoc])"
268+
269+For more sophisticated use-cases, however, it's probably nicer to save the
270+desired configuration in a file called `shell.nix` that looks like this:
271+
272+ { nixpkgs ? import <nixpkgs> {}, compiler ? "ghc7101" }:
273+ let
274+ inherit (nixpkgs) pkgs;
275+ ghc = pkgs.haskell.packages.${compiler}.ghcWithPackages (ps: with ps; [
276+ monad-par mtl
277+ ]);
278+ in
279+ pkgs.stdenv.mkDerivation {
280+ name = "my-haskell-env-0";
281+ buildInputs = [ ghc ];
282+ shellHook = "eval $(egrep ^export ${ghc}/bin/ghc)";
283+ }
246284
247− $ cabal get lens && cd lens-4.10
248− Downloading lens-4.10...
249− Unpacking to lens-4.10/
285+Now run `nix-shell` --- or even `nix-shell --pure` --- to enter a shell
286+environment that has the appropriate compiler in `$PATH`. If you use `--pure`,
287+then add all other packages that your development environment needs into the
288+`buildInputs` attribute. If you'd like to switch to a different compiler
289+version, then pass an appropriate `compiler` argument to the expression, i.e.
290+`nix-shell --argstr compiler ghc784`.
291+
292+If you need such an environment because you'd like to compile a Hackage package
293+outside of Nix --- i.e. because you're hacking on the latest version from Git
294+---, then the package set provides suitable nix-shell environments for you
295+already! Every Haskell package has an `env` attribute that provides a shell
296+environment suitable for compiling that particular package. If you'd like to
297+hack the `lens` library, for example, then you just have to check out the
298+source code and enter the appropriate environment:
299+
300+ $ cabal get lens-4.11 && cd lens-4.11
301+ Downloading lens-4.11...
302+ Unpacking to lens-4.11/
250303
251304 $ nix-shell "<nixpkgs>" -A haskellPackages.lens.env
252− [nix-shell:/tmp/lens-4.10]$ cabal configure
253− Resolving dependencies...
254− Configuring lens-4.10...
255− [...]
305+ [nix-shell:/tmp/lens-4.11]$
306+
307+At point, you can run `cabal configure`, `cabal build`, and all the other
308+development commands. Note that you need `cabal-install` installed in your
309+`$PATH` already to use it here --- the `nix-shell` environment does not provide
310+it.
256311
257312# Adding support for your own packages
258313
@@ -315,51 +370,29 @@ Use this `~/.nixpkgs/config.nix` file to register the build inside of
315370 };
316371 }
317372
318−# How to download binary packages
319−
320−NixOS users add this setting to `/etc/nixos/configuration.nix`:
321−
322− nix.trustedBinaryCaches = [
323− http://hydra.nixos.org
324− ];
325−
326−Everyone else adds this setting to `/etc/nix/nix.conf`:
327−
328− trusted-binary-caches = http://hydra.nixos.org
329−
330−Now run `nix-env -f "<nixpkgs>"`, `nix-build`, and `nix-shell` with this option:
331−
332− --option extra-binary-caches http://hydra.nixos.org
333−
334373## GHC's infamous non-deterministic library ID bug
335374
336375GHC and distributed build farms don't get along well:
337376
338− https://ghc.haskell.org/trac/ghc/ticket/4012
339− https://github.com/NixOS/nixpkgs/issues/7792
377+ https://ghc.haskell.org/trac/ghc/ticket/4012
378+ https://github.com/NixOS/nixpkgs/issues/7792
340379
341380When you see an error like this one
342381
343− package foo-0.7.1.0 is broken due to missing package
344− text-1.2.0.4-98506efb1b9ada233bb5c2b2db516d91
345−
346−then you have to garbage collect `foo` and all its dependents,
347−and re-install from scratch.
348−
349− # nix-store -q --referrers /nix/store/*-haskell-text-1.2.0.4 | nix-store --repair-path --option binary-caches http://hydra.nixos.org
350−
351−If you're using a Hydra server other than `hydra.nixos.org`, then it
352−might be necessary to disable the binary channels for the duration of
353−the previous command, i.e. by running:
354−
355− # nix-channel --remove nixos
356−
382+ package foo-0.7.1.0 is broken due to missing package
383+ text-1.2.0.4-98506efb1b9ada233bb5c2b2db516d91
357384
385+then you have to download and re-install `foo` and all its dependents from
386+scratch:
358387
388+ # nix-store -q --referrers /nix/store/*-haskell-text-1.2.0.4 \
389+ | nix-store --repair-path --option binary-caches http://hydra.nixos.org
359390
360−[^Hackage]: http://hackage.haskell.org/
391+If you're using additional Hydra servers other than `hydra.nixos.org`, then it
392+might be necessary to purge the local caches that store data from those
393+machines to disable these binary channels for the duration of the previous
394+command, i.e. by running:
361395
362−[^names-that-cannot-be-mapped-to-attributes]: This convention causes trouble
363−with packages like `3dmodels` and `4Blocks`, because these names are invalid
364−identifiers in the Nix language. The issue of how to deal with these (rare)
365−corner cases is currently unresolved.
396+ rm /nix/var/nix/binary-cache-v3.sqlite
397+ rm /nix/var/nix/manifests/*
398+ rm /nix/var/nix/channel-cache/*