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

        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

*       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, ...  

*       '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

*       '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

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

*       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

        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.