79693768

Date: 2025-07-08 06:52:44
Score: 3
Natty:
Report link

Any solution that doesn't get its list from the output of make -p or similar, i.e. tries to parse the targets in the Makefile(s) itself, is going to miss and/or show extra targets. sed, grep, awk, etc., without a pipe from make -p will not be accurate.

Additionally, any solution which requires gnu extensions to sed or grep will likely fail on Mac OS.

Here's my solution for a list target/help target that works on Mac OS (tested on Sonoma and Sequoia with the make that ships with Mac OS, GNU Make 3.81, built for i386-apple-darwin11.3.0) and Linux (tested on AlmaLinux 9.6, GNU Make 4.3, Built for x86_64-redhat-linux-gnu). It's cobbled together from four or five different answers I've found on SO, various mailing lists, and AI answers, and tweaked for my particular style of help (two hashes after the target list).

It supports cascading/included Makefiles, Makefiles not called Makefile, target definitions with multiple targets in them (e.g.: foo bar: baz ## create either foo or bar from baz), removes hidden targets (.hidden: hidden-file.txt ## don't show this hidden target) and all of the builtin-targets (e.g. .PHONY), removes targets that are if or ifdeffed out (e.g.: ifdef INCLUDE_ME\nmore-stuff: my-stuff ## build more-stuff from my-stuff if INCLUDE_ME is defined\nendif), sorts and de-dups, gives you the user-friendly command to use (basename of the command called, e.g. make, not /Library/Developer/CommandLineTools/usr/bin/make), and will cook waffles for you while you wait. Assuming you have that recipe in your Makefile.

It uses xargs with grep to ensure that only the targets that are valid are shown in the output. It also does not show any target that is missing the ## comment goes here in the target definition. So if you haven't commented a target, it won't get shown with this.

Also if you have a compound target where one of the targets is hidden (e.g.: target .hidden-target: ## make this target), neither will be shown in the help list.

If you just want the list of targets without the help messages, remove everything after the { print $$1 }' . No need to pipe to xargs grep and search for commented targets. Note: if you make this change and have a compound target where one is hidden (e.g.: target .hidden-target: ## normal and hidden targets here), the one not hidden will be shown as a valid target.

.PHONY: help
help: ## Show this help message
    @echo "$(notdir $(MAKE)) targets:"
    @LC_ALL=C $(MAKE) -qp -f $(firstword $(MAKEFILE_LIST)) : 2> /dev/null | awk -v RS= -F: '$$1 ~ /^[^#%. ]+$$/ { print $$1 }' | xargs -I % grep -E '^%(:| [a-zA-Z_ -]+:).*?## .*$$' $(MAKEFILE_LIST) | sort -u | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
Reasons:
  • Blacklisted phrase (1): help me
  • Blacklisted phrase (1.5): Any solution
  • Blacklisted phrase (1.5): any solution
  • Long answer (-1):
  • Has code block (-0.5):
  • Low reputation (0.5):
Posted by: Joseph Cheek