# Makefile Performance **Incremental builds** are Make's strength—only rebuild what changed. But slow Makefiles can still hurt productivity. Optimize with parallelization and caching. **Parallel builds with `-j`:** ```bash make -j4 # run up to 4 recipes in parallel make -j # unlimited parallelism (risky on limited systems) ``` `-j4` runs 4 compile jobs concurrently. On a 4-core machine, this gives ~4x speedup if recipes don't have synchronization conflicts. **Load-based parallelism:** ```bash make -l 4 # run while average load < 4 ``` `-l 4` starts new jobs only if system load is below 4. Prevents overwhelming the system. **Watching parallelization:** ```bash make -j4 --print-directory ``` `--print-directory` shows which subdirectory Make is working in, helpful for debugging parallel issues. **Avoiding redundant recipes:** Don't call expensive functions (like `$(shell ...)`) repeatedly: ```makefile # Slow: calls $(shell ...) every time SRCS = $(shell find . -name "*.c") # Fast: calls once, reuses result SRCS := $(shell find . -name "*.c") ``` Use `:=` (immediate assignment) for expensive operations so they're computed once. **Caching expensive computations:** ```makefile git_version := $(shell git describe --tags 2>/dev/null || echo "unknown") version.h: echo "#define VERSION \"$(git_version)\"" > version.h ``` Compute `git_version` once at Makefile parse time, reuse everywhere. **Reducing object files:** Fewer files = fewer compilation steps: ```makefile # Many small files (slow) app: main.o util.o helper.o string.o math.o ... gcc -o app $^ # Fewer larger files (faster) app: core.o utils.o ... gcc -o app $^ ``` Grouping source into fewer object files reduces link overhead. **Ccache for faster rebuilds:** Use ccache to cache compiler output: ```makefile CC = ccache gcc CXXFLAGS = -O3 -Wall ``` `ccache` memoizes compilation results. Recompiling the same file is instant if nothing changed. **Link-time optimization overhead:** LTO (`-flto`) makes linking slow: ```bash # Slow if many objects gcc -flto -o app *.o # Faster: parallelize gcc -flto -o app *.o -j4 ``` Use `-j` with GCC when using LTO for parallelized linking. **Profiling Make:** See where time is spent: ```bash make --debug=b > debug.txt 2>&1 ``` Produces a detailed log of every Make decision. Useful for identifying bottlenecks.