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