The basic task of the `ghc' driver is to run each input file through the right phases (parsing, linking, etc.).
The first phase to run is determined by the input-file suffix, and the last phase is determined by a flag. If no relevant flag is present, then go all the way through linking. This table summarises:
phase of the suffix saying flag saying (suffix of) compilation system "start here" "stop after" output file ---------------------------------------------------------------- literate pre-processor .lhs - - C pre-processor (opt.) - - - Haskell compiler .hs -C, -S .hc, .s C compiler (opt.) .hc or .c -S .s assembler .s -c .o linker other - a.out
Thus, a common invocation would be: `ghc -c Foo.hs'
Note: What the Haskell compiler proper produces depends on whether a native-code generator is used (producing assembly language) or not (producing C).
The option `-cpp' must be given for the C pre-processor phase to be run, that is, the pre-processor will be run over your Haskell source file before continuing.
The option `-E' runs just the pre-processing passes of the compiler, outputting the result on stdout before stopping. If used in conjunction with -cpp, the output is the code blocks of the original (literal) source after having put it through the grinder that is the C pre-processor. Sans `-cpp', the output is the de-litted version of the original source.
The option `-optcpp-E' runs just the pre-processing stage of the C-compiling phase, sending the result to stdout. (For debugging or obfuscation contests, usually.)