What should I `make`?
Published on
I noticed a cool pattern at work recently: all of our Makefiles have a help target.
Running make help prints out all targets and includes any trailing comment on the same line.
And that solves essentially the only problem I've found with using make as a simple task runner:
Is this a verb-noun or noun-verb project?
So I took a random Makefile I had lying around at home and tried to make it self-documenting.
When I started, my work laptop was in another room and the internet was, like, right here, so I searched "self-documenting makefile" and found Self-Documented Makefile which helped me learn about MAKEFILE_LIST.
Clearly, I'm far from the first person to do this, but I think I've made some interesting improvements!
Anyway, here's the thing:
.DEFAULT_GOAL := help
.PHONY: help
help: ## List targets in this Makefile
@awk '\
BEGIN { FS = ":$$|:[^#]+|:.*?## "; OFS="\t" }; \
/^[0-9a-zA-Z_-]+?:/ { print $$1, $$2 } \
' $(MAKEFILE_LIST) \
| sort --dictionary-order \
| column --separator $$'\t' --table --table-wrap 2 --output-separator ' '
Document targets with end-of-line double-hash comments (##):
.PHONY: clean
clean: ## Remove output files
rm -rf dist
.PHONY: release
release: clean ## Build app in release mode
npm install
npm run build
And example output:
clean Remove output files
help List targets in this Makefile
release Build app in release mode
Features I kept:
- Non-doc comments can still be made with single-hashes.
- Running just
makeis equivalent tomake help. But TIL.DEFAULT_GOALis a GNU make extension.
Things I changed:
- Don't skip targets without documentation.
There's not often a lot to say about
make build, but it's still nice to know it's there. - In case you forget what
make helpdoes, it tells you. 😛 - Look, no
grep! I finally get to show off what I learned by reading Awk in 20 Minutes. - I recently learned that
sortorders some characters differently by default on MacOS from my normal Linux setup (BSD vs. GNU?) (also 🙁), so I tried to make that more consistent. I think the Makefile grammar makes it impossible to trigger that difference, but I'm not taking any chances! - I like tabular output but hate adjusting spacing.
I don't actually care about portability, so
columnworks great!