The C pre-processor cpp is run over your Haskell code only if the
-cpp option is given. Unless you are
building a large system with significant doses of conditional
compilation, you really shouldn't need it.

-D<foo>:

Define macro <foo> in the usual way. NB: does not affect
-D macros passed to the C compiler when compiling via C! For those,
use the -optc-Dfoo hack… (see Section 3.13.2).

-U<foo>:

Undefine macro <foo> in the usual way.

-I<dir>:

Specify a directory in which to look for #include files, in
the usual C way.

GHC has to link your code with various libraries, possibly including:
user-supplied, GHC-supplied, and system-supplied (-lm math
library, for example).

-l<FOO>:

Link in a library named lib<FOO>.a which resides somewhere on the
library directories path.

Because of the sad state of most UNIX linkers, the order of such
options does matter. Thus: ghc -lbar *.o is almost certainly
wrong, because it will search libbar.abefore it has
collected unresolved symbols from the *.o files.
ghc *.o -lbar is probably better.

The linker will of course be informed about some GHC-supplied
libraries automatically; these are:

-l equivalent

description

-lHSrts,-lHSclib

basic runtime libraries

-lHS

standard Prelude library

-lHS_cbits

C support code for standard Prelude library

-lgmp

GNU multi-precision library (for Integers)

-syslib <name>:

If you are using a Haskell “system library” (e.g., the POSIX
library), just use the -syslib posix option, and the correct code
should be linked in.

-L<dir>:

Where to find user-supplied libraries… Prepend the directory
<dir> to the library directories path.

-static:

Tell the linker to avoid shared libraries.

-no-link-chk and -link-chk:

By default, immediately after linking an executable, GHC verifies that
the pieces that went into it were compiled with compatible flags; a
“consistency check”.
(This is to avoid mysterious failures caused by non-meshing of
incompatibly-compiled programs; e.g., if one .o file was compiled
for a parallel machine and the others weren't.) You may turn off this
check with -no-link-chk. You can turn it (back) on with
-link-chk (the default).

-no-hs-main:

In the event you want to include ghc-compiled code as part of another
(non-Haskell) program, the RTS will not be supplying its definition of
main() at link-time, you will have to. To signal that to the
driver script when linking, use -no-hs-main.

Notice that since the command-line passed to the linker is rather
involved, you probably want to use the ghc driver script to do the
final link of your `mixed-language' application. This is not a
requirement though, just try linking once with -v on to see what
options the driver passes through to the linker.