### 2.6 A simple makefile ¶

For those unfamiliar with `make`, this section provides a simple demonstration of its use. Make is a program in its own right and can be found on all Unix systems. To learn more about the GNU version of `make` you will need to consult the GNU Make manual by Richard M. Stallman and Roland McGrath (see Further reading).

Make reads a description of a project from a makefile (by default, called `Makefile` in the current directory). A makefile specifies a set of compilation rules in terms of targets (such as executables) and their dependencies (such as object files and source files) in the following format:

    target: dependencies
            command

For each target, make checks the modification time of the corresponding dependency files to determine whether the target needs to be rebuilt using the corresponding command. Note that the `command` lines in a makefile must be indented with a single `TAB` character, not spaces.

GNU Make contains many default rules, referred to as implicit rules, to simplify the construction of makefiles. For example, these specify that `.o` files can be obtained from `.c` files by compilation, and that an executable can be made by linking together `.o` files. Implicit rules are defined in terms of make variables, such as `CC` (the C compiler) and `CFLAGS` (the compilation options for C programs), which can be set using `VARIABLE=VALUE` lines in the makefile. For C++ the equivalent variables are `CXX` and `CXXFLAGS`, while the make variable `CPPFLAGS` sets the preprocessor options. The implicit and user-defined rules are automatically chained together as necessary by GNU Make.

A simple `Makefile` for the project above can be written as follows:

    CC=gcc
    CFLAGS=-Wall
    main: main.o hello_fn.o

    clean:
    	rm -f main main.o hello_fn.o

The file can be read like this: using the C compiler `gcc`, with compilation option `-Wall`, build the target executable `main` from the object files `main.o` and `hello_fn.o` (these, in turn, will be built via implicit rules from `main.c` and `hello_fn.c`). The target `clean` has no dependencies and simply removes all the compiled files.4 The option `-f` (force) on the `rm` command suppresses any error messages if the files do not exist.

To use the makefile, type `make`. When called with no arguments, the first target in the makefile is built, producing the executable `main`:

    $ make
    gcc -Wall   -c -o main.o main.c
    gcc -Wall   -c -o hello_fn.o hello_fn.c
    gcc   main.o hello_fn.o   -o main
    $ ./main
    Hello, world!

To rebuild the executable after modifying a source file, simply type `make` again. By checking the timestamps of the target and dependency files, make identifies the files which have changed and regenerates the corresponding intermediate files needed to update the targets:

    $ emacs main.c  (edit the file)
    $ make
    gcc -Wall   -c -o main.o main.c
    gcc    main.o hello_fn.o   -o main
    $ ./main
    Hello, everyone!

Finally, to remove the generated files, type `make clean`:

    $ make clean
    rm -f main main.o hello_fn.o

A more sophisticated makefile would usually contain additional targets for installation (`make install`) and testing (`make check`).

The examples in the rest of this book are small enough not to need makefiles, but the use of make is recommended for any larger programs.

#### Footnotes

##### (4)

This assumes that there is no file called `clean` in the current directory—see the discussion of “phony targets” in the GNU Make manual for details.