Practical cabal-dev


Cabal-dev is a tool for sandboxed builds of Haskell packages. In my use of cabal-dev I need to:

  • build several packages with common cabal-dev environment
  • build and run some programs which use those packages to test them
  • repeat with different versions of GHC

My current way of using cabal-dev:

  • Let say package A depends on package B. Then go to package B's directory, and cabal-dev configure, cabal-dev install-deps, cabal-dev install.
  • Then go to package A's directory, and use -s flag of cabal-dev: cabal-dev -s path/to/packageB/cabal-dev configure, cabal-dev -s /path/to/packageB/cabal-dev install-deps, cabal-dev -s path/to/packageB/cabal-dev install. I can use relative path here.

This way both packages share the same environment. Now if I want to build some program which depends on both packages, I do:

GHC_PACKAGES_PATH=/path/to/packageB/cabal-dev/packages-7.0.3.conf/: ghc --make someProgram.hs

Please note : in the GHC_PACKAGES_PATH, it tells GHC to use its system-wide package database too. I don't recommend to export GHC_PACKAGES_PATH, it seems to break cabal-dev.

If the program uses some third party dependency (e.g. -lHSfoo-1.2.3), the linker may fail to find that library. Then to build that program I have to do:

GHC_PACKAGES_PATH=/path/to/packageB/cabal-dev/packages-7.0.3.conf/: ghc --make someProgram.hs -L/path/to/packageB/cabal-dev/packages-7.0.3/lib/foo-1.2.3/ghc-7.0.3/

Fortunately, GHC-7.2 and GHC-7.4 don't require -L flag anymore, and find all libraries automatically.

I switch GHC versions just by updating the PATH variable.

Probably there are better and easier ways to do sandboxed builds, please let me know.