Makefile Cheatsheet - Build Automation
Make shaves rebuilds to a minimum because of one idea: a target only reruns when its prerequisites changed. That means rules, not commands, are the thing to learn — pattern rules like %.o: %.c, automatic variables $@ and $^, and declaring .PHONY for the non-file targets. This table keeps those essentials plus the := versus = assignment gotcha in one place.
Variables & Assignment 6
CC = gccRecursively expanded var (expands on use, may have side effects)
CC := gccSimply expanded var (expands at definition; recommended)
CC ?= gccConditional assignment (= if undefined)
CFLAGS += -WallAppend to a variable
export PATH := /opt/bin:$(PATH)Export a variable to sub-processes
$(CC) or ${CC}Reference a var (parens or braces)
Automatic Variables 7
$@The current target name
$<The first prerequisite
$^All prerequisites (deduplicated)
$+All prerequisites (with duplicates)
$*The % stem in a pattern rule
$?Prerequisites newer than the target
$(@D) / $(@F)Target's directory / filename part
Rules & Targets 5
target: deps\n\trecipeBasic rule: target, prerequisites, recipe
.PHONY: clean installDeclare a phony target (avoids file-name clash)
all: prog1 prog2Default target (first non-dot target)
clean:\n\trm -f *.o $(TARGET)Clean object files
install: target\n\tcp target /usr/local/binInstall target to a system path
Pattern Rules 5
%.o: %.c\n\t$(CC) -c $< -o $@Pattern rule: each .o from its .c
%.o: %.c $(HDRS)Add extra prerequisites (headers) to a pattern rule
$(OBJDIR)/%.o: $(SRCDIR)/%.cCross-directory pattern rule
OBJS := $(SRCS:.c=.o)Substitution reference (batch suffix change)
$(OBJS): obj/%.o: src/%.cStatic pattern rule with explicit targets
Built-in Functions 8
$(wildcard *.c)Expand a wildcard to a file list
$(patsubst %.c,%.o,$(SRCS))Pattern substitution (.c -> .o)
$(filter %.c %.h,$(SRCS))Filter words matching a pattern
$(filter-out %.test,$(SRCS))Filter out matching words
$(strip $(string))Strip leading/trailing whitespace
$(shell date +%Y)Run a shell command, return output
$(subst from,to,text)Text substitution (literal)
$(foreach var,list,text)Map over a list to build text
Conditionals 5
ifeq ($(OS),Windows_NT)\n...\nendifEqual check
ifneq ($(CC),gcc)\n...\nendifNot-equal check
ifdef DEBUG\nCFLAGS += -g\nendifIf a variable is defined
ifndef RELEASE\n...\nelse\n...\nendifConditional with else branch
$(if $(DEBUG),-g,-O2)if() function: 2nd arg if true, else 3rd
Practical Examples 6
SRCS := $(wildcard src/*.c)\nOBJS := $(SRCS:.c=.o)Auto-collect sources and build object list
include config.mkInclude another Makefile (split config)
.DEFAULT_GOAL := installSet the default goal explicitly
vpath %.c src:src2Set a search path for a suffix
make -j4Parallel build (4 jobs)
make CFLAGS="-O2 -g"Override variables from the CLI (highest priority)
Tips
- Recipe lines MUST start with a Tab, not spaces - the most common mistake.
- The .PHONY target ignores a same-named file on disk; good for clean/install.
- $@ = target, $< = first prerequisite, $^ = all prerequisites - the three most-used automatic vars.
- := expands immediately, = defers; prefer := to avoid recursive side effects.
- include other.mk pulls in another Makefile, good for large projects.
- CLI variables override Makefile assignments; use override to prevent that.
Official References
Each command links to its official documentation below, so you can verify the latest usage and read deeper.
Maintained by LaoHand
Publicly updated on Jul 19, 2026, continuously proofread against official docs.
Contact Us
Wrong command or description? Send us corrections, business inquiries or product feedback by email.
Contact Us