-
-
Save pvdb/777954 to your computer and use it in GitHub Desktop.
# | |
# 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 ; } ; }' | |
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
OS X compatible: make -qp | awk -F":" "/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ {split($1,A,/ /);for(i in A)print A[i]}"
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!
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! 😄
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!
Embedding into makefile
#(3) implementation as a shell alias or as a Makefile target left as an exercise to the reader :-)
Thank you for your implementation, it was very helpful as I'm not familiar with sed etc. However, it's a bit tricky in case someone wants to embed this piece into his makefile, so here is the solution to save time:
make -rpn | sed -n -e '/^$/ { n ; /^[^ .#][^ ]*:/ { s/:.*$// ; p ; } ; }'
->
make -rpn | sed -n -e '/^$$/ { n ; /^[^ .#][^ ]*:/ { s/:.*$$// ; p ; } ; }'
Apparently make tries to expand single $ (dollar signs), so they need to be escaped with another $ (dollar sign).
Building on top of that I was able to use it to mark all targets as .PHONY
.PHONY: $(shell sed -n -e '/^$$/ { n ; /^[^ .\#][^ ]*:/ { s/:.*$$// ; p ; } ; }' $(MAKEFILE_LIST))
Works perfectly even for targets mentioned as dependencies.
Here there's a good option
Does not work with FreeBSD:
sed: 1: "/^$/ { n ; /^[^ ]*:/p } ": extra characters at the end of p command