The Haskell Package System

Isaac Jones

Simon Peyton Jones

Simon Marlow

Malcolm Wallace

Ross Patterson

The Haskell Library Infrastructure Project is an effort to provide a framework for developers to more effectively contribute their software to the Haskell community. This document specifies the Haskell Package System (HPS), which contributes to the goals of the Haskell Library Infrastructure Project.

Specifically, the HPS describes what a Haskell package is, how these packages interact with the language, and what Haskell implementations must to do to support packages. The HPS also specifies some infrastructure (code) that makes it easy for tool authors to build and distribute conforming packages.

The HPS is only one contribution to the Library Infrastructure project. In particular, the HPS says nothing about more global issues such as how authors decide where in the module name space their library should live; how users can find a package they want; how orphan packages find new owners; and so on.

The HPS has been discussed by the implementors of GHC, Nhc98, and Hugs, all of whom are prepared to implement it. The proposal is now open for wider debate. Please contribute by emailing .

Table of Contents
1. The Haskell Package System: goals
1.1. Dramatis personae
1.2. An example
2. The Haskell Package System: overview
2.1. Packages
2.2. Packages and the Haskell language
2.3. Packages and compilers
2.4. Package distributions
2.5. The Setup script
3. What the compilers must implement
3.1. Building and registering a package
3.1.1. Global packages and user packages
3.1.2. Exposed packages and hidden packages
3.1.3. Registration invariants
3.2. The -package compiler flag
3.3. The interface to hc-pkg
3.4. Syntax of installed package description
4. The setup script
4.1. The package description
4.2. The setup script specification
4.2.1. configure
4.2.2. build
4.2.3. install
4.2.4. register and unregister
4.3. Examples
4.3.1. Bob the Builder and Sam Sysadmin
4.3.2. System packagers (Debian, RPM etc)
5. The HPS simple build infrastructure
5.1. Overview
5.2. Package description in the simple build infrastructure
5.3. Distribution.Simple
5.4. The Makefile route
A. Related Systems
A.1. Debian
A.2. Python Distutils
A.3. CPAN and Boost
A.4. FreeBSD's Ports System
A.5. The XEmacs Packaging System
A.6. Make-Based Systems
A.7. hmake

1. The Haskell Package System: goals

The Haskell Package System (HPS) has the following main goal: to specify a standard way in which a Haskell tool can be packaged, so that it is easy for consumers to use it, or re-package it, regardless of the Haskell implementation or installation platform.

The HPS also supports tool authors by providing an infrastructure that automates the process of building and packaging simple tools. It is not necessary to use this code—indeed complex libraries may exceed its abilities—but it should handle many cases with no trouble.

1.1. Dramatis personae

The HPS serves a number of different people:

  • Joe User is simply a Haskell user. He does not download new packages. Nevertheless, he needs to know about his Haskell compiler's -package flag (see Section 3).

  • Bob the Builder and Sam Sysadmin both download, build, and install new packages. The only difference between the two is that Sam has root permission, and can install packages in more globally-visible places.

  • Roland RPM, Donald Debian, and Willie Windows build Linux RPM, Debian, and Windows installer packages respectively (this list is not exhaustive). They do this as a service for Angela Author and the community, and may know little or nothing about the internal details of the Haskell packages they are wrapping up.

  • Angela Author wants to write a simple Haskell tool, and distribute it with minimum fuss, in such a way that all the above folk can easily use it.

  • Marcus Makefile is like Angela, but more sophisticated. He has a complicated tool, and uses makefiles. Still, he wants to arrange that Roland, Donald, Bob, Sam, and Joe don't need to know about his internal complexity.

We describe Angela and Marcus as producers of their packages, and all the others as package consumers.

1.2. An example

To give the idea, here is a simple example. Angela has written a couple of Haskell modules that implement sets and bags; she wants to distribute them to Bob as a package called, say, angela-coll. Let's say that the modules are Data.Set, Data.Bag, Angela.Internals. (The HPS says nothing about how Angela decides where in the name space to put her modules.) Angela only wants to expose the first two to Bob; the Angela.Internals module is (as its name suggests) internal to the package.

Angela decides to use the simple build infrastructure that the HPS provides. She is working in a directory ~/coll. In there she puts the modules, in sub-directories driven by their module name: ~/coll/Data/Set.hs, ~/coll/Data/Bag.hs, and ~/coll/Angela/Internals.hs. Next, she writes a package description, which she puts in ~/coll/pkg.desc:

    name:     angela-coll
    version:  1
She also creates a three-line Haskell file ~/coll/Setup.lhs as follows:
  #! runhugs

  > import Distribution.Simple( main )
The first line arranges that when Angela executes Setup.lhs as a shell script, the shell will invoke runhugs, which will in turn run main imported from the library Distribution.Simple. This library implements the HPS simple build infrastructure.

Now she is ready to go. She types:

  ./Setup.lhs configure --ghc
  ./Setup.lhs build
  ./Setup.lhs src-dist
The first line readies the system to build the tool using GHC; for example, it checks that GHC exists on the system. The second line checks that the tool does indeed build flawlessly. (At this point she can write and execute tests, as we discuss later.) The third line wraps up the package as a source distribution, making the file ~/coll/angela-coll-1.tar.gz.

Angela emails the tar file to Bob, who untars it into tmp/coll. He cd's to that directory and types

  ./Setup.lhs configure --ghc
  ./Setup.lhs build
  ./Setup.lhs install
He's all done. Now in his Haskell programs, Bob can simply import the new modules Data.Set and Data.Bag. He does not need to give extra flags to GHC to tell it to look for Angela's modules; they are there automatically. If Angela used the same module names as someone else, Bob may need finer control: see Section 3.

If Angela wrote her modules in a suitably portable variant of Haskell, Bob could also have said --hugs or --nhc in his configure line, and the package would have been built and installed for those compilers instead.