Tools for working on GHC

Posted on June 11, 2019

In the old days of the Make build system, the only reliable IDE-like feature which was useful whilst working on GHC was a tags file. Even loading GHC into GHCi was not easily possible, the most simple of interactive development workflows. Thankfully now times are changing, there are now build targets to start a GHCi session which enables developers to use tooling such as ghcid or vscode-ghc-simple. Something which is quite important when working on a project with over 500 modules!

In this post we’ll briefly describe some recent advancements in developer tooling which have been made possible by the move to Hadrian.

ghci

The first target allows a developer to load GHC into GHCi. The -fno-code option is used which means that you can’t evaluate any expressions. It is useful for rapid feedback.

ghcid

ghcid can be used whilst working on ghc by invoking the ./hadrian/ghci.sh target.

There is a .ghcid file included in the repo which includes some basic settings instructing .ghcid to reload the session if hadrian/ changes. It might also be useful to add further directories here so that working with the many components of ghc is seamless.

haskell-ide-engine

Once you have a working ghci target then in theory it becomes possible to use all other tooling with your build system. I realised that it would be possible to get haskell-ide-engine working with ghc but it required a very significant refactor.

As a result, the branch can’t easily be merged back into the main repo but once it is merged then haskell-ide-engine will be more flexible and target agnostic.

Future work: running :main

A final goal is to be able to run GHC’s main function from inside the interpreter. In order to do this it’s necessary to interpret the code rather than pass -fno-code. With some modifications to the ./hadrian/ghci.sh script and patches by Michael Sloan we have been able to load load ghc into GHCi in the interpreted mode.

Unfortunately, this isn’t enough as in order to build programs with HEAD you also need to build libraries such as base with HEAD. The way around this is to first compile stage2 and then use the stage2 compiler to launch GHCi and load GHC into that. Then the libraries will be the correct versions and can be used to compile other modules.

A few months ago I got this working but since then it seems that the workflow has been broken. It’s a bit unfortunate that you have to jump through so many hoops in order to compile even a simple module but this is a unavoidable consequence of how GHC compiles and uses modules.

GHCi Debugger

Once you can execute :main, you can also use the GHCi debugger to debug GHC itself! This works without any problems but until you can use :main to compile programs then its of limited utility. I used the debugger to find the original reason why :main was failing whe compiling a program.