Makefile Cheat Sheet
A Makefile is a build automation file used by
maketo define rules for compiling, building, and running projects efficiently.
Basic Structure
target: dependencies
<TAB> commandExample:
main:
gcc main.c -o mainIMPORTANT
Commands MUST start with a TAB, not spaces.
Simple Example
all: build
build:
gcc main.c utils.c -o app
clean:
rm -f appUsage:
make # runs "all" by default
make build
make cleanVariables
Define reusable values.
CC = gcc
CFLAGS = -Wall -Wextra -O2
TARGET = appUse them:
build:
$(CC) $(CFLAGS) main.c -o $(TARGET)Automatic Variables
| Variable | Meaning |
|---|---|
$@ | Target name |
$< | First dependency |
$^ | All dependencies |
Example:
app: main.c utils.c
$(CC) $^ -o $@Equivalent to:
gcc main.c utils.c -o appPattern Rules
Compile many files automatically.
%.o: %.c
$(CC) -c $< -o $@Explanation:
-
%.c→ any C file -
%.o→ corresponding object file
Full Build Example
CC = gcc
CFLAGS = -Wall -Wextra -O2
SRC = main.c utils.c
OBJ = $(SRC:.c=.o)
app: $(OBJ)
$(CC) $(OBJ) -o app
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f $(OBJ) appPhony Targets
Used for commands, not files.
.PHONY: clean run allExample:
run:
./appMultiple Targets
all: build test
build:
gcc main.c -o app
test:
./app --testConditionals
ifeq ($(OS),Windows_NT)
RM = del
else
RM = rm -f
endifFunctions
String substitution
FILES = main.c utils.c
OBJ = $(FILES:.c=.o)Wildcard
SRC = $(wildcard *.c)Notdir
Remove directories:
SRC = src/main.c src/utils.c
FILES = $(notdir $(SRC))Include Other Makefiles
include config.mkDefault Target
First target is default:
all:
echo "default"Or explicitly:
.DEFAULT_GOAL := allSilent Commands
all:
@echo "Building project"@ prevents command echoing.
Export Variables
export PATH := $(PATH):/custom/binRecursive Make
make -C subdirDebugging Makefiles
Print variable:
make -pDry run:
make -nVerbose output:
make --debugCommon Build Flow
all: build run
build:
gcc main.c -o app
run:
./app
clean:
rm -f appDirectory-Based Project Example
SRC = src
BIN = bin
CC = gcc
all:
mkdir -p $(BIN)
$(CC) $(SRC)/main.c -o $(BIN)/app
clean:
rm -rf $(BIN)Dependency Example
main.o: main.c main.h utils.hMeaning:
- rebuild
main.oif any header changes
Recursive Pattern Build
SRCS = $(wildcard *.c)
OBJS = $(SRCS:.c=.o)
app: $(OBJS)
$(CC) $^ -o $@Key Concepts
-
Target → what you want to build
-
Dependency → what it needs
-
Recipe → commands to build it
-
Variables → reusable values
-
Pattern rules → generic compilation rules
-
Phony targets → commands like
clean,run
Mental Model
file.c → compile → file.o
file.o → link → executable
Make tracks timestamps:
If dependency is newer → rebuild targetMost Used Commands
make
make clean
make all
make run
make -j4
make -n
make -BParallel Build
make -j4Builds using 4 threads (faster compilation).
Golden Rule
A good Makefile should:
- avoid repetition
- use variables
- use pattern rules
- include
clean - be readable, not clever