makefilegnu-maketargets

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


I've used rake a bit (a Ruby make program), and it has an option to get a list of all the available targets, eg

> rake --tasks
rake db:charset      # retrieve the charset for your data...
rake db:collation    # retrieve the collation for your da...
rake db:create       # Creates the databases defined in y...
rake db:drop         # Drops the database for your curren...
...

but there seems to be no option to do this in GNU make.

Apparently the code is almost there for it, as of 2007 - http://www.mail-archive.com/help-make@gnu.org/msg06434.html.

Anyway, I made little hack to extract the targets from a makefile, which you can include in a makefile.

list:
    @grep '^[^#[:space:]].*:' Makefile

It will give you a list of the defined targets. It's just a start - it doesn't filter out the dependencies, for instance.

> make list
list:
copy:
run:
plot:
turnin:

Solution

  • Preface:


    Note: This answer has been updated to still work as of GNU make v4.3 - let us know if you come across something that breaks.

    This is an attempt to improve on Brent Bradburn's great approach as follows:


    Curiously, GNU make has no feature for listing just the names of targets defined in a makefile. While the -p option produces output that includes all targets, it buries them in a lot of other information and also executes the default target (which could be suppressed with -f/dev/null).

    Place the following rule in a makefile for GNU make to implement a target named list that simply lists all target names in alphabetical order - i.e.: invoke as make list:

    .PHONY: list
    list:
    	@LC_ALL=C $(MAKE) -pRrq -f $(firstword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/(^|\n)# Files(\n|$$)/,/(^|\n)# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | grep -E -v -e '^[^[:alnum:]]' -e '^$@$$'
    # IMPORTANT: The line above must be indented by (at least one) 
    #            *actual TAB character* - *spaces* do *not* work.
    

    Important: On pasting this, make sure that the last line is indented by exactly 1 actual tab char. (spaces do not work).

    Note that sorting the resulting list of targets is the best option, since not sorting doesn't produce a helpful ordering in that the order in which the targets appear in the makefile is not preserved.
    Also, the sub-targets of a rule comprising multiple targets are invariably output separately and will therefore, due to sorting, usually not appear next to one another; e.g., a rule starting with a z: will not have targets a and z listed next to each other in the output, if there are additional targets.

    Explanation of the rule:

    Running make list then prints all targets, each on its own line; you can pipe to xargs to create a space-separated list instead.