haskell/cabal — pull request #2255 by christiaanb (2014-12-04 11:41:27+00:00)
Title: Relocatable packages

This patch partially implements Relocatable Packages as discussed in https://github.com/haskell/cabal/issues/462. This entails:
* `RPATH` included in libraries and executables are `$ORIGIN` (`@loader_path` on OS X) relative.
* `data-files` are located relative to installation directory of the executable.
* `package.conf` files now contain directory specifications that are `${pkgroot}` relative.

It enables the installation of packages that are _prefix-relative_ with regards to dependencies in the same package database. For example, assume a relocatable ghc installation (e.g. http://ghcformacosx.github.io/ for OS X). You can add packages to this relocatable ghc installation by: `cabal install --global --enable-relocatable `. You can then make a new tar-ball of this installation and deploy it on someone else's machine, and the added libraries and executable will work out-of-the-box.

Another example is the `.cabal-sandbox` directory created by cabal sandboxes. When you do a `cabal install --dependencies-only --enable-relocatable` you will get a `.cabal-sandbox` directory which is relocatable anywhere on the developer machine. That is, all libraries and executables in the `.cabal-sandbox` directory are prefix-relative amongst eachother, however, they will contain hardcoded paths to the dependencies in the global package database (e.g. the `base` package). That is what is meant by: _prefix-relative with regards to dependencies in the same package database_.

`data-files` are located based on the location returned by `System.Environment.getExecutablePath`. I have confirmed that this works on my OS X and Linux machines. The current implementation of relocatable packages will not work on operating systems where `System.Environment.getExecutablePath` does not function correctly.

This patch also puts the handling of `RPATH` in the hands of Cabal on those systems on which the patch has been tested (OS X and Linux). When `--enable-relocatable` is specified, the `RPATH`s will be prefix-relative. Coincidentally, this also fixes https://github.com/haskell/cabal/issues/1568.

This patch has been tested on OS X 10.8, and Linux (CentOS 6.4), using GHC 7.8.3. Relocatable packages are only supported on those platforms, and installation will fail (Cabal will inform the user) if `--enable-relocatable` is specified for an unsupported platform.

As said, this _partially_ implements https://github.com/haskell/cabal/issues/462. To fully implement that issue, we would additionally need a `deploy` command. Which you would call like: `cabal deploy --deploy-dir= ` which would collect the binaries, libraries of the dependencies (in case of a dynamically linked executable), and data-files, and turn them into a relocatable bundle at the specified directory.