Futurice + Haskell

macOS (OSX) multi-GHC installer and (bleeding-edge) builds for cabal-install.


We made a small Python 3 script, haskell-on-macos.py, to install multiple GHC versions on macOS. It installs multiple GHC versions with the same file-system layout as packages from HVR PPA. Synopsis usage:

brew upgrade python@3
./haskell-on-macos.py --make-dirs --paths.d --ghc-alias=8.2.2 --cabal-alias=head install ghc-8.0.2 ghc-8.2.2 ghc-8.4.1 cabal-install-head
cabal new-build -w ghc-8.2.2 all

The script is written using Python 3, so you need to install it, for example using Homebrew. After that you can run the script to install ghc-8.0.2, ghc-8.2.2 and cabal-install-head (arguments), creating a cabal link to cabal-head (--cabal-alias), a ghc link to ghc-8.2.2 (--ghc-alias), making needing directories (--make-dirs) and creating /etc/paths.d/ghc file to adjust $PATH automatically (--paths.d). See --help for more information. Note:You will need to restart a shell (terminal) to re-adjust a $PATH using /etc/paths.d mechanism. After this you can use cabal new-build!.

Report issues to tracker on GitHub.

You can download the script using cURL and pipe it into python3 too, for example:

curl -sL https://haskell.futurice.com/haskell-on-macos.py | python3 - -h
curl -sL https://haskell.futurice.com/haskell-on-macos.py | python3 - --make-dirs --paths.d --ghc-alias=8.2.2 --cabal-alias=head install ghc-8.0.2 ghc-8.2.2 cabal-install-head

There are other ways to install GHC and cabal on macOS. These might suit your needs better, especially if you don't need multiple GHC or cabal-install HEAD.

Occassional Cabal builds

cabal executables build from master branch. These are useful if you want to try new, yet unreleased features. Or you need an already merged bug fix.

The date suffix indicates the --index-state used to build particular binary. Note: Cabal won't accept it as is, you have to reformat it into proper ISO-8601 UTC timestamp.

To "install" some version and if you feel lucky, use a script below (substitute another URL if needed). If https isn't enough for you (security-wise), you probably know how to use gpg --verify.

curl -L https://haskell.futurice.com/files/cabal-c219cd3f31c8e4e4bc71f93bbcd4de87830a986d-20180309-090233.xz | gunzip -c > /usr/local/bin/cabal-head
chmod a+x /usr/local/bin/cabal-head

The builds aren't triggered automatically or periodically, but fuzzily and manually. Ping me (phadej in various media) if you need a recent build.


All files are signed using the key:

pub   4096R/B8BB0BA4 2015-02-11 [expires: 2019-02-11]
      Key fingerprint = 5AC8 9B37 47FF 9612 810F  909E EB79 05A7 B8BB 0BA4
uid                  Oleg Grenrus <oleg.grenrus@iki.fi>
uid                  [jpeg image of size 12002]
sub   4096R/74B96F94 2015-02-11 [expires: 2019-02-11]

There is also a SHA256SUMS file, which is also signed.

Alex & Happy

There are no happy nor alex binaries provided. cabal new-build is able to install them on need.

Build environment

$ uname -a
Darwin ... 16.0.0 Darwin Kernel Version 16.0.0: Mon Aug 29 17:56:20 PDT 2016; root:xnu-3789.1.32~3/RELEASE_X86_64 x86_64


HVR's multi-ghc-travis uses haskell-on-macos.py to generate macOS (OSX) build jobs in Travis scripts.

Note:Run macOS-jobs only if you have a reason, for example C-bits in your package. At the moment (2017-07-25) open-source macOS (OSX) builds start very slowly. (ref).

A brief guide into new-build

  1. Don't use cabal install.
  2. Use only cabal new-build.


First we clone a repository we want to tinker with

~ $ git clone https://github.com/haskell-servant/servant
Cloning into 'servant'...

Change to the cloned repository

~ $ cd servant

Servant is a multi-package project, so it has a cabal.project file:

~/servant master $ cat cabal.project

For simple one-package projects, with <pkg>.cabal at the root of the repository, it's not required to have cabal.project. You may create one with echo "packages: ." > cabal.project, if you want.

Now we can build the whole project

~/servant master $ cabal new-build all
Resolving dependencies...
Build profile: -w ghc-8.2.1 -O1
In order, the following will be built (use -v for more details):
 - servant-0.11 (lib:servant) (first run)
 - servant-server-0.11 (lib:servant-server, exe:greet) (first run)
 - servant-foreign-0.10.1 (lib) (first run)
 - servant-docs-0.11 (lib) (first run)
 - servant-client-0.11 (lib) (first run)
 - servant-js-0.9.3 (lib) (requires build)
 - servant-docs-0.11 (exe:greet-docs) (first run)
 - tutorial-0.10 (lib) (first run)

You will probably see a longer list of "the following will be built". I have a short list, because cabal new-build have already built and cached dependencies for me, when I was working on other projects.

The all keyword asks cabal to build all components. We can however ask for specific one, for example:

~/servant master % cabal new-build servant:doctests
Resolving dependencies...
Build profile: -w ghc-8.2.1 -O1
In order, the following will be built (use -v for more details):
 - servant-0.11 (test:doctests) (first run)
There are also new-test, new-repl and bunch of other new- commands. Happy hacking!

Futurice – company sponsoring running this site and related work.