41

When compiling a haskell source file via ghc --make foo.hs GHC always leaves behind a variety of intermediate files other than foo.exe. These are foo.hi and foo.o.

I often end up having to delete the .hi and .o files to avoid cluttering up the folders.

Is there a command line option for GHC not to leave behind its intermediate files? (When asked on #haskell, the best answer I got was ghc --make foo.hs && rm foo.hi foo.o.

6 Answers6

40

I've gone through the GHC docs a bit, and there doesn't seem to be a built-in way to remove the temporary files automatically -- after all, GHC needs those intermediate files to build the final executable, and their presence speeds up overall compilation when GHC knows it doesn't have to recompile a module.

However, you might find that setting the -outputdir option will help you out; that will place all of your object files (.o), interface files (.hi), and FFI stub files in the specified directory. It's still "clutter," but at least it's not in your working directory anymore.

Mark Rushakoff
  • 249,864
  • 45
  • 407
  • 398
  • I know this question is old but this tip is very handy. I've added an alias to my `./zshrc` for ghc to put all intermediate files into a folder every time I run ghc from the command line – djhworld Mar 25 '12 at 20:36
  • 1
    When I don't use cabal, I usually write a makefile (even on Windows), set the `-outputdir` as mentioned, and delete it automatically from within the makefile. – MasterMastic Aug 09 '14 at 06:48
  • 1
    I also find it easier to just write a shell script. Since my intention was just to test a program, I just wrote a `run.sh` with `ghc program.hs -outputdir dist && ./program && rm program && rm -rf dist/` – lucasarruda Jan 27 '15 at 15:29
25

GHC now has the options no-keep-hi-files and no-keep-o-files. See here for more information.

user76284
  • 1,269
  • 14
  • 29
16

My usual workflow is to use cabal rather than ghc directly. This sets the outputdir option into an appropriate build folder and can do things like build haddock documentation for you. All you need is to define the .cabal file for your project and then say cabal install or cabal build instead of run ghc directly. Since you need to follow this process in the end if you ever want to share your work on hackage, it is a good practice to get into and it helps manage package dependencies as well.

Edward Kmett
  • 29,632
  • 7
  • 85
  • 107
  • 1
    That's what I do as well. For every piece of Haskell code that's bigger than a single file, I setup a .cabal file. That is, I just copy an existing .cabal file from somewhere and modify it. I think someone is working on a `cabal --init` command to setup a default working space, which would be quite useful. – Tom Lokhorst Sep 11 '09 at 21:22
  • I'm fairly new to Haskell, but that's something I really like about cabal. cabal creates one directory (dist) and puts all output-files in that directory while building. It keeps other directories clean. – davidbe Sep 14 '09 at 07:14
6

You can set the -hidir to /dev/null, I think, sending them there. Also, the -fno-code option in general turns off a lot of output. You might just want to use Cabal.

Don Stewart
  • 137,316
  • 36
  • 365
  • 468
3

Turns out that using -hidir/-odir/-outputdir is no good; /dev/null is a file, and not a directory. See http://www.haskell.org/pipermail/xmonad/2010-May/010182.html

gwern
  • 223
  • 1
  • 8
1

2 cents to improve the workflow a bit:
We can put the following alias into the .bashrc (or similar) config file:

alias hsc='_hsc(){ ghc -no-keep-hi-files -no-keep-o-files "$@";}; _hsc'

And then just call

$ hsc compose.hs 
[1 of 1] Compiling Main             ( compose.hs, compose.o )
Linking compose ...
$ ls
compose  compose.hs
Jan Bodnar
  • 10,969
  • 6
  • 68
  • 77