I took a few answers mentioned above and compiled this one, which can also generate a nice description for each target and it works for targets with variables too.
Example Makefile:
APPS?=app1 app2
bin: $(APPS:%=%.bin)
@# Help: A composite target that relies only on other targets
$(APPS:%=%.bin): %.bin:
echo "build binary"
@# Help: A target with variable name, value = $*
test:
echo $(MAKEFLAGS)
echo "starting test"
@# Help: A normal target without variables
# A target without any help description
clean:
echo $(MAKEFLAGS)
echo "Cleaning..."
MAKEOVERRIDES =
help:
@printf "%-20s %s\n" "Target" "Description"
@printf "%-20s %s\n" "------" "-----------"
@make -pqR : 2>/dev/null \
| awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' \
| sort \
| egrep -v -e '^[^[:alnum:]]' -e '^$@$$' \
| xargs -I _ sh -c 'printf "%-20s " _; make _ -nB | (grep -i "^# Help:" || echo "") | tail -1 | sed "s/^# Help: //g"'
Example output:
$ make help
Target Description
------ -----------
app1.bin A target with variable name, value = app1
app2.bin A target with variable name, value = app2
bin A composite target that relies only on other targets
clean
test A normal target without variables
How does it work:
The top part of the make help
target works exactly as posted by mklement0 here - How do you get the list of targets in a makefile?.
After getting the list of targets, it runs make <target> -nB
as a dry run for each target and parses the last line that starts with @# Help:
for the description of the target. And that or an empty string is printed in a nicely formatted table.
As you can see, the variables are even expanded within the description as well, which is a huge bonus in my book :).