Table of Contents
Makefile Phony Targets
Phony targets don't produce files—they're commands. Mark them with .PHONY so Make doesn't check for a file with that name.
.PHONY: all clean install test all: app app: main.o util.o gcc -o app main.o util.o clean: rm -f *.o app install: app cp app /usr/local/bin/ test: app ./test.sh
Without .PHONY, if a file named clean exists, make clean won't run (Make thinks the target is up to date). .PHONY tells Make “this target is not a file; run it every time.”
Common phony targets:
.PHONY: all clean install test help all: @echo "Building application" gcc -o app *.c clean: rm -f *.o app install: all mkdir -p /usr/local/bin cp app /usr/local/bin/ test: all ./run_tests.sh help: @echo "Usage: make [target]" @echo "Targets:" @echo " all - build application (default)" @echo " clean - delete build artifacts" @echo " install - install to /usr/local/bin" @echo " test - run tests"
all target: Conventionally, all is the default target. If no target is specified, make all runs:
.PHONY: all all: app app: main.o util.o gcc -o app main.o util.o
make with no arguments is equivalent to make all.
clean target: Delete build artifacts:
.PHONY: clean clean: rm -f *.o *.so app rm -rf build/
Run with make clean before rebuilding to start fresh.
install target: Copy built files to their destination:
.PHONY: install install: all install -d $(PREFIX)/bin install -m 755 app $(PREFIX)/bin/app
Depends on all (builds first), then installs. $(PREFIX) allows customization (make PREFIX=/opt install).
test target: Run tests:
.PHONY: test test: app ./test_app @echo "Tests passed"
Depends on app (ensures app is built), then runs the test.
help target: Document available targets:
.PHONY: help help: @echo "Available targets:" @grep "^.PHONY:" Makefile | sed 's/.PHONY: //' | tr ' ' '\n' | grep -v "^$$"
The @ prefix suppresses command echoing; only the output is printed. Good for documentation.
Avoiding accidental files: If you have both a phony target and a file with the same name, the phony target always runs:
.PHONY: build build: mkdir -p build
Without .PHONY, if build/ directory exists, make build would do nothing.
