Skip to content
Create a gist now

Instantly share code, notes, and snippets.

List all targets (sometimes incorrectly referred to as "goals") in a GNU Makefile
#
# this gist can be used to list all targets, or - more correctly - rules,
# that are defined in a Makefile (and possibly other included Makefiles)
# and is inspired by Jack Kelly's reply to a StackOverflow question:
#
# http://stackoverflow.com/questions/3063507/list-goals-targets-in-gnu-make/3632592#3632592
#
# I also found this script - http://www.shelldorado.com/scripts/cmds/targets - which does
# something similar using awk, but it extracts targets from the "static" rules from a single
# Makefile, meaning it ignores any included Makefiles, as well as targets from "dynamic" rules
#
# Notes:
#
# (1) the sed expression is "scraping" the make output, and will hence break of the output format ever changes
# (2) the "-r" option excludes the built-in rules, as these are typically not relevant, but isn't required
# (3) implementation as a shell alias or as a Makefile target left as an exercise to the reader :-)
#
#
# in the directory containing your Makefile:
#
make -rpn | sed -n -e '/^$/ { n ; /^[^ .#][^ ]*:/p ; }'
#
# ... or add a touch of color by highlighting the targets in the rules:
#
make -rpn | sed -n -e '/^$/ { n ; /^[^ .#][^ ]*:/p ; }' | egrep --color '^[^ ]*:'
#
# ... or if you prefer just the list of targets, WITHOUT the dependencies:
#
make -rpn | sed -n -e '/^$/ { n ; /^[^ .#][^ ]*:/ { s/:.*$// ; p ; } ; }'
@drorata

This doesn't work on Mac OSX. I get:

sed: 1: "/^$/ { n ; /^[^ ]*:/p }\n": extra characters at the end of p command

Could be useful :)

@oluc

It lists ".PHONY:", I think it should not

@bbenne10

so change the regex...
make -rpn | sed -n -e '/^$/ { n ; /^[^ ]*:/p }' | egrep --color '^[^ .]*:'
should list everything EXCEPT lines that start with spaces or dots. This will exclude .PHONY

@michael-o

Does not work with FreeBSD: sed: 1: "/^$/ { n ; /^[^ ]*:/p }
": extra characters at the end of p command

@mklement0

To make the command work with BSD sed (as used on OSX and FreeBSD), simply append ; after the p - for more on the differences between GNU sed and BSD sed, see http://stackoverflow.com/a/24276470/45375

@ronanguilloux

OS X compatible: make -qp | awk -F":" "/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ {split(\$1,A,/ /);for(i in A)print A[i]}"

@pvdb
Owner

Hey @drorata,

You wrote:

This doesn't work on Mac OSX. I get:
sed: 1: "/^$/ { n ; /^[^ ]*:/p }\n":
extra characters at the end of p command

My bad, it is missing a ; after the p, as already mentioned by @mklement0 in a later comment... the correct version, tested on Mac OS X:

make -rpn | sed -n -e '/^$/ { n ; /^[^ ]*:/p ; }'

I have updated the gist accordingly ... thanks for spotting and reporting!

@pvdb
Owner

Hey @oluc,

You wrote:

It lists ".PHONY:", I think it should not

See note (3) in the script documentation:

(3) to improve the readability of the output, "| egrep -v '^.PHONY:'"can be appended to the pipeline

... or else @bbenne10's version of the pipeline.

I have also updated the gist itself, and it now filters out all occurrences of .PHONY... please have a whirl! :smile:

@pvdb
Owner

Hey @michael-o,

You wrote:

Does not work with FreeBSD:
sed: 1: "/^$/ { n ; /^[^ ]*:/p }\n":
extra characters at the end of p command

My bad, it is missing a ; after the p, as already mentioned by @mklement0 in a later comment... the correct version, tested on Mac OS X, but should also work on FreeBSD:

make -rpn | sed -n -e '/^$/ { n ; /^[^ ]*:/p ; }'

I have updated the gist accordingly ... thanks for spotting and reporting!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.