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

A small project

To get started, let us look at the `Makefile' for an imaginary small `fptools' project, `small'. Each project in `fptools' has its own directory in `FPTOOLS_TOP', so the `small' project will have its own directory `FPOOLS_TOP/small/'. Inside the `small/' directory there will be a `Makefile', looking something like this:

  #     Makefile for fptools project "small"

  TOP = ..
  include $(TOP)/mk/boilerplate.mk

  SRCS = $(wildcard *.lhs) $(wildcard *.c)
  HS_PROG = small

  include $(TOP)/target.mk
This `Makefile' has three sections:
  1. The first section includes(1) a file of "boilerplate" code from the level above (which in this case will be `FPTOOLS_TOP/mk/boilerplate.mk'). As its name suggests, `boilerplate.mk' consists of a large quantity of standard `Makefile' code. We discuss this boilerplate in more detail in Section See section The main `mk/boilerplate.mk' file. Before the `include' statement, you must define the `make' variable `TOP' to be the directory containing the `mk' directory in which the `boilerplate.mk' file is. It is not OK to simply say
      include ../mk/boilerplate.mk  # NO NO NO
    Why? Because the `boilerplate.mk' file needs to know where it is, so that it can, in turn, `include' other files. (Unfortunately, when an `include'd file does an `include', the filename is treated relative to the directory in which `gmake' is being run, not the directory in which the `included' sits.) In general, every file `foo.mk' assumes that `$(TOP)/mk/foo.mk' refers to itself. It is up to the `Makefile' doing the `include' to ensure this is the case. Files intended for inclusion in other `Makefile's are written to have the following property: after `foo.mk' is `include'd, it leaves `TOP' containing the same value as it had just before the `include' statement. In our example, this invariant guarantees that the `include' for `target.mk' will look in the same directory as that for `boilerplate.mk'.
  2. The second section defines the following standard `make' variables: `SRCS' (the source files from which is to be built), and `HS_PROG' (the executable binary to be built). We will discuss in more detail what the "standard variables" are, and how they affect what happens, in Section See section The main `mk/target.mk' file. The definition for `SRCS' uses the useful GNU `make' construct `$(wildcard' pat`)', which expands to a list of all the files matching the pattern pat in the current directory. In this example, `SRCS' is set to the list of all the `.lhs' and `.c' files in the directory. (Let's suppose there is one of each, `Foo.lhs' and `Baz.c'.)
  3. The last section includes a second file of standard code, called `target.mk'. It contains the rules that tell `gmake' how to make the standard targets (Section See section Standard targets). Why, you ask, can't this standard code be part of `boilerplate.mk'? Good question. We discuss the reason later, in Section See section Boilerplate architecture. You do not have to `include' the `target.mk' file. Instead, you can write rules of your own for all the standard targets. Usually, though, you will find quite a big payoff from using the canned rules in `target.mk'; the price tag is that you have to understand what canned rules get enabled, and what they do (Section See section The main `mk/target.mk' file).

In our example `Makefile', most of the work is done by the two `include'd files. When you say `gmake all', the following things happen:

All `Makefile's should follow the above three-section format.

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