| name | make |
| description | Guide for using GNU Make build automation. Use when creating Makefiles, defining build rules, managing dependencies, or automating compilation workflows. Covers targets, prerequisites, variables, and common patterns. |
GNU Make
Basic Makefile Structure
# Variables
CC = gcc
CFLAGS = -Wall -g
TARGET = myprogram
# Default target (first target)
all: $(TARGET)
# Build rule: target: prerequisites
$(TARGET): main.o utils.o
$(CC) $(CFLAGS) -o $@ $^
# Pattern rule for object files
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
# Phony targets (not actual files)
.PHONY: all clean install
clean:
rm -f *.o $(TARGET)
Automatic Variables
| Variable |
Meaning |
$@ |
Target name |
$< |
First prerequisite |
$^ |
All prerequisites |
$? |
Prerequisites newer than target |
$* |
Stem of pattern match |
Variable Assignment
# Recursive (expanded when used)
VAR = value
# Simple (expanded when assigned)
VAR := value
# Conditional (only if not set)
VAR ?= default
# Append
VAR += more
Functions
# Wildcard - find files
SRCS := $(wildcard *.c)
# Substitution
OBJS := $(SRCS:.c=.o)
# or
OBJS := $(patsubst %.c,%.o,$(SRCS))
# Shell command
DATE := $(shell date +%Y%m%d)
# Conditional
DEBUG ?= 0
ifeq ($(DEBUG),1)
CFLAGS += -g -DDEBUG
endif
Common Patterns
Multi-directory Build
SRCDIR = src
OBJDIR = obj
BINDIR = bin
SRCS := $(wildcard $(SRCDIR)/*.c)
OBJS := $(patsubst $(SRCDIR)/%.c,$(OBJDIR)/%.o,$(SRCS))
$(BINDIR)/$(TARGET): $(OBJS) | $(BINDIR)
$(CC) $(CFLAGS) -o $@ $^
$(OBJDIR)/%.o: $(SRCDIR)/%.c | $(OBJDIR)
$(CC) $(CFLAGS) -c $< -o $@
$(OBJDIR) $(BINDIR):
mkdir -p $@
Dependency Generation
DEPFLAGS = -MMD -MP
DEPS := $(OBJS:.o=.d)
%.o: %.c
$(CC) $(CFLAGS) $(DEPFLAGS) -c $< -o $@
-include $(DEPS)
Library Building
# Static library
libfoo.a: foo.o bar.o
$(AR) rcs $@ $^
# Shared library
libfoo.so: CFLAGS += -fPIC
libfoo.so: foo.o bar.o
$(CC) -shared -o $@ $^
Running Make
# Build default target
make
# Build specific target
make clean
# Parallel build
make -j$(nproc)
# Dry run (show commands)
make -n
# Override variable
make CC=clang DEBUG=1
# Specify makefile
make -f Makefile.custom
Debugging Makefiles
# Print database
make -p
# Print why target is being rebuilt
make --debug=b
# Print variable value
$(info VAR is $(VAR))
$(warning This is a warning)
$(error This stops make)