Here's one more sample makefile which has a few other things not mentioned so far that should be pretty self explanatory. It's set up to manage three versions of a library and test programs: one for general use (``release''), one with debugging information, and one with profiling information.
One last word about macros: You can even define them on the command line. Suppose you wanted to make the debugging version of the library:
gmake depend gmake clean gmake VERSION=DEBUG
Then, you get all the bugs worked out and want to time it using the profiler:
gmake clean gmake VERSION=PROFILE
Now, you've optimized it, so you build a version for general use:
gmake clean gmake VERSION=RELEASE
Note that when you define a macro on the command line, make ignores any definition of it that appears in the makefile. In this example, if you don't specify a version, you get ``release'' by default.
VERSION = RELEASE
DEBUG_CFLAGS = -g -DUSE_HEAP_STATS
PROFILE_CFLAGS = -pg
RELEASE_CFLAGS = -O2
ifeq "$(VERSION)" "PROFILE"
CFLAGS = $(PROFILE_CFLAGS)
ifeq "$(VERSION)" "DEBUG"
CFLAGS = $(DEBUG_CFLAGS)
ifeq "$(VERSION)" "RELEASE"
CFLAGS = $(RELEASE_CFLAGS)
CXX = g++
CC = $(CXX)
CXXFLAGS = $(CFLAGS)
TESTSRC = testdeq.cc testperf.cc
TESTOBJ = $(TESTSRC:%.cc=%.o)
TESTEXE = $(TESTSRC:%.cc=%)
LIBSRC = template.cc DequeHelper.cc deque.cc HeapStats.cc
LIBHEADER = DequeHelper.h deque.h adeque.h HeapStats.h Error.h
LIBOBJ = $(LIBSRC:%.cc=%.o)
SRC = $(LIBSRC) $(TESTSRC)
HEADER = $(LIBHEADER)
OBJ = $(LIBOBJ) $(TESTOBJ)
EXE = $(TESTEXE)
SUBMISSIONS = $(SRC) $(HEADER) Makefile README
makedepend -Y $(SRC)
rm -f $(OBJ) $(EXE)
testdeq: testdeq.o $(LIBOBJ)
testperf: testperf.o $(LIBOBJ)
rm -rf Submit
cp $(SUBMISSIONS) Submit
rm -rf deque deque.tar.gz
cp $(SUBMISSIONS) deque
tar -cf deque.tar deque
# gmake depend tacks on a bunch of stuff after this...