Cabal/Survival

From HaskellWiki

Historically, Cabal-install has often been the part of Haskell ecosystem that causes most of the beginner troubles. Currently (2013/spring) this tool is in a very usable condition and causes but a few difficulties for most people. However, there are people for whom it does not seem to work and who are very vocal about their issues. It seems that many of these problems get solved through discussions in IRC or other forums, but the solutions are not officially documented anywhere. Further, due to historical reasons there is some advice, such as deleting all installed packages at the first sign of trouble, which is not relevant anymore.

This page is an attempt to document the usage patterns that seem to lead to relatively problem-free use of Cabal and to provide a common place to resolve
Cabal related issues. There is no no information in this page that hasn't been published in a blog or another. Instead, the intent is to gather all the good advice in one common place.

(Currently, this is page is put in work-in-progress state by a person who doesn't
have much difficulties with cabal-install, and is pretty much just guessing what goes wrong.)

1 What is the difficulty caused by Cabal-install?

The main difficulty with Cabal is otherwise known as 'dependency hell', in which the cabal-install does not manage to install a desired package for a reason or another, leading to large amount of manual work. As an example of this difficulty, consider a case where the user wishes to install packages A and B. Both of these work with package C, but not with the same version of C.

2 Why does cabal-install cause difficulties?

Cabals performance as a package manager is often compared to tools like apt in Debian or Portage in Gentoo, which are perceived as relatively problem free environments. Why are there less issues with such tools? The largest reason seems to be that Debian/Gentoo maintainers spend a huge effort in selecting the proper versions of software which to include and hand tuning the dependencies so everything works properly together. Hackage, from where the Cabal packages come from is not vetted like this. Instead, almost anyone can upload their packages to Hackage and there is no committee making sure everything has to work together.

In an environment like this it is not reasonable to assume that *absolutely everything* will work together.

3 The main sources of the problems and their solutions

There are few main items which cause difficulties with cabal:

Using an ancient version of Cabal, or the package listing.

Installing each package separately.

Using '--force-reinstalls' or other force switches.

Installing packages with incompatible version bounds.

Installing packages with external dependencies.

3.1 Issue #1 -- Old cabal-install

If you are having difficulties, and using a cabal-install version of less than 0.14, you should upgrade. In most cases, 'cabal update' followed by 'cabal install cabal-install' will do the trick. Notice, that in some cases (OS X, especially) the new cabal-install might not be installed on top of the previous one, and the old cabal-install must be replaced manually.

Newer versions of cabal cause significantly less problems.
Also, do 'cabal update' every now and then.

3.2 Issue #2 -- Not installing all the packages in one go

Always try to use one 'cabal install' command to install all the packages you need.

When cabal-install is invoked to install a package, the package is installed to either user-global or system-wide-global package repository. In this case, cabal tries very hard to install such version of the package that is compatible with the other installed packages. Every package must be compatible to each previous package, which narrows the options of what cabal can do until they are eventually exhausted.

Here, explicitly telling cabal which subset we want in one go often fixes things. Instead of doing

> cabal install A
> cabal install B
> cabal install C

one should do

> cabal install A B C

where A, B and C are either Hackage package names or directories containing cabal packages. In the first case, A and its dependencies are installed first. Now, to install B cabal has to find such versions of dependencies of B that work with the existing dependencies of A, which might be difficult. In the latter case, cabal-install is free to find a compatible subset of the dependencies of A, B and C.

This approach also works often when cabal complains that it cannot satisfy some constraint because of another package. Re-installing the offending package at the same time will often solve the problems.

3.3 Issue #3 -- using '--force-reinstalls'

When encountering an install plan that would break a package, cabal-install offers the possibility of continuing regardless. Doing '--force-reinstalls' *will* break something and this will cause problems in the long run.

Instead what should be done is to use the command 'ghc-pkg unregister' (or the 'cabal-uninstall' program) to remove the packages that would get broken. This is sometimes a large manual chore, but it saves trouble.

Also, if the packages that would get broken are needed, reinstalling within the same cabal install command can often help.

3.4 Issue #4 -- installing packages with incompatible version bounds

Cabal packages have the option of specifying the upper bounds of package dependencies, which is important for making sure that programs that are operational today will also build next week, even if some of their dependencies have had API breaking changes.

The downside of this is that when some widely used package has API breaking changes, really many other packages must be upgraded. As Hackage has no central authority responsible for this, some packages are left behind. Installing such packages with newer versions of their dependencies becomes impossible.

Nowadays, with excellent tools like packdep, which inform the package authors of constraining upper bounds on their packages, this is less of a problem than it used to be. Also, in many cases this can be fixed by simply bumping the upper bound to the next version. If you can't wait the package maintainer to do this, you can do:

> cabal unpack troublesomepackage

and relaxing the upper bound in the .cabal file of the resulting directory. Now, you can try installing the relaxed version of the package by adding path to this directory in the cabal-install command that was giving you trouble.

Notice that the upper version bounds are there for a reason and relaxing them might result in non-functional packages.

3.5 Issue #5 -- packages with external dependencies

Some cabal packages are just wrappers on other libraries, such as gtk. Cabal cannot, by itself, install such dependencies and they must be installed manually.