Building GHC in under /8/ minutes

In response to my last post, Simon Marlow suggested building the first GHC stage with -O, hoping that an optimised GHC in turn will be faster compiling the libraries and second stage. Here’s the result:

With the following build.mk:

SRC_HC_OPTS     = -H64m -Onot -fasm
GhcStage1HcOpts = -O -fasm
GhcStage2HcOpts = -Onot -fasm
GhcLibHcOpts    = -Onot -fasm
GhcLibWays      =
SplitObjs       = NO

On a 2 processor, 4 core linux machine, running with -j10:

make -j10 > /dev/null  1015.77s user 155.19s system 249% cpu 7:49.50 total

Great! A new GHC build record (I think). Can’t wait till the 16 core machine arrives…

Building GHC in under 10 minutes

People often complain at how long the GHC build process can be. This is even more of an issue for developers working on libraries, or the compiler itself, who need to quickly check their code typechecks and links inside the glorious maze that is GHC’s builds system.

With the fairly recent GNU make -j fixes, and a decent multicore machine, you can cut your build times dramatically. Here’s a transcript, with some hints on getting fast turnarounds from GHC builds:

$ cat /proc/cpuinfo
processor       : 0
vendor_id       : GenuineIntel
cpu family      : 15
model           : 4
model name      : Intel(R) Xeon(TM) CPU 2.80GHz
stepping        : 8
cpu MHz         : 2800.184
cache size      : 2048 KB
bogomips        : 5604.39

processor       : 7
vendor_id       : GenuineIntel
cpu family      : 15
model           : 4
model name      : Intel(R) Xeon(TM) CPU 2.80GHz
stepping        : 8
cpu MHz         : 2800.184
cache size      : 2048 KB
bogomips        : 5600.47

$ uname -msr
Linux 2.6.15.3-general i686

$ bzip2 -dc ghc-6.6-src.tar.bz2 | tar xf -
$ cd ghc-6.6
$ cat ../build.mk
SRC_HC_OPTS     = -H64m -Onot -fasm
GhcStage1HcOpts = -Onot -fasm
GhcStage2HcOpts = -Onot -fasm
GhcLibHcOpts    = -Onot -fasm
GhcLibWays      =
SplitObjs       = NO

$ mv ../build.mk ./mk/
$ autoreconf
$ ./configure
checking build system type... i686-pc-linux-gnu
checking host system type... i686-pc-linux-gnu
checking target system type... i686-pc-linux-gnu
Canonicalised to: i386-unknown-linux
...
config.status: creating config.mk
config.status: creating include/HsRegexPosixConfig.h
config.status: include/HsRegexPosixConfig.h is unchanged

$ time nice gmake -j10 > /dev/null
ghc: 25107068 bytes, 5 GCs, 125160/125160 avg/max bytes residency (1 samples), 63M in use, 0.00 INIT (0.00 elapsed), 0.05 MUT (0.53 elapsed), 0.02 GC (0.02 elapsed) :ghc
...
/usr/bin/ar: creating libHSghc.a
make -j10 > /dev/null  1299.72s user 163.13s system 250% cpu 9:44.08 total

$ compiler/stage2/ghc-inplace --version
The Glorious Glasgow Haskell Compilation System, version 6.6

And we’re done! So, use GNU make’s -j flag, disable optimisations, use the native code generator, and get as many cores as you can.