Skip to content

Preprocessing without invoking external `cpp`

Currently, modules using the CPP language extension are processed by assembling a command line invoking an external cpp program. This is not ideal especially on Windows, because it means users of GHC-as-a-library need MinGW or similar suites installed just to use the GHC frontend.

One way of improving this could be to use an in-proc library like cpphs to implement this preprocessing step. The module GHC.SysTools.Cpp currently exposes a monolithic doCpp :: ... -> IO () function that takes care of a lot of aspects of preprocessing:

  1. Macros describing the target architecture and the backend
  2. Macros for GHC version included from ghcversion.h
  3. Macros for package versions (included from generated temporary text files)
  4. Include directories
  • From packages (-I only)
  • From command line (-I and -iquote)
  1. Turn line pragmas on/off
  2. CPP invocation details: verbosity, tokenization mode, file I/O
  3. The actual invocation of cpp or cc -E

A good first step would be factoring out all the macro definition parts, and avoiding external files as much as possible. This cppDefs :: ... -> IO [(String, Maybe String)] function can take care of 1., 2., and 3., without any file-generating side-effect. Similarly, we can compute all the include directories separately. These two functions should then pave the way towards either turning them into a cpp command-line (i.e. the legacy mode), or passing them as data to a library implementation of preprocessing (e.g. cpphs or hpp).

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information