expanded, updated version of my "How to cabal install" tutorial from school of haskell

root / README.md

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
---
title: How to cabal install
date: 2013/3/2
author: Simon Michael <simon@joyful.com>
---

# How to cabal install

`cabal` is a command-line program for downloading and building software written in [Haskell].
It can install all kinds of fascinating and useful software packages from the [Hackage] repository.
It is excellent and indispensable, but it currently has a troublesome flaw:
it sometimes mysteriously refuses to install things, leading to cries of "*AAAGH! CABAL HELL!!*".

A little extra know-how prevents this.
This tutorial aims to show you how to install cabal packages with confidence,
especially if you are new to Cabal and Haskell.
Welcome and let's get started!

1. [Should I use cabal ?](#should-i-use-cabal)
2. [cabal, Cabal, cabal-install](#cabal-cabal-cabal-install)
3. [Getting cabal](#getting-cabal)
4. [Installing things](#installing-things)
5. [How to check what's installed](#how-to-check-whats-installed)
6. [When it won't install: cabal hell](#when-it-wont-install-cabal-hell)
7. [The easy solution: reset your packages](#the-easy-solution-reset-your-packages)
8. [The careful solution: use a sandbox](#the-careful-solution-use-a-sandbox)
9. [The harder, quicker solution: clean your packages](#the-harder-quicker-solution-clean-your-packages)
10. [Dealing with bad dependencies](#dealing-with-bad-dependencies)
11. [Summary](#summary)
12. [Further reading](#further-reading)
13. [About this document](#about-this-document)

--------------------------------------------------------------------------------

## Should I use cabal ?

Your system may have a package manager, like apt-get, yum, or macports, and it might offer packages for the Haskell software you want to install.
In this case you may save time by using it instead of cabal. It probably offers more stable, better-integrated packages, and they may be pre-compiled.

Otherwise, yes, use cabal. It is cross-platform and can install the widest range of up-to-date Haskell software.
It is also an essential tool if you want to develop Haskell software.

--------------------------------------------------------------------------------

## cabal, Cabal, cabal-install

Let's clarify these now to avoid confusion later. The [Cabal wiki page][Cabal] says:

> *"Cabal is a package and build system. Cabal is only involved in the creation of packages and the building of their contents. It does not manage packages.*
> *Cabal-Install installs cabal packages. It is distinct from Cabal (the build system). This often confuses new users. Furthermore, Cabal-Install is not a fully featured package manager. For example, it cannot install non cabal packaged dependencies, it cannot uninstall packages, nor can it automatically upgrade installations.*

In short: this tutorial is about using [cabal-install](http://hackage.haskell.org/package/cabal-install), which is `cabal` on the command line.
We'll just say cabal from now on.
It installs cabal packages, can't uninstall them, and can upgrade them only with supervision.
(Uninstalling is done with a lower-level tool called `ghc-pkg`, as we will see below.)
 
--------------------------------------------------------------------------------

## Getting cabal

cabal installs software, and can upgrade itself, but first you need get it installed by some other means.
It is often available as a system package, otherwise get it by installing the [Haskell Platform], 
or just [GHC].

To check that it's installed, at a command prompt do:

```
$ cabal --version
cabal-install version 1.16.0.2
using version 1.16.0 of the Cabal library
$
```

You should avoid versions older than 0.14. (After 0.14 the version number jumped to 1.16).
If you do have a very old version, you might be able to upgrade like so (we take care not
to leave two versions of Cabal installed):

```
$ cabal update
Downloading the latest package list from hackage.haskell.org
$ cabal install cabal-install && ghc-pkg unregister Cabal
Resolving dependencies...
Downloading Cabal-1.16.0.3...
...
Installed cabal-install-1.16.0.2
$
```

--------------------------------------------------------------------------------

## Installing things

As we just saw, installing usually goes like this:

1. find a package you want to install, eg from
   the [Hackage package list](http://hackage.haskell.org/packages/archive/pkg-list.html)
   or `cabal list`
2. update your local list of available packages with `cabal update`
3. download and install the package with `cabal install PACKAGE`.  
   Some useful options:  
   `--dry-run` to see what cabal plans to do (recommended),  
   `-jN` to build N packages in parallel (faster, uses more memory),  
   `-fFLAG` or `-f-FLAG` to turn build flags on or off (for packages that have them).

For example:

```
$ cabal update
Downloading the latest package list from hackage.haskell.org
$ cabal install --dry shelltestrunner
Resolving dependencies...
In order, the following would be installed (use -v for more details):
Diff-0.2.0
ansi-terminal-0.6
ansi-wl-pprint-0.6.6
filemanip-0.3.6.2
hostname-1.0
test-framework-0.8
test-framework-hunit-0.3.0
shelltestrunner-1.3.1
$ cabal install shelltestrunner -j2
Resolving dependencies...
Downloading Diff-0.2.0...
Downloading ansi-terminal-0.6...
Configuring filemanip-0.3.6.2...
..etc..
Downloading shelltestrunner-1.3.1...
Configuring shelltestrunner-1.3.1...
Building shelltestrunner-1.3.1...
Installed shelltestrunner-1.3.1
$
```

More tips:

- If you have multiple packages to install, it's preferable to install them all together, so that cabal can make better decisions. 
  Eg instead of: `cabal install A; cabal install B`
  do: `cabal install A B`.

--------------------------------------------------------------------------------

## How to check what's installed

Note that cabal knows about only some installed packages:

```
$ cabal list --installed Diff
* Diff
    Synopsis: O(ND) diff algorithm in haskell.
    Default available version: 0.3.0
    Installed versions: 0.2.0
    License:  BSD3

$ cabal list --installed shelltestrunner
No matches found.
$
```

It's the same with `ghc-pkg`:

```
$ ghc-pkg list --simple Diff 
Diff-0.2.0
$ ghc-pkg list --simple shelltestrunner
$
```

Packages can contain libraries (for use by other packages), executables (for use by humans), or both.
cabal and ghc-pkg only keep track of installed library packages.
The shelltestrunner package provides only executables, so cabal and ghc-pkg do not care about it after installation.
To check for installed executables, we can do eg:

```
$ ls -lt ~/.cabal/bin | head -5
total 1852920
-rwxr-xr-x  1 simon  simon  10394608 Mar  2 07:17 shelltest
-rwxr-xr-x  1 simon  simon   4962612 Mar  2 07:10 gearbox
-rwxr-xr-x  1 simon  simon  12279756 Mar  1 06:56 cabal
-rwxr-xr-x  1 simon  simon   1083948 Mar  1 06:54 hakyll-init
$
```

--------------------------------------------------------------------------------

## When it won't install: cabal hell

Over time, as you install more packages, and as new versions are released on Hackage,
`cabal install` becomes more likely to fail due to unresolvable dependencies.
There are other reasons for install failure (bad dependencies, bad code, incompatible compiler version, missing C libraries),
but unresolvable dependencies is the most common.
When it happens, you'll see something horrible like:

```
$ cabal install hledger-0.18
Resolving dependencies...
cabal: Could not resolve dependencies:
rejecting: hledger-0.19.4/installed-402..., 0.19.3, 0.19.2, 0.19.1, 0.19,
0.18.2, 0.18.1 (global constraint requires ==0.18)
trying: hledger-0.18
trying: regexpr-0.5.4/installed-0da...
trying: process-1.1.0.2/installed-7b6...
rejecting: haskeline-0.7.0.3/installed-414..., 0.7.0.3, 0.7.0.2, 0.7.0.1,
0.7.0.0 (conflict: hledger => haskeline==0.6.*)
rejecting: haskeline-0.6.4.7 (conflict: process =>
unix==2.6.0.1/installed-ccb..., haskeline => unix>=2.0 && <2.6)
rejecting: haskeline-0.6.4.6 (conflict: regexpr =>
mtl==2.1.2/installed-538..., haskeline => mtl>=1.1 && <2.1)
rejecting: haskeline-0.6.4.5, 0.6.4.4, 0.6.4.3, 0.6.4.2, 0.6.4.1, 0.6.4.0,
0.6.3.2, 0.6.3.1, 0.6.3, 0.6.2.4, 0.6.2.3 (conflict: process =>
filepath==1.3.0.1/installed-a78..., haskeline => filepath>=1.1 && <1.3)
rejecting: haskeline-0.6.2.2, 0.6.2.1, 0.6.2, 0.6.1.6, 0.6.1.5, 0.6.1.3,
0.6.1.2, 0.6.1.1, 0.6.1, 0.6.0.1, 0.6 (conflict: process =>
filepath==1.3.0.1/installed-a78..., haskeline => filepath==1.1.*)
rejecting: haskeline-0.5.0.1, 0.5, 0.4, 0.3.2, 0.3.1, 0.3, 0.2.1, 0.2
(conflict: hledger => haskeline==0.6.*)
$
```

What has happened is that your installed packages,
plus the new packages cabal thinks should be installed,
plus a GHC restriction that only one version of each package is used in any build,
have formed a network of dependencies that cabal can't satisfy.
And, cabal's explanation of the problem is hard for a human to understand.
You are entering.. *cabal hell!*

--------------------------------------------------------------------------------

## The easy solution: reset your packages

There is an easy workaround that does not require cabal troubleshooting skills or special tools.
If we clear out all installed libraries, cabal may have to reinstall a few but will have a much better chance of success.
The easiest way to do this (on unix) is:

```
$ rm -rf ~/.ghc ~/.cabal
$ 
```

This is simplest and reclaims most disk space, but it also deletes executables and config files. 
A less crude way is to use this bash script, which you can add to your ~/.bashrc:

```bash
# Uninstalls and deletes all installed GHC/cabal packages, but not binaries, docs, etc.
# Use this to get out of dependency hell and start over, at the cost of some rebuilding time.
function ghc-pkg-reset() {
    read -p 'erasing all your user ghc and cabal packages - are you sure (y/n) ? ' ans
    test x$ans == xy && ( \
        echo 'erasing directories under ~/.ghc'; rm -rf `find ~/.ghc -maxdepth 1 -type d`; \
        echo 'erasing ~/.cabal/lib'; rm -rf ~/.cabal/lib; \
        # echo 'erasing ~/.cabal/packages'; rm -rf ~/.cabal/packages; \
        # echo 'erasing ~/.cabal/share'; rm -rf ~/.cabal/share; \
        )
}
```

and:

```
$ source ~/.bashrc
$ ghc-pkg-reset
erasing all your user ghc and cabal packages - are you sure (y/n) ? y
$ ghc-pkg list --user
/Users/simon/.ghc/x86_64-darwin-7.6.1/package.conf.d
$
```

and then run the cabal install command again.

--------------------------------------------------------------------------------

## The careful solution: use a sandbox

Another approach is to keep separate installed package sets, known as sandboxes.
This costs more disk space and build time overall (for me, each package set takes about 0.5G of space).
But when you need to work on multiple projects whose dependencies are incompatible,
or to isolate projects from unrelated upgrades, this is the solution.
cabal does not yet provide this feature natively; for now it means using an additional tool, either [cabal-dev] or [hsenv].

--------------------------------------------------------------------------------

## The harder, quicker solution: clean your packages

As you get familiar with diagnosing these failures,
you will more often be able to see how to clean up your installed package set to give cabal more freedom.
Sometimes just removing the right old package will get things unstuck. Use `ghc-pkg unregister PACKAGE` for this.
If other packages depend on it, you can add `--force`, then also remove those packages (which will now be in a broken state).
The following bash script makes this easier:

```bash
# Unregisters broken GHC packages. Run a few times until it finds no more.
# ghc-pkg-clean -f cabal/dev/packages*.conf also works.                                                                                                                                                                                     
function ghc-pkg-clean() {
    for p in `ghc-pkg check $* 2>&1  | grep problems | awk '{print $6}' | sed -e 's/:$//'`
    do
        echo unregistering $p; ghc-pkg $* unregister $p
    done
}
```

An example:

```
$ ghc-pkg unregister tls
ghc-pkg: unregistering tls would break the following packages: hakyll-4.1.4.0 http-conduit-1.8.9 http-conduit-1.8.7.1 tls-extra-0.6.1 (use --force to override)
$ ghc-pkg unregister tls --force
unregistering tls would break the following packages: hakyll-4.1.4.0 http-conduit-1.8.9 http-conduit-1.8.7.1 tls-extra-0.6.1 (ignoring)
$ ghc-pkg-clean
unregistering http-conduit-1.8.9
unregistering http-conduit-1.8.7.1
unregistering tls-extra-0.6.1
$ ghc-pkg-clean
unregistering hakyll-4.1.4.0
$ ghc-pkg-clean
$
```

Since cabal will reinstall whatever it needs, you can keep removing and cleaning until your install command works again.
This incremental removal might be preferable to a full reset.

--------------------------------------------------------------------------------

## Dealing with bad dependencies

If, after a reset or in a clean sandbox, there are still unresolvable dependencies,
it means the released packages on Hackage have bad (incorrect, out-of-date, too tight, too loose) dependency declarations,
or the packages are not compatible with your GHC version.
In this case identify the problem package(s) and get the maintainer's help,
and/or try fixing the dependencies yourself in a local copy of the package (`cabal unpack` is good for this).

--------------------------------------------------------------------------------

## Summary

- `cabal` installs [Haskell] software from [Hackage]. It comes with [GHC] or the [Haskell Platform] or as a system package.
   Use at least version 0.14, and preferably the [newest](http://hackage.haskell.org/package/cabal-install).
- Use it instead of your system's package manager when you want to install (or develop) the latest Haskell software.
- The main subcommands are `update`, `list` and `install`.
- install becomes more likely to fail over time, as packages are added locally and on Hackage. Understanding these failures can be hard.
- The easy fix is to reset your packages, eg with `ghc-pkg-reset`.
- Or, you can install packages in separate sandboxes with [cabal-dev] or [hsenv].
- Or, with experience quicker fixes may be apparent, eg uninstall old package versions with `ghc-pkg unregister` and `ghc-pkg-clean`.
- Packages which fail to install even with a clean slate should be reported to their maintainers.

May you be free from *cabal hell* and enjoy *haskell heaven!*

--------------------------------------------------------------------------------

## Further reading

- [cabal-install][cabal-install] wiki page
- [How to install a Cabal package](http://www.haskell.org/haskellwiki/Cabal/How_to_install_a_Cabal_package), an older how-to
- [Cabal FAQ](http://www.haskell.org/cabal/FAQ.html) has detailed troubleshooting tips
- [Cabal][Cabal] gives more background
- [Repeat after me: “Cabal is not a Package Manager”][CINAPM] distinguishes various things
- [Storage and Identification of Cabalized Packages][SICP] explains some things in detail

--------------------------------------------------------------------------------

## About this document

- [Discussion](http://www.reddit.com/r/haskell/comments/19jbz5/how_to_cabal_install_a_new_tutorial/) on reddit, 2013/3/2-...
- [School of Haskell version](https://haskell.fpcomplete.com/user/simonmichael/how-to-cabal-install) at fpcomplete.com, short and to the point
- [Darcs hub version](http://hub.darcs.net/simon/cabal-install-tutorial/README.md) at hub.darcs.net, slightly more in-depth
  ([changes](http://hub.darcs.net/simon/cabal-install-tutorial/changes))



[Haskell]:          http://haskell.org
[Cabal]:            http://haskell.org/haskellwiki/Cabal
[Hackage]:          http://hackage.haskell.org
[Stackage]:         https://github.com/fpco/stackage
[cabal-install]:    http://www.haskell.org/haskellwiki/Cabal-Install
[GHC]:              http://haskell.org/ghc
[Haskell Platform]: http://haskell.org/platform
[cabal-dev]:        http://hackage.haskell.org/package/cabal-dev
[hsenv]:            http://hackage.haskell.org/package/hsenv
[SICP]:             http://www.vex.net/~trebla/haskell/sicp.xhtml
[CINAPM]:           http://ivanmiljenovic.wordpress.com/2010/03/15/repeat-after-me-cabal-is-not-a-package-manager