The hmake compilation management tool

Choosing a compiler
Hmake options
Compiler options
Hat options

Hmake is an intelligent compilation management tool for Haskell programs. It automatically extracts dependencies between source modules, and issues the appropriate compiler commands to rebuild only those that have changed, given just the name of the program or module that you want to build. Yes, you need never write a Makefile again!


  • hmake knows about interface (.hi) files. Even though a source module has changed, if its interface file has not changed, then other modules which import it do not need to be recompiled.
  • hmake is compiler-independent. The installation process automatically detects which Haskell compilers you have, and sets up hmake to use any of them. You can separately add or remove compilers to the configuration at any time after installation, and change which compiler is used as the default. You can easily use different versions of a compiler (e.g. ghc 4.08 + 5.02) without any extra hassle. (See hmake-config.)
  • hmake is aware of many pre-processors. Not only is the C preprocessor commonly used for selective imports, but tools such as happy, hsc2hs, c2hs, greencard, are also often used to generate Haskell modules. If hmake finds a module with the appropriate filename extension (.y, .ly, .hsc, .chs, .gc), it automatically runs the preprocessor before the compiler.

Minor Features

  • hmake can generate object files in a separate directory from your sources.
  • hmake understands the library package system.
  • hmake understands hierarchical module namespaces.
  • hmake understands the Hat tracer.


The basic option summary is:

    Usage: hmake [compiler] [hmake-opts] [compiler-opts] target ...
Choosing a compiler
-HC comp
-hc comp
Specify which compiler you want to use. If no compiler is specified, the default compiler is used. (See hmake-config to set the default.)
-f cfgfile Use cfgfile as the hmake configuration file. This file contains information about the Haskell compilers that are available. (See hmake-config for more information.)

You can use any form of the compiler name that would normally work directly on the command-line, for instance

  hmake -ghc Prog.hs
  hmake -HC=/usr/local/bin/ghc-5.02.2 Prog.hs
  hmake -hc ghc-5.02.2 Prog.hs
provided only that its configuration is already known to hmake, via hmake-config.


  • You can have more than one target: all of them are built.
  • If the target is a module source filename (i.e. with .lhs, .hs, .hi, or pre-processor extension), the module and everything it depends on is compiled, but not linked. e.g.
        hmake LiterateMod.lhs 
  • If the target is a program name (i.e. no extension), the appropriate modules are linked as well as compiled. e.g.
        hmake Prog 
  • An object or archive filename (.o, .a extension) cannot be a target, but if you add it to the commandline, it will be added into the final link.

Hmake Options

Most options are passed straight through to the appropriate compiler. However, hmake understands and strips the following options.

-clean remove all .o files relevant to the given targets (does not compile anything).
-realclean remove all .o and .hi files relevant to the given targets (does not compile anything).
-hat compile for the Hat tracing system.
-q Quiet - don't echo compilation commands.
-n Noexec - echo the compilation commands but don't execute them.
-g Graph - show module dependency graph (implies -n).
-M Makefile - show dependencies in Makefile format (implies -n).
-Md as for -M, but treats -d objdir specially.
-watch turn on debugging output.

Compiler Options

Hmake also makes use of some compiler options if you specify them. (That is, the options are used by hmake as well as being passed on to the compiler, with suitable translation if necessary.)

-dobjdir Search for (and compile) object files in(to) a separate objdir.
Search the directory dir for imported modules - compile them if necessary, and link against the resulting .o files.
-package pkgname Add the library package pkgname to the search path for interface files for imported modules. hmake knows how packages work in both ghc and nhc98. A warning is produced if the package cannot be found.
-Pdir Search the directory dir for interface files for imported modules. If an interface is found here, don't look for a source file to compile or link against. (hmake assumes it is the prelude or a library module that is already linked into the program in some other manner). This option is pretty-much obsolete now that packages are supported.

Some options are passed to the compiler's runtime system (using whatever underlying mechanism is appropriate for the particular compiler).

-[Hh]size Compiler's heap size.
-[KVA]size Compiler's stack size.
-[BS] Compiler's garbage collector information options.

You can force an option which would otherwise be interpreted by another part of the system to be passed to the compiler by enclosing it within +CTS ... -CTS delimiters. For example, with nhc98, to set the final executable's default heapsize rather than the compiler's heapsize, use +CTS -H4mb -CTS.


hmake understands cpp directives in the source modules: this is particularly useful for imports which differ depending on which compiler you are using. For example,

        #if defined(__HBC__) || defined(__GLASGOW_HASKELL__)
        import Native
        #elsif __NHC__
        import Binary
hmake automatically inserts the -cpp compiler option, but only for those modules which require it. The compiler symbols are defined automatically - you can also define other symbols on the commandline.
-Dsym Define the cpp symbol sym.
-Dsym=val Define the cpp symbol sym with the value val.

Various other Haskell-specific preprocessors (happy, c2hs, hsc2hs, greencard) are recognised and called automatically when the source filename indicates by its extension that they are required. It is not currently possible to pass extra options just to the pre-preprocessor.

.y A Happy grammar
.ly A literate Happy grammar
.gc GreenCard input
.chs c2hs input
.hsc hsc2hs input

Hat Options

hmake understands the Hat tracing system. This is essentially just a more complex pre-processor. For every module, the file is first transformed by hat-trans, generating a new module which is then compiled with some extra options. Additionally, if any other pre-processing is required, it must be done before hat-trans is called; an auxiliary interface file (.hx) is also tracked.

-hat compile for the Hat tracing system.
-trusted in conjunction with -hat, compile the targets in trusted mode, so that their internal calls are not traced.

The latest updates to this software are available on the WWW from (

Information last updated: 2002-08-09
York Functional Programming Group