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.

SysOps·42 commands·Last updated 2026-07-19
makefileBuildCompilationAutomation

Variables & Assignment 6

CC = gcc
Recursively expanded var (expands on use, may have side effects)
CC := gcc
Simply expanded var (expands at definition; recommended)
CC ?= gcc
Conditional assignment (= if undefined)
CFLAGS += -Wall
Append 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\trecipe
Basic rule: target, prerequisites, recipe
.PHONY: clean install
Declare a phony target (avoids file-name clash)
all: prog1 prog2
Default target (first non-dot target)
clean:\n\trm -f *.o $(TARGET)
Clean object files
install: target\n\tcp target /usr/local/bin
Install 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)/%.c
Cross-directory pattern rule
OBJS := $(SRCS:.c=.o)
Substitution reference (batch suffix change)
$(OBJS): obj/%.o: src/%.c
Static 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...\nendif
Equal check
ifneq ($(CC),gcc)\n...\nendif
Not-equal check
ifdef DEBUG\nCFLAGS += -g\nendif
If a variable is defined
ifndef RELEASE\n...\nelse\n...\nendif
Conditional 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.mk
Include another Makefile (split config)
.DEFAULT_GOAL := install
Set the default goal explicitly
vpath %.c src:src2
Set a search path for a suffix
make -j4
Parallel 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