Futurice + Haskell

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

Note:ghcup does support macOS.


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.4.4 --cabal-alias= install ghc-8.0.2 ghc-8.2.2 ghc-8.4.4 ghc-8.6.5 ghc-8.8.1 cabal-install-
cabal new-build -w ghc-8.4.4 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.4.4 --cabal-alias= install ghc-8.0.2 ghc-8.2.2 ghc-8.4.4 ghc-8.6.5 ghc-8.8.1 cabal-install-

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-f2b2ab7c11541fecef81bd9f954d7ff33002c485-20190827-113809.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   rsa4096 2018-01-16 [SC] [expires: 2021-06-12]
      7E8A 0D73 F61F 0006 697A  1AFB D255 EF35 7806 99D5
uid           [ultimate] Toni Okuogume <toni.okuogume@futurice.com>
sub   rsa4096 2018-01-16 [E] [expires: 2021-06-12]

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 ... 17.7.0 Darwin Kernel Version 17.7.0: Thu Jun 21 22:53:14 PDT 2018; root:xnu-4570.71.2~1/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.