Cabal: bindir/libdir/datadir

Simon Marlow simonmar at
Thu Oct 6 06:29:30 EDT 2005

While I was away last week I hacked into Cabal support for
bindir/libdir/datadir, as previously discussed on this list.  However,
while doing it I changed my mind about the design so thought I'd run it
past the list.

The problem with bindir/libdir/datadir is that they are specified as
absolute  pathnames, but in reality most of the time they will be
relative to (i.e. subdirectories of) prefix.  Specifying them with
absolute pathnames is inconvenient because:

  -  The "setup copy" command already has --copy-prefix, and it would
     need additional arguments --copy-bindir, --copy-libdir etc. if
     bindir and friends were absoluate paths (actually, I don't know
     why we have --copy-prefix, when we should really have a --copy-to
     that is prepended to the existing prefix, that would eliminate
     the need for --copy-bindir etc.).

  -  On Windows and systems that support querying the pathname of a 
     running binary, we want to support prefix-independent installs,
     such that a binary can find its files by only knowing the
     directory layout under $prefix, not the value of prefix itself.
     If bindir/libdir/datadir are relative to prefix, we can do this.

However, specifying bindir/libdir/datadir with absolute pathnames is
desirable because:

  +  It's what autoconf does

  +  If the Cabal package is implemented using autoconf+make, then
     --bindir can be passed direct to ./configure (but implementing
     the appropriate impedence matching for relative paths isn't
     hard either).

In the end I plumped for relative pathnames, but I renamed the options:


How can the package itself find out what these paths are?  As discussed
previously, Cabal generates a file Paths.hs-inc containing

   prefix = "<dir>"
   binDirRel = "<dir>"
   libDirRel = "<dir>"
   ... etc ...

which can be #included into Haskell source.  Additionally I have the

   getPrefix :: FilePath{-binDirRel-} -> IO (Maybe FilePath)

which figures out prefix when called from a binary installed in
$prefix/$bindirrel.  If it returns Nothing, then you can fall back to
the hard-coded value of prefix from Paths.hs-inc.

With these changes I've Cabalised Alex (Happy & Haddock to follow).

Please shout if you object to the design in any way.  I plan to write a
section for the documentation describing all this.

There's one thing I'm not sure about yet: the default $libdirrel on Unix
systems is lib/<pkgid>/<compiler>, eg. lib/pkg-0.2/ghc-6.4, and you
might want to change just the "lib" bit, eg. to get
lib64/pkg-0.2/ghc-6.4.  It's annoying to have to specify the <pkgid> and
<compiler> when Cabal knows them, so we might want a simple substitution
syntax, such as --libdirrel=lib64/%p/%c.  Sound reasonable?

We might also want a simple way in the .cabal file to specify some files
to be installed in $datadir (I think someone suggested this before).
It's quite annoying to do it with hooks.


More information about the Libraries mailing list