Makefiles
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
...
SHELLLINE1
SHELLLINE2
SHELLLINE3
...
If TARGET is no real file you should insert a .PHONY TARGET rule:
.PHONY: TARGET
TARGET: TARGETSOURCE1 TARGETSOURCE2 TARGETSOURCE3 ...
...
TARGET: TARGETSOURCE1 TARGETSOURCE2 TARGETSOURCE3 ...
...
It is even possible to jump with a SHELLLINE to another TARGET:
TARGET2:
test -e FOO && $(make) TARGET3
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
$(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 $@
$(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)
VAR2 = bar $(VAR1)
Macro Modifiers
Replace all ".obj" in VAR1 with ".c":
VAR2 = $(VAR1,.obj=.c)
VAR4 = $(VAR3:foo%.obj=bar%.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) $< -o $@
.PHONY: clean
clean:
-rm *.o
-rm *~
-rm $(EXECUTABLE)
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) $< -o $@
.PHONY: clean
clean:
-rm *.o
-rm *~
-rm $(EXECUTABLE)