[makefile] How do you get the list of targets in a makefile?

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 :).