RECIPE
Makefile Patterns
Reusable templates for C++ projects — from single-binary builds to multi-target libraries with automatic dependency tracking.
Minimal Single Binary
CXX := clang++ CXXFLAGS := -std=c++20 -Wall -Wextra -O2 LDFLAGS := SRCS := $(wildcard src/*.cpp) OBJS := $(SRCS:.cpp=.o) BIN := build/nimbus $(BIN): $(OBJS) mkdir -p build $(CXX) $(LDFLAGS) $^ -o $@ %.o: %.cpp $(CXX) $(CXXFLAGS) -c $< -o $@ .PHONY: clean clean: rm -rf build
Automatic Dependency Generation
DEPDIR := .deps DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.d %.o: %.cpp | $(DEPDIR) $(CXX) $(CXXFLAGS) $(DEPFLAGS) -c $< -o $@ $(DEPDIR): mkdir -p $@ -include $(OBJS:.o=.d)
Multi-Target Library
STATIC_LIB := build/libnimbus.a SHARED_LIB := build/libnimbus.so $(STATIC_LIB): $(OBJS) mkdir -p build ar rcs $@ $^ $(SHARED_LIB): CXXFLAGS += -fPIC $(SHARED_LIB): $(OBJS) mkdir -p build $(CXX) -shared $(LDFLAGS) $^ -o $@ all: $(STATIC_LIB) $(SHARED_LIB)
Release vs Debug
BUILD ?= debug ifeq ($(BUILD),release) CXXFLAGS += -O3 -DNDEBUG BIN := build/release/nimbus else CXXFLAGS += -O0 -g -DDEBUG BIN := build/debug/nimbus endif $(BIN): $(OBJS) mkdir -p $(dir $@) $(CXX) $(LDFLAGS) $^ -o $@
Tip: Always use .PHONY for targets that don't produce files. Combine with -j$(nproc) for parallel builds.