git.iko.soy/typeable/cabal2nix
on cabal2-support help sign in
typeable/cabal2nix/doc/nixos-meetup-3-slides.md
357 lines 11 kB history raw
1% Nix loves Haskell
2% Peter Simons \<simons@cryp.to\>
3% 2015-05-21
5-------------------------------------------------------------------------------
7# Road-map of this presentation
9- Install Haskell packages from Hackage
10- Install one (or many) Haskell compiler(s)
11- Create a Haskell development environment
12 - permanent environments with `ghcWithPackages`
13 - ad-hoc environments for `nix-shell`
14- Integrate your own (non-public) packages into Nix
15- Take advantage of the central build farm
16- Pitfalls to avoid
18-------------------------------------------------------------------------------
20# Install Haskell packages from Hackage
22Lookups based on package names like
24 $ nix-env -i cabal-install
26don't work! You have to use attribute paths:
28 $ nix-env -iA haskellPackages.cabal-install
30To list all Haskell packages, run:
32 $ nix-env -qaP -A haskellPackages
34-------------------------------------------------------------------------------
36# Install Haskell packages from Hackage
38There is one Haskell package set per compiler:
40 $ nix-env -qaP -A haskellPackages
41 $ nix-env -qaP -A haskell.packages.ghc6123
42 $ nix-env -qaP -A haskell.packages.ghc763
43 $ nix-env -qaP -A haskell.packages.ghc7101
45The default `haskellPackages` currently refers to
46`haskell.packages.ghc7101`.
48-------------------------------------------------------------------------------
50# Install a Haskell compiler
52 $ nix-env -iA haskell.compiler.ghc784
54 $ nix-env -qaP -A haskell.compiler
55 haskell.compiler.ghc6104 ghc-6.10.4
56 haskell.compiler.ghc6123 ghc-6.12.3
57 haskell.compiler.ghc704 ghc-7.0.4
58 haskell.compiler.ghc722 ghc-7.2.2
59 haskell.compiler.ghc742 ghc-7.4.2
60 haskell.compiler.ghc763 ghc-7.6.3
61 haskell.compiler.ghc784 ghc-7.8.4
62 haskell.compiler.ghc7101 ghc-7.10.1
63 haskell.compiler.ghcHEAD ghc-7.11.20150402
64 haskell.compiler.ghcjs ghcjs-0.1.0
65 haskell.compiler.jhc jhc-0.8.2
66 haskell.compiler.uhc uhc-1.1.9.0
68-------------------------------------------------------------------------------
70# Install a Haskell compiler
72For every compiler version XYZ, the attributes
74 haskell.compiler.ghcXYC
76and
78 haskell.packages.ghcXYC.ghc
80are synonymous.
82-------------------------------------------------------------------------------
84# Install more than one Haskell compiler (temporary)
86 $ nix-shell -p haskell.compiler.ghc7101
87 [nix-shell:~]$ ghc --numeric-version
88 7.10.1
89 [nix-shell:~]$ exit
91 $ nix-shell -p haskell.compiler.ghc784 \
92 --command "cabal configure"
93 $ cabal build
95-------------------------------------------------------------------------------
97# Install several Haskell compilers (transient)
99 $ nix-env -p ~/ghc-7.6.3 -iA haskell.compiler.ghc763
100 $ nix-env -p ~/ghc-7.8.4 -iA haskell.compiler.ghc784
101 [...]
103 $ export PATH=$HOME/ghc-7.6.3/bin:$PATH
104 $ ghc --numeric-version
105 7.6.3
107 $ cabal configure --with-compiler=$HOME/ghc-7.6.3/bin/ghc
109-------------------------------------------------------------------------------
111# Install several Haskell compilers (permanent)
113 $ PROFILE_DIR=/nix/var/nix/profiles/per-user/$USER
114 $ nix-env -p $PROFILE_DIR/ghc-7.6.3 -iA ...
116On NixOS, `/etc/profile` defines `$NIX_USER_PROFILE_DIR` automatically.
118-------------------------------------------------------------------------------
120# Create a Haskell development environment
122Edit the file `~/.nixpkgs/config.nix`:
124 {
125 packageOverrides = super: let self = super.pkgs; in
126 {
127 myHaskellEnv =
128 self.haskell.packages.ghc7101.ghcWithPackages
129 (haskellPackages: with haskellPackages; [
130 arrows async cabal-install case-insensitive
131 cgi criterion hspec HStringTemplate
132 ]);
133 };
134 }
136Now installl with `nix-env -iA myHaskellEnv`.
138-------------------------------------------------------------------------------
140# Create a Haskell development environment
142The generated `ghc` program is a wrapper script that re-directs the real
143`ghc` to use a "libdir" with all the specified packages installed:
145 #! /nix/store/xlxjcjbnbwnz...-bash-4.3-p33/bin/bash -e
146 realGhc=/nix/store/zzhasddj77xhwdban95...-ghc-7.10.1
147 ghcEnv=/nix/store/cgddwzz9hkdgprvbymph...-ghc-7.10.1
148 export NIX_GHC=$ghcEnv/bin/ghc
149 export NIX_GHCPKG=$ghcEnv/bin/ghc-pkg
150 export NIX_GHC_DOCDIR=$ghcEnv/share/doc/ghc/html
151 export NIX_GHC_LIBDIR=$ghcEnv/lib/ghc-7.10.1
152 exec $realGhc/bin/ghc "-B$NIX_GHC_LIBDIR" \
153 "${extraFlagsArray[@]}" "$@"
156-------------------------------------------------------------------------------
158# Create a Haskell development environment
160Define the same environment variables in your `~/.bashrc`:
162 NIX_GHC="$HOME/.nix-profile/bin/ghc"
163 ghcVersion=$($NIX_GHC --numeric-version)
164 NIX_GHCPKG="$HOME/.nix-profile/bin/ghc-pkg"
165 NIX_GHC_DOCDIR="$HOME/.nix-profile/share/doc/ghc/html"
166 NIX_GHC_LIBDIR="$HOME/.nix-profile/lib/ghc-$ghcVersion"
167 export NIX_GHC NIX_GHCPKG NIX_GHC_DOCDIR NIX_GHC_LIBDIR
168 unset ghcVersion
171Or:
173 if [ -e ~/.nix-profile/bin/ghc ]; then
174 eval $(grep export ~/.nix-profile/bin/ghc)
175 fi
177-------------------------------------------------------------------------------
179# Create a temporary Haskell development environment
181Save as `shell.nix`:
183 with (import <nixpkgs> {}).pkgs;
184 let
185 ghc = haskell.packages.ghc7101.ghcWithPackages
186 (pkgs: with pkgs; [ aeson lens monad-par ]);
187 in
188 stdenv.mkDerivation {
189 name = "my-haskell-env-0";
190 buildInputs = [ ghc ];
191 shellHook = "eval $(grep export ${ghc}/bin/ghc)";
192 }
194Now run `nix-shell`, or even `nix-shell --pure`.
196-------------------------------------------------------------------------------
198# Create a temporary Haskell development environment
200To parameterize the compiler version, edit the file as follows:
202 { compiler ? "ghc7101" }:
204 with (import <nixpkgs> {}).pkgs;
205 let
206 ghc = haskell.packages.${compiler}.ghcWithPackages
207 (pkgs: with pkgs; [ aeson lens monad-par ]);
208 in
209 [...]
211Now run "`nix-shell --argstr compiler ghc784`" to select a different
212compiler.
214-------------------------------------------------------------------------------
216# Create a temporary Haskell development environment
218Every Haskell package has an `env` attribute that provides a temporary shell environment in which that package can be built:
220 $ cabal get lens && cd lens-4.10
221 Downloading lens-4.10...
222 Unpacking to lens-4.10/
224 $ nix-shell "<nixpkgs>" -A haskellPackages.lens.env
225 [nix-shell:/tmp/lens-4.10]$ cabal configure
226 Resolving dependencies...
227 Configuring lens-4.10...
228 [...]
230-------------------------------------------------------------------------------
232# Create a development environment for your own packages
234 $ nix-env -iA cabal2nix
236 $ cabal2nix --shell . >shell.nix
237 $ nix-shell --command "cabal configure"
239 $ cabal build
240 [...]
242-------------------------------------------------------------------------------
244# Create a development environment for your own packages
246 $ cabal2nix --shell .
247 with (import <nixpkgs> {}).pkgs;
248 let pkg = haskellPackages.callPackage
249 ({ mkDerivation, base, stdenv, transformers }:
250 mkDerivation {
251 pname = "mtl";
252 version = "2.2.1";
253 src = ./.;
254 buildDepends = [ base transformers ];
255 homepage = "http://github.com/ekmett/mtl";
256 license = stdenv.lib.licenses.bsd3;
257 }) {};
258 in
259 pkg.env
261-------------------------------------------------------------------------------
263# Create builds for your own packages
265 $ cd ~/src/foo
266 $ cabal2nix . > default.nix
268Now edit `~/.nixpkgs/config.nix`:
270 {
271 packageOverrides = super: let self = super.pkgs; in
272 {
273 foo = self.haskellPackages.callPackage
274 ../src/foo {};
275 };
276 }
278Build it by running "`nix-env -iA foo`".
280-------------------------------------------------------------------------------
282# Create builds for your own packages
284Use this `~/.nixpkgs/config.nix` file to register the build inside of
285`haskellPackages`, so that other libraries may depend on it:
287 {
288 packageOverrides = super: let self = super.pkgs; in
289 {
290 haskellPackages = super.haskellPackages.override {
291 overrides = self: super: {
292 foo = self.callPackage ../src/foo {};
293 bar = self.callPackage ../src/bar {};
294 };
295 };
296 };
297 }
299-------------------------------------------------------------------------------
301# How to download binary packages
303NixOS users add this setting to `/etc/nixos/configuration.nix`:
305 nix.trustedBinaryCaches = [
306 http://hydra.cryp.to
307 http://hydra.nixos.org
308 ];
310Everyone else adds this setting to `/etc/nix/nix.conf`:
312 trusted-binary-caches = http://hydra.nixos.org \
313 http://hydra.cryp.to
315Now run `nix-env`, `nix-build`, and `nix-shell` with this option:
317 --option extra-binary-caches http://hydra.nixos.org
319-------------------------------------------------------------------------------
321# GHC's infamous non-deterministic library ID bug
323GHC and distributed build farms don't get along well:
325 https://ghc.haskell.org/trac/ghc/ticket/4012
326 https://github.com/NixOS/nixpkgs/issues/7792
328When you see an error like this one
330 package foo-0.7.1.0 is broken due to missing package
331 text-1.2.0.4-98506efb1b9ada233bb5c2b2db516d91
333then you have to garbage collect `foo` and all its dependents,
334and re-install from scratch.
336-------------------------------------------------------------------------------
338# Where to get help ...
340Haskell-specific resources:
342- https://github.com/NixOS/nixpkgs/issues/4941
344- A Journey into the Haskell NG infrastructure
345 - Part 1: https://nixos.org/nix-dev/2015-January/015591.html
346 - Part 2: https://nixos.org/nix-dev/2015-January/015608.html
347 - Part 3: https://nixos.org/nix-dev/2015-April/016912.html
349- Oliver Charles Wiki: http://wiki.ocharles.org.uk/Nix
351General Nix resources:
353- `https://nixos.org/`
355- https://groups.google.com/forum/#!forum/nix-devel
357- `#nixos` auf `irc.freenode.org`