Comments

# foo bar

Rules, Dependency Lines, Target Sources, Shell Lines

Create TARGET which needs TARGETSOURCE1 TARGETSOURCE2 TARGETSOURCE3 ... by running SHELLLINE1 SHELLLINE2 SHELLLINE3 ...

TARGET: TARGETSOURCE1 TARGETSOURCE2 TARGETSOURCE3 ...
        SHELLLINE1
        SHELLLINE2
        SHELLLINE3
        ...

If TARGET is no real file you should insert a .PHONY TARGET rule:

.PHONY: TARGET
TARGET: TARGETSOURCE1 TARGETSOURCE2 TARGETSOURCE3 ...
          ...

It is even possible to jump with a SHELLLINE to another TARGET:

TARGET2:
        test -e FOO && $(make) TARGET3

Inference Rules

Instead of writing lots of rules like this:

foo.obj: foo.c
        $(CC) foo.c -o foo.obj

bar.obj: bar.c
        $(CC) bar.c -o bar.obj

....obj: ....c
        $(CC) ....c -o ....obj

You may also write:

%.obj: %.c
        $(CC) $< -o $@

$@ Current TARGET $(@F) Filename (without path) of the current TARGETS $< First Current TARGETSOURCES $^ All current TARGETSOURCES $? All current TARGETSOURCES the are out-of-date

Macros

VAR1 = foo bar
VAR2 = bar $(VAR1)

Macro Modifiers

Replace all ".obj" in VAR1 with ".c":

VAR2 = $(VAR1,.obj=.c)
VAR4 = $(VAR3:foo%.obj=bar%.c)

Invocation

Silent operation:

make -s

make TARGET:

make TARGET

Example

# Enforce that $CC contains a valid compiler
ifndef CC
CC=g++
endif

# Some variables that our compiler understands
CFLAGS=-c -Wall -O2
LDFLAGS= -L/usr/X11R6/lib -lGLU -lGL -lglut -lm

# List of all source files
SOURCES=myprg.cpp file1.cpp file2.cpp

# Replace .cpp with .h the get the header files names
HEADERS=$(SOURCES:.cpp=.h)

# Replace .cpp with .o the get the object file names
OBJECTS=$(SOURCES:.cpp=.o)

# Name of our binary
EXECUTABLE=myprg_bin

.PHONY: all
all: $(SOURCES) $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS) $(HEADERS)
        $(CC) $(LDFLAGS) $(OBJECTS) -o $@

%.o: %.cpp
        $(CC) $(CFLAGS) $&lt; -o $@

.PHONY: clean
clean:
        -rm *.o
        -rm *~
        -rm $(EXECUTABLE)

Links

GNU MAKE