makeReads `GNUmakefile`, `makefile`, or `Makefile` and builds the default goal.
Comprehensive GNU make and Makefile reference covering targets, prerequisites, recipes, variables, includes, conditionals, pattern rules, and command-line usage.
Run make, choose files, select targets, and control execution.
makeReads `GNUmakefile`, `makefile`, or `Makefile` and builds the default goal.
make testBuilds or executes the recipe for target `test`.
make -f build/Makefile deployUse `-f` to point make at a specific file.
make -C services/api testUseful in monorepos and wrapper scripts.
make -j8Allows multiple recipes to run in parallel when dependencies permit.
make -n deployGreat for inspecting what a target would do.
make -tUseful for recovery and dependency graph alignment.
make -qHandy in CI checks or wrapper scripts.
make --print-directory -C app testUseful when debugging recursive make.
make --debug=bGNU make supports several debug modes such as `a`, `b`, `v`, `i`, `j`, and `m`.
make --warn-undefined-variablesVery useful in large makefiles with many variables.
make -p -nShows built-in rules, variables, and parsed state.
Core makefile structure and everyday patterns.
build/app: main.o util.o
cc -o build/app main.o util.oA rule maps a target to prerequisites and the commands needed to update it.
bundle.js: app.js ui.js api.js
cat $^ > $@`$^` expands to all prerequisites and `$@` to the target name within the recipe.
.PHONY: test
test:
pytest -qUse phony targets for commands like `test`, `clean`, and `deploy`.
.PHONY: lint fmt
lint fmt:
pnpm biome check .Useful when several targets truly run the same command.
Require creation order without forcing rebuilds when the prerequisite timestamp changes.
dist/app.js: src/app.js | dist
cp $< $@
dist:
mkdir -p distPrerequisites after `|` enforce order only.
node_modules/.stamp: package-lock.json
npm ci
touch $@
A stamp file is often cleaner than making a phony install target rerun every time.
.PHONY: clean
clean:
rm -rf dist build *.oClassic maintenance target.
.DEFAULT_GOAL := helpClearer than relying on the first target in the file.
Recursive, simple, conditional, and shell-expanded variables.
SRC = $(wildcard src/*.c)`=` creates a recursively expanded variable.
CURDIR_ABS := $(shell pwd)`:=` is useful when you want shell commands or functions evaluated once.
CFLAGS += -Wall -WextraWorks with both recursive and simple variables.
ENV ?= devOften used with environment overrides like `make ENV=prod deploy`.
make IMAGE_TAG=2026.03.06 deployCommand-line variables override normal makefile assignments.
override CFLAGS += -gUse sparingly when the makefile must enforce a setting.
export AWS_PROFILE := prod-adminExported variables are inherited by recipe shells and recursive make invocations.
unexport DEBUGUseful when a parent environment leaks unwanted values.
$(info CC came from $(origin CC))Origins include `default`, `environment`, `file`, `command line`, and more.
$(info CFLAGS flavor: $(flavor CFLAGS))Useful when debugging unexpected expansions.
Split makefiles and branch on environment or platform.
include config.mk rules/*.mk`include` is excellent for shared project fragments.
-include .env.mkCommon for generated dependency files and local overrides.
ifeq ($(ENV),prod)
API_URL := https://api.example.com
else
API_URL := https://api.dev.example.com
endifGNU make conditionals run during parsing, not execution.
ifdef CI
TEST_FLAGS += --maxfail=1
endifUseful for CI-vs-local behavior.
ifeq ($(OS),Windows_NT)
RM := del /Q
else
RM := rm -f
endifPortable projects often branch on Windows vs Unix-like behavior.
Targets that alter how make interprets rules and files.
.PHONY: all clean test lint format helpPrevents file name collisions and speeds make slightly by skipping implicit rule search.
.SILENT:
# or prefix a line with @Silence all recipes or use `@command` for individual lines.
.DELETE_ON_ERROR:Helpful for avoiding corrupt output files after failures.
.ONESHELL:
deploy:
set -eu
cd infra
terraform apply -auto-approveWithout `.ONESHELL`, each recipe line runs in a separate shell.
.SECONDEXPANSION:
$(OUT_DIR)/%.o: $$(SRC_DIR)/%.c
cc -c $< -o $@Advanced GNU make feature used with dynamic prerequisite lists.
.NOTPARALLEL:Useful for non-parallel-safe recipes.