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.
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".