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
drorata commented Nov 5, 2013

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
oluc commented Mar 17, 2014

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
pvdb commented Oct 6, 2015

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
pvdb commented Oct 6, 2015

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! 😄

@pvdb
Owner
pvdb commented Oct 6, 2015

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