CSC270: 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.