Cabal: bindir/libdir/datadir

Simon Marlow simonmar at
Fri Oct 7 04:34:39 EDT 2005

On 06 October 2005 18:46, Krasimir Angelov wrote:

> 2005/10/6, Simon Marlow <simonmar at>:
>>   --bindirrel=<dir>
>>   --libdirrel=<dir>
>>   --datadirrel=<dir>
>>   --libexecdirrel=<dir>
> bindirrel, libdirrel, ... looks a little bit verbose. Why not just
> bindir/libdir?

Because bindir/libdir are already used by autoconf with a different

>> 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
>> function: 
>>   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.
> What does the argument of getPrefix mean? Is it the --bindirrel value?
> With this semantic I should write something like this each time:
> getDataDir :: IO FilePath
> getDataDir = do
>   mb_path <- getPrefix bindir
>   case mb_path of
>      Just path -> return (path ++ datadir)
>      Nothing   -> return (prefix ++ datadir)

Yes, in fact it is:

getDataDir :: IO FilePath
getDataDir = do
  mb_path <- getPrefix binDirRel
  return (fromMaybe prefix mb_path `joinFileName` dataDirRel)

> I think that is better to add these templates to Paths.hs-inc.

Fine by me.  One problem is that I need to use stuff from
Distribution.Compat.FilePath, which isn't available outside Cabal, and
in any case we don't want every package to depend on Cabal.  I might
have to include a definition of joinFileName in Paths.hs-inc too.

> The
> prefix constant doesn't make sense under Windows. The program
> shouldn't assume that it is installed at any specific place.
> Paths.hs-inc should contain: getBinDir, getLibDir and getDataDir
> functions where under Unix they should return any hard coded value
> while under Windows they should compute the real value.
> I am worried about the meaning of these directories for the library
> packages. Under Unix the getDataDir will return any constant value, so
> that all executables which are linked to the given library will share
> the same data files. Under Windows if datadir is relative to the
> executable directory then each application will need its own copy of
> the shared files.

A library cannot be prefix-independent, only an executable.  That was
the assumption I was working with, sorry for not making it clear.

> It is even tricky to compute datadir for libraries
> under Windows. There will be two getDataDir functions. One in the
> Paths.hs-inc for the library and second for the executable to which
> the library is linked. The getDataDir in the library should know the
> bindir value specified for the executable in order to work properly.
> Instead of this I think that the right place for the library specific
> data files is:
> C:\Program Files\Common Files\<package>

That's sounds like a reasonable default.  The current defaults for a
library on Windows are:

  prefix        = C:\Program Files\
  bindirrel     = $package
  libdirrel     = Haskell\$package\$compiler
  datadirrel    = $package
  libexecdirrel = $package

you suggest changing datadirrel to:

  datadirrel    = Common Files\$package

and on Unix, for completeness:

  prefix        = /usr/local
  bindirrel     = bin
  libdirrel     = lib/$package/$compiler
  datadirrel    = share/$package
  libexecdirrel = libexec

> This might sense for Unix too. For some libraries it might be prefered
> to use /etc/<package>, so the datadir isn't necessary relative to the
> prefix.

No, I think we want datadir to be relative to prefix.  It should be
possible to install a library in your home directory, for example.


More information about the Libraries mailing list