Clang-based GHC 9, done easy

Introduction

For various reasons, you might want a Clang-based GHC on a platform where Clang is not the default compiler. You might want to debug low-level trouble on Clang-default platforms (this was my use case), or perhaps you just want to use a different C compiler for your FFI code. Either way, this is a somewhat-fraught process. To help you along, I’ll present how you can do this easily, and without spending a week or so hitting your head against the wall.

This will only work for GHC 9.0.1. Similar instructions could be used for other versions, but they would require a different commit (the -g argument below), and providing all of these is outside the scope of this writeup.

Instructions

You will need:

  • ghcup, version 0.1.17.2. This is important, as lower versions will fail on the --overwrite-version argument.
  • Clang (lld can be used, but isn’t required).
  • GHC whose version is below 9. I used 8.10.7, from ghcup.
  • All the pieces needed to compile GHC. ghcup will let you know if you’re missing anything.

What to do:

  1. Download this patch. Put it in a folder whose path is easy to type, under a name that’s easy to type. For this example, assume we put it in /home/nyan/ghc-clang-patches/pie.patch.
  2. Invoke CC=clang ghcup compile ghc -b 8.10.7 -g 67683142f1e0d9f95bc1be0306b676b5d2e4e97f --patchdir=/home/nyan/ghc-clang-patches --overwrite-version='9.0.1-clang'
  3. Sit back and relax for a while.

If you are using a different version of GHC to 8.10.7, replace the argument to -b appropriately. If you have the RAM and cores to spare, you can pass -jN, where N is a number of parallel processes to use, which will save you considerable time. If you want a different version name, change what you pass to --overwrite-version.

After this is done, if successful, you will now have ghc-9.0.1-clang available to use.

Important note

Take care when using cabal build (and anything which might call it). Cabal cannot distinguish between version 9.0.1 and version 9.0.1-clang, and will thus cache libraries built with either of these compilers in the same location. This can cause linker errors if you end up mixing libraries built with 9.0.1 with stuff wanting to build with 9.0.1-clang.

To solve this problem, either manually remove any libraries in .cabal/store/ghc-9.0.1 before you use 9.0.1-clang, or pass --config-file with a 9.0.1-clang-specific Cabal config to cabal, specifying a different directory to cache libraries in.

Credit where it’s due

Thanks to Ben Gamari, who helped throughout this entire process, and maerwald, who maintains ghcup, and fixed the --overwrite-version bug so promptly.

11 Likes

Fantastic writeup, thank you very much!

2 Likes

Thanks! Hopefully nobody else will have to solve this Lament Configuration any time soon. :smile_cat:

1 Like