In this handout, we will take apart an example makefile and see how
the pieces contribute to a working whole.
prog3: main.o heap.o server.o
g++ -g main.o heap.o server.o -o prog3
main.o: main.C main.h heap.h server.h
g++ -g -c main.C heap.o: heap.C heap.h
g++ -g -c heap.C server.o: server.C server.h
g++ -g -c server.C
clean:
rm *.o prog3
Initial Notes
* A makefile is stored in the same directory as your source code
and is called 'Makefile' or 'makefile' (without the quotes of
course).
* To compile your program with a working makefile, type 'make
* -k' on the command line or 'M-x compile' and then 'make -k' in
emacs. The -k option tells the program make to continue to
compile files if it 'thinks' that there is some possibility of
success. (Note that this is an oversimplification. If the -k
option is specified and a command line returns an error
status, work is abandoned on the current rule, but continues
on other branches that do not depend on that rule. Read the
man page on make for more information.
Basic Structure
The structure of this makefile consists of three parts-the link rule,
the compilation rules, and the cleanup rule. Each type of rule has the
same basic format, but there are a few differences. The basic form is:
file: component-file1, component-file2, component-file3, ...
shell-command
* 'file' is both the name of the rule (such as the 'main.o'
rule) and usually the name that 'shell-command' creates
(e.g. the 'heap.o' rule creates the file 'heap.o').
* Putting a 'component-file' in the rule tells make that 'file'
is dependent on 'component-file' and that any time that
'component-file' is modified, 'file' will be invalidated and
will need to be remade (e.g. if server.h changes, server.o
will no longer reflect the source code and will need to be
recompiled).
* 'shell-command' is a command that make uses to bring 'file' up
to date (e.g. make will use 'g++ -g -c main.C' to compile
main.o).
The Link Rule
prog3: main.o heap.o server.o
g++ -g main.o heap.o server.o -o prog3
The link rule starts a makefile. Although you could type 'make clean'
on the command line and have it remove your extra junk files, if you
just type 'make' or 'make -k', make will assume that you want to start
with the first rule in the file.
* 'prog3' is the name of your executable.
* main.o, heap.o, and server.o are object files. These are files
created by the compiler, but are not executable. On the first
line, they tell the compiler that 'prog3' will need to be
recompiled if any of them change.
* g++ is the name of the compiler.
* '-g' tells the compiler to save debugging information. Note
that -g can appear anywhere on the line after the 'g++'.
* main.o, heap.o, and server.o on the second line are used by
g++ to produce the executable (prog3). In compiler
terminology, they are linked together to form prog3.
* '-o prog3' tells the compiler to create the executable prog3
with the results of the link. Note that the pair '-o prog3'
can be anywhere in that line after the g++.
The Compile Rule
main.o: main.C main.h heap.h server.h
g++ -g -c main.C
* Many things in this rule are similar to the link rule
structure.
* Note that we list heap.h as one of the component files. This
is because main.h includes heap.h (for this example
anyway). If we didn't list heap.h, then when we later modified
heap.h, the compiler would not recompile main.C and we would
get incorrect results.
* '-c' tells the compiler to produce an object file (a '.o'
file). Note that the option is independent of main.C. We could
just as easily written 'g++ -g main.C -c'.
The Cleanup Rule
clean:
rm *.o prog3
This is an optional rule. It allows you to type 'make clean' at the
command line to get rid of your object and executable files. Sometimes
the compiler will link or compile files incorrectly and the only way
to get a fresh start is to remove all the object and executable files.