Getting started with installing third-party Haskell packages

Since I’ve been away from the Haskell world for a long time, it’s been interesting to return and observe some surprises about the practical side of working with the language. For me, an early gotcha has been the relative paucity of information on how to obtain and install third-party software packages. So here’s my little contribution, in the form of simple instructions for the newcomer. I hope that someone will find them useful. If you’re using Debian, you’re in great shape; there’s a good chance that whatever third-party package you’re interested in is already available. Whatever the Haskell package is named, if there’s a corresponding Debian package, it will ave a lowercase name. So here’s how use the regular package management tools to see if, for example, the indispensable MissingH is available:
$ apt-cache search missingh libghc6-missingh-dev – Library of utility functions for Haskell, GHC6 package libhugs-missingh – Library of utility functions for Haskell, Hugs package missingh-doc – Documentation for Haskell utility library
Nice! Whether you prefer to do your Haskell hacking with hugs or ghc, you’re set. The “libghc6-” prefix indicates that the package is for use with ghc, while the”libhugs-” prefix denotes a hugs-specific version of the same package. Fedora users aren’t nearly so well-off. While hugs and ghc themselves are up to date and available in Fedora Extras, there are few third-party Haskell packages available. There exists a Fedora Haskell project, but it’s moribund; there are no packages available for FC6, for example. To level the playing field, I’ll discuss how to build and install a third-party project that I’m fairly sure hasn’t yet been turned into a Debian or other package. The first thing you should know is that Haskell has a de facto standard way of managing software packages, called Cabal. Cabal’s concept of a package is similar to, but independent of, the packages that your operating system’s package manager handles. A Cabal package has a name, a version number, and dependencies, but Cabal doesn’t know anything about the operating system’s packages; it has its own independent database of packages. If you use ghc, you can find out what packages Cabal thinks are installed using the “ghc-pkg list” command.
$ ghc-pkg -l /usr/lib64/ghc-6.6/package.conf: Cabal-1.1.6, GLUT-2.0, HGL-3.1, HTTP-2006.7.7, HUnit-1.1, OpenAL-1.3, OpenGL-2.1, QuickCheck-1.0, X11-1.1, base-2.0, cgi-2006.9.6, fgl-5.2, (ghc-6.6), haskell-src-1.0, haskell98-1.0, html-1.0, mtl-1.0, network-2.0, parsec-2.0, readline-1.0, regex-base-0.71, regex-compat-0.71, regex-posix-0.71, rts-1.0, stm-2.0, template-haskell-2.0, time-1.0, unix-1.0, xhtml-2006.9.13
I’m not going to discuss any of Cabal’s more interesting features here; I just want to illustrate the basics, because I couldn’t even find those a few days ago. The third-party package I’m going to work with is a new one, Martin Grabmueller’s rdtsc. It’s easiest to download using Darcs.
$ darcs get http://uebb.cs.tu-berlin.de/~magr/darcs/rdtsc/ $ cd rdtsc
A lovely feature of Cabal is that it acknowledges that people don’t necessarily want to install packages as root; you can install a package into a directory that’s specific to you, and Cabal will maintain a package database of your personal packages, as well as those installed system-wide. If you want to install a “you-only” package, it’s simple.
$ runghc Setup.hs configure –user –prefix=$HOME Configuring rdtsc-1.1.2… configure: /usr/bin/ghc-pkg configure: Dependency base-any: using base-2.0 configure: Using install prefix: /usr/local …blah blah…
This will print a lot of output, some of which is downright confusing and scary-looking:
configure: No happy found configure: No alex found
As far as I can tell, Cabal is merely complaining that some software that it would like to use, but that isn’t necessary, is missing. Unless configure explicitly says there’s an error, and exits with an error code, the build should run fine. Configuring for a system-wide install is just as easy; merely omit the “–user” and “–prefix” options.
$ runghc Setup.hs configure
(Just remember that you’ll need to run the final install step as root if you’re doing a system-wide install.) The next step is to build the package.
$ runghc Setup.hs build Preprocessing library rdtsc-1.1.2… Building rdtsc-1.1.2… [1 of 1] Compiling System.CPUTime.Rdtsc ( System/CPUTime/Rdtsc.hs, dist/build/System/CPUTime/Rdtsc.o ) /usr/bin/ar: creating dist/build/libHSrdtsc-1.1.2.a
And finally, the installation step. Cabal remembers whether you specified “–user” and the prefix you used when you configured the package, so you don’t need to tell it a second time.
$ runghc Setup.hs install
After the install, ghc-pkg should be able to find the package:
$ ghc-pkg list /usr/lib64/ghc-6.6/package.conf: Cabal-1.1.6, GLUT-2.0, HGL-3.1, HTTP-2006.7.7, HUnit-1.1, OpenAL-1.3, OpenGL-2.1, QuickCheck-1.0, X11-1.1, base-2.0, cgi-2006.9.6, fgl-5.2, (ghc-6.6), haskell-src-1.0, haskell98-1.0, html-1.0, mtl-1.0, network-2.0, parsec-2.0, readline-1.0, regex-base-0.71, regex-compat-0.71, regex-posix-0.71, rts-1.0, stm-2.0, template-haskell-2.0, time-1.0, unix-1.0, xhtml-2006.9.13 /home/bos/.ghc/x86_64-linux-6.6/package.conf: rdtsc-1.1.2
The last two lines of output are what we were looking for. We have the package installed! It should now be available to both ghc and the interactive interpreter:
$ ghci Prelude> :module +System.CPUTime.Rdtsc Prelude System.CPUTime.Rdtsc> rdtsc Loading package rdtsc-1.1.2 … linking … done. 3552638252
This stuff is actually documented, and quite thoroughly so, but I found it amazingly hard to find. If you don’t already know that (a) there’s a standard Haskell packaging mechanism and (b) exactly what commands you must run to work with it, it’s surprisingly hard to construct a Google query that will return a result that gives you any practical clue of what to do. Finally, thanks to the wonderful denizens of #haskell for guiding me through the maze over the past few days.
Posted in haskell, linux
One comment on “Getting started with installing third-party Haskell packages
  1. David Cabana says:

    Thank you very much for that. It was very helpful.

Leave a Reply

Your email address will not be published. Required fields are marked *

*