make

Make ( the command is 'make' ), is a utility used to build projects, and is available on all unix style systems. The idea is to establish dependancies for building a program, and they typing make followed by a target name will build the binary for you, so you don't have to remember how to build your program.

Makefile

Make, by default, reads the file called 'Makefile' in the current working directory. Each target in a makefile has the name, its dependancies, and the instruction to build the target. A dependancy may be another target, this avoids redundant work.

note: the instruction lines after the target must start with a tab
Here is a simple example:

#   anything after the "#" symbol is a comment, like the C++ "//"

# WARNING: the indents MUST be a tab
# link the object file(s) into a program
prog1: prog1.o
        g++ -Wall prog1.o -o prog1

# compile each source file to an object file
prog1: prog1.cpp
        g++ -Wall -c prog1.cpp

clean:
        rm -f prog1
Here is another example that has a couple of .o files

prog2: main.o stack.o
        g++ -Wall main.o stack.o -o prog2

# the main and stack code include stack.h so it is a dependancy
# the -c command is compile only, which creates the .o file
main.o: main.cpp stack.h
        g++ -Wall -c main.cpp

stack.o: stack.cpp stack.h
        g++ -Wall -c stack.cpp

clean:
        rm -f prog2 *.o
The following example builds a binary from multiple modules, without recompiling unchanged code. It comiples each section into an object file, and links them together. It is similar to the previous example, except it uses variable definitions.
# CC, CFLAGS, CXXFLAGS, and LDFLAGS are variables
# using them makes it easier to change compilers or compile options
# you may use any name you want, but some like CC have specific meaning
CXX=g++         # the compiler
CXXFLAGS=-Wall  # c++ compiler flags
LDFLAGS=-Wall   # linker flags
.SUFFIXES:      # clear all built in suffix rules

cool_prog: String.o Queue.o cool_prog.o
        $(CXX) $(LDFLAGS) String.o Queue.o cool_prog.o -o cool_prog

String.o: String.cpp String.h
        $(CXX) $(CXXFLAGS) -c String.cpp

Queue.o: Queue.cpp Queue.h
        $(CXX) $(CXXFLAGS) -c Queue.cpp

cool_prog.o: cool_prog.cpp cool_prog.h
        $(CXX) $(CXXFLAGS) -c cool_prog.cpp

clean:
        rm -f *.o cool_prog

There are predefined variables in "make" as well. Here is the previous "Makefile" using them, and showing the meanings in the comments. Here is the previous makefile using these predefined variables, without the help target.

CC=g++
CXXFLAGS=-g -Wall
LDFLAGS=-g -Wall
.SUFFIXES:      # clear all built in suffix rules
#   $<  first depandancy
#   $^  all depandancies
#   $@  target
# these are not used very often
#   $*  file root name
#   $?  dependacies that are newer than the target

cool_prog: String.o Queue.o cool_prog.o
        $(CC) $(LDFLAGS) $^ -o $@

String.o: String.cpp String.h
        $(CC) $(CXXFLAGS) -c $<

Queue.o: Queue.cpp Queue.h
        $(CC) $(CXXFLAGS) -c $<

cool_prog.o: cool_prog.cpp cool_prog.h
        $(CC) $(CXXFLAGS) -c  $<

clean:
        rm -f *.o cool_prog

If you have to build multiple programs in a single makefile, just use a dummy target that lists the targets you want built.


.SUFFIXES:      # clear all built in suffix rules
all: prog1 prog2

prog1: foo.o prog1.o
        g++ -Wall foo.o prog1.o -o prog1

prog2: foo.o prog2.o
        g++ -Wall foo.o prog2.o -o prog2

prog1.o: prog1.cpp foo.h
        g++ -Wall -c prog1.cpp

prog2.o: prog2.cpp foo.h
        g++ -Wall -c prog2.cpp

foo.o: foo.cpp foo.h
        g++ -Wall -c foo.cpp

clean:
        -rm -f *.o prog1 prog2
More info on variables, built in rules, and minimal Makefiles :
I can't build the same two programs as above with this Makefile
CXX=g++
CXXFLAGS=-Wall
CC=g++
LDFLAGS=-Wall
TARGETS=prog1 prog2

all: ${TARGETS}
prog1: prog1.o foo.o 
prog2: prog2.o foo.o 
prog1.o: prog1.cpp foo.h
prog2.o: prog2.cpp foo.h
foo.o: foo.cpp foo.h

clean:
        -rm -f *.o ${TARGETS}
This works as long as you follow some naming conventions ( and do not clear the suffix rules ). The resulting executable must have the same base name as the first object file, and the object file must have the same base name as the first source (cpp) file. The base name is the file name without the extension ( ex: .o .cpp ).

CXXFLAGS are the flags passed to the compiler when doing the "-c" compiles on your cpp files ( the c version is CFLAGS ). CC and LDFLAGS must be defined when linking c++ code since the compiler will default to using gcc otherwise to link the object files, since it can't tell if the source is c or c++, based on the .o extension.

If you need to link any libraries with your executable define LDLIBS or LOADLIBES. The compiler flags for C code is CCFLAGS, CPPFLAGS are the preprocessor flags. To see the detailed builtin rules run "make -p".

Here is another source of info on Makefiles