GHC's compiled output normally goes into a .hc, .o, etc., file, depending on the last-run compilation phase. The option -o foo re-directs the output of that last-run phase to file foo.
Note: this “feature” can be counterintuitive: ghc -C -o foo.o foo.hs will put the intermediate C code in the file foo.o, name notwithstanding!
EXOTICA: But the -o option isn't of much use if you have several input files… Non-interface output files are normally put in the same directory as their corresponding input file came from. You may specify that they be put in another directory using the -odir <dir> (the “Oh, dear” option). For example:
% ghc -c parse/Foo.hs parse/Bar.hs gurgle/Bumble.hs -odir `arch`
The output files, Foo.o, Bar.o, and Bumble.o would be put into a subdirectory named after the architecture of the executing machine (sun4, mips, etc). The directory must already exist; it won't be created.
Note that the -odir option does not affect where the interface files are put. In the above example, they would still be put in parse/Foo.hi, parse/Bar.hi, and gurgle/Bumble.hi.
MORE EXOTICA: The -osuf <suffix> will change the .o file suffix for object files to whatever you specify. (We use this in compiling the prelude.). Similarly, the -hisuf <suffix> will change the .hi file suffix for non-system interface files (see Section 3.7.3).
The -hisuf/-osuf game is useful if you want to compile a program with both GHC and HBC (say) in the same directory. Let HBC use the standard .hi/.o suffixes; add -hisuf g_hi -osuf g_o to your make rule for GHC compiling…
FURTHER EXOTICA: If you are doing a normal .hs-to-.o compilation but would like to hang onto the intermediate .hc C file, just throw in a -keep-hc-file-too option. If you would like to look at the assembler output, toss in a -keep-s-file-too, too.
Sometimes, you may cause GHC to be rather chatty on standard error; with -v, for example. You can instruct GHC to append this output to a particular log file with a -odump <blah> option.
If you have trouble because of running out of space in /tmp (or wherever your installation thinks temporary files should go), you may use the -tmpdir <dir> option to specify an alternate directory. For example, -tmpdir . says to put temporary files in the current working directory.
Alternatively, use your TMPDIR environment variable. Set it to the name of the directory where temporary files should be put. GCC and other programs will honour the TMPDIR variable as well.
Even better idea: Set the TMPDIR variable when building GHC, and never worry about TMPDIR again. (see the build documentation).