CSC270 October 28 Tutorial: Makefiles
Makefiles
[ King 15.4 ]
`make' is a Unix program that helps in compiling large programs that
occupy more than one source file. Suppose you had a program that
occupied three source files:
maze.c
read.c
shortest-matrix.c
Typically, what you do is compile each file separately and then link
them together:
% gcc -c maze.c
% gcc -c read.c
% gcc -c shortest-matrix.c
% gcc -o mazem maze.o read.o shortest-matrix.o
The -c flag causes gcc to stop compiling after producing an object
file with the .o suffix. Thus, the first three lines above produce
the files
maze.o
read.o
shortest-matrix.o
The last line above links the three *.o files into an executable
called `mazem'.
It would be painful if you had to do this by hand every time you made
a change in your source code. In fact, you might forget which files
you made changes to and then forget to recompile, resulting in a
debugging nightmare!
`make' deals with this. You must create a `Makefile' that defines
the dependences between your files. For example,
mazem depends upon maze.o, read.o, and shortest-matrix.o
maze.o depends upon maze.c
read.o depends upon read.c
shortest-matrix.o depends upon shortest-matrix.c
The corresponding Makefile would contain
mazem: maze.o read.o shortest-matrix.o
gcc -o mazem maze.o read.o shortest-matrix.o
maze.o: maze.c
gcc -c maze.c
read.o: read.c
gcc -c read.c
shortest-matrix.o: shortest-matrix.c
gcc -c shortest-matrix.c
The lines of the form
FILE: FILE1 FILE2 FILE3 ...
define dependences, where FILE depends upon FILE1 FILE2 FILE3 ... If
you change any one of the file to the right of the colon, `make' will
recreate the file to the left of the colon.
WARNING: There must be at least one TAB after the colon. Otherwise,
`make' will not work.
The line below the dependency line gives a Unix command to recreate
FILE from FILE1, FILE2, FILE3, ... There can be more than one line
if necessary.
WARNING: These line must also start with TABs.
NOTE: If a *.o file depends only upon a *.c file of the same name, no
dependency line is necessary; `make' knows what to do. Thus, the
Makefile above could be shortened to:
mazem: maze.o read.o shortest-matrix.o
gcc -o mazem maze.o read.o shortest-matrix.o
Including compilation flags
There are several variables that can be used in the Makefile. The
most important is CC, which is the string used by `make' to run the C
compiler. If you want to include flags with every C compilation,
include the following at the top of your Makefile:
CC = gcc -g -Wall
Then `make' will use that string every time it does a C compilation.
However, you must then use $(CC) in your makefile everywhere that
you do a compilation. The Makefile would change to
CC = gcc -g -Wall
mazem: maze.o read.o shortest-matrix.o
$(CC) -o mazem maze.o read.o shortest-matrix.o
Including header files *.h
If your source files depend upon other *.h files that contain
definitions, it's often a good idea to state this in the Makefile.
For example, if read.c has a line of
the form
#include "defs.h"
then this is reflected in the Makefile as
read.o: read.c defs.h
Thus, `make' will recompile read.o if there is a change to read.c OR
to defs.h. As before, no compilation statement is necessary since
`make' knows how to create read.o from read.c.