Go to the first, previous, next, last section, table of contents.

Makefile dependencies in Haskell: using `mkdependHS'

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'.


Go to the first, previous, next, last section, table of contents.