Phony targets and make as a task runner

Make · Essentials · 10 min

Most Makefiles in modern projects are task runners, and .PHONY is what makes them reliable.

Targets such as clean, test or run don't produce a file named after themselves. That works by accident until someone creates a file or directory called test: make sees it exists with no prerequisites, decides it is up to date and silently does nothing.

Declare such targets phony:

.PHONY: all clean test

A phony target is always considered out of date, so its recipe always runs, and make doesn't look for a file with that name.

Conventions worth following:

  • all is the first target and builds everything; clean removes generated files; test, lint, install do what they say.
  • A phony target can depend on other targets: check: lint test runs both.
  • Use rm -f in clean so it doesn't fail when files are already gone.

As a task runner, make gives every project the same entry points (make test, make run), handles dependencies between tasks, and is installed almost everywhere. A self-documenting help target is a common touch: put ## description after each target and print them with a little grep and awk.

Set .DEFAULT_GOAL := help if you'd rather show help than build when someone types just make.

Example

.PHONY: help test lint check clean
.DEFAULT_GOAL := help

help:  ## show this help
	@grep -E '^[a-z]+:.*## ' $(MAKEFILE_LIST) | awk -F':.*## ' '{printf "%-8s %s\n", $$1, $$2}'

test:  ## run the tests
	python3 -m pytest -q

lint:  ## check style
	ruff check .

check: lint test  ## lint, then test

clean:  ## remove build output
	rm -rf build dist .pytest_cache

# $ make
# help     show this help
# test     run the tests
# ...

Remember

  • Mark non-file targets with .PHONY so they always run
  • Conventional targets: all, clean, test, install
  • A phony target can just depend on others, like check: lint test

Watch out for

  • Forgetting .PHONY and a directory named test or build makes the target silently do nothing.

Check yourself

  1. A project has a directory called docs and a rule docs: with no .PHONY. What does make docs do?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: www.gnu.org/software/make/manual/make.html#Phony-Targets