Site Tools


wiki:makefile-patterns

Table of Contents

Makefile Patterns

Pattern rules define a generic recipe for a class of targets. Instead of writing a rule for each .o file, write one pattern rule that matches all of them.

%.o: %.c
	gcc -c -o $@ $<

The % is a wildcard. This rule matches main.o (from main.c), util.o (from util.c), etc. $@ is the target (e.g., main.o), $< is the prerequisite (e.g., main.c).

Using pattern rules:

%.o: %.c
	gcc $(CFLAGS) -c -o $@ $<
 
app: main.o util.o helper.o
	gcc -o app $^
 
clean:
	rm -f *.o app

Make automatically applies the %.o: %.c rule to build any .o file from its corresponding .c file. No need to list every file individually.

Multiple patterns:

%.o: %.c
	gcc -c -o $@ $<
 
%.so: %.c
	gcc -fPIC -shared -o $@ $<

The first rule builds .o files, the second builds shared libraries (.so). Make chooses the appropriate rule based on the target.

Chained patterns: Make chains pattern rules automatically. If app needs main.o, and main.o can be built from main.c (which exists), Make chains the rules:

app: main.o
	gcc -o app main.o
 
main.o: main.c
	gcc -c -o main.o main.c

This is equivalent to explicitly listing the prerequisites. Make infers the dependency.

Suffix rules (old style):

.c.o:
	gcc -c $<

This is an older syntax for the same pattern rule. Avoid in new Makefiles; use %.o: %.c instead. It's clearer and more flexible.

Modifying implicit rules:

Make has built-in implicit rules. You can add prerequisites or override flags:

CFLAGS = -O3 -Wall
CXXFLAGS = -O3 -Wall -std=c++17
 
# Use the built-in %.o: %.c rule, but with our CFLAGS

The built-in rules use $(CFLAGS) and $(CXXFLAGS), so setting these variables affects all compilation.

Disabling patterns:

%.o: %.c
	@echo "Not using pattern rules"
	gcc -c -o $@ $<
 
main.o: main.c helper.c
	gcc -c -o main.o main.c helper.c  # explicit rule (overrides pattern)

Explicit rules take precedence over pattern rules. Use this for special cases.

wiki/makefile-patterns.md · Last modified: by 127.0.0.1