It is reasonably straightforward to set up a `Makefile' to use with GHC, assuming you name your source files the same as your modules. Thus:
HC = ghc HCFLAGS = -fhaskell-1.3 -cpp -hi-diffs $(EXTRA_HC_OPTS) SRCS = Main.lhs Foo.lhs Bar.lhs OBJS = Main.o Foo.o Bar.o .SUFFIXES : .o .hi .lhs .o.hi: @: .lhs.o: $(RM) $@ $(HC) -c $< $(HCFLAGS) cool_pgm : $(OBJS) $(RM) $@ $(HC) -o $@ $(HCFLAGS) $(OBJS)
Note the cheesy `.o.hi' rule: It records the dependency of the interface (`.hi') file on the source. The rule says a `.hi' file can be made from a `.o' file by doing... nothing. Which is true.
(Sophisticated `make' variants may achieve some of the above more elegantly. What we've shown should work with any `make'.)
The only thing lacking in the above `Makefile' is interface-file dependencies. If `Foo.lhs' imports module `Bar' and the `Bar' interface changes, then `Foo.lhs' needs to be recompiled.
Putting dependencies of the form `Foo.o : Bar.hi' into your `Makefile' by hand is rather error-prone. Don't worry -- never fear, `mkdependHS' is here! (and is distributed as part of GHC) Add the following to your `Makefile':
depend : mkdependHS -- $(HCFLAGS) -- $(SRCS)
Now, before you start compiling, and any time you change the `imports' in your program, do `make depend' before you do `make cool_pgm'. `mkdependHS' will append the needed dependencies to your `Makefile'.
A few caveats about this simple scheme: (a) You may need to compile some modules explicitly to create their interfaces in the first place (e.g., `make Bar.o' to create `Bar.hi'). (b) You may have to type `make' more than once for the dependencies to have full effect. However, a `make' run that does nothing does mean "everything's up-to-date." (c) This scheme will work with mutually-recursive modules but, again, it may take multiple iterations to "settle."
To see `mkdependHS''s command-line flags, give it a duff flag, e.g., `mkdependHS -help'.