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. https://asciinema.org/a/EKHiPuGgxhXz0ZHQgtR3OQd9G/embed?
ghcid
ghcid
can be used whilst working on ghc
by invoking the ./hadrian/ghci.sh
target. https://asciinema.org/a/HAu0U5cVbneuujaoUA92Nxld5/embed?
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. https://platform.twitter.com/embed/index.html?dnt=false&embedId=twitter-widget-0&frame=false&hideCard=false&hideThread=false&id=1110874588509016064&lang=en&origin=https%3A%2F%2Fmpickering.github.io%2Fposts%2F2019-06-11-ghc-tools.html&theme=light&widgetsVersion=ed20a2b%3A1601588405575&width=550px
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.