我使用过一些rake(一个Ruby make程序),它有一个选项,可以获得所有可用目标的列表,例如

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

但是在GNU make中似乎没有这样做的选项。

显然,代码几乎已经有了,截至2007年- http://www.mail-archive.com/help-make@gnu.org/msg06434.html。

不管怎样,我做了一个小hack来从makefile中提取目标,你可以将它包含在makefile中。

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

它会给你一个已定义目标的列表。这只是一个开始——例如,它并没有过滤掉依赖关系。

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

当前回答

@nobar的回答很有帮助地展示了如何使用TAB补全来列出makefile的目标。

这对于默认提供此功能的平台(例如Debian、Fedora)非常有效。 在其他平台上(例如Ubuntu),你必须显式加载这个功能,正如@hek2mgl的回答所暗示的那样: . /etc/bash_completion安装几个制表符补全函数,包括make函数 或者,为make只安装制表符补全: . /usr/share/bash-completion /完成/

对于根本不提供这个功能的平台,比如OSX,你可以使用下面的命令来实现它:

_complete_make() { COMPREPLY=($(compgen -W "$(make -pRrq : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($1 !~ "^[#.]") {print $1}}' | egrep -v '^[^[:alnum:]]' | sort | xargs)" -- "${COMP_WORDS[$COMP_CWORD]}")); }
complete -F _complete_make make

注意:这并不像Linux发行版附带的制表符补全功能那么复杂:最值得注意的是,它总是以当前目录中的makefile为目标,即使命令行以-f <file>为目标的另一个makefile也是如此。

其他回答

不知道之前的答案为什么这么复杂:

list:
    cat Makefile | grep "^[A-z]" | awk '{print $$1}' | sed "s/://g" 

@nobar的回答很有帮助地展示了如何使用TAB补全来列出makefile的目标。

这对于默认提供此功能的平台(例如Debian、Fedora)非常有效。 在其他平台上(例如Ubuntu),你必须显式加载这个功能,正如@hek2mgl的回答所暗示的那样: . /etc/bash_completion安装几个制表符补全函数,包括make函数 或者,为make只安装制表符补全: . /usr/share/bash-completion /完成/

对于根本不提供这个功能的平台,比如OSX,你可以使用下面的命令来实现它:

_complete_make() { COMPREPLY=($(compgen -W "$(make -pRrq : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($1 !~ "^[#.]") {print $1}}' | egrep -v '^[^[:alnum:]]' | sort | xargs)" -- "${COMP_WORDS[$COMP_CWORD]}")); }
complete -F _complete_make make

注意:这并不像Linux发行版附带的制表符补全功能那么复杂:最值得注意的是,它总是以当前目录中的makefile为目标,即使命令行以-f <file>为目标的另一个makefile也是如此。

非常简单的AWK解决方案:

all:
    @awk -F'[ :]' '!/^all:/ && /^([A-z_-]+):/ {print "make " $$1}' Makefile

(注:这并没有涵盖所有被接受的极端情况,如这里解释的那样。)

对于讨厌AWK的人来说,为了简单起见,这个精巧的设计适合我:

help:
  make -qpRr $(lastword $(MAKEFILE_LIST)) | egrep -v '(^(\.|:|#|\s|$)|=)' | cut -d: -f1

(对于在Makefile外部使用,只需删除$(最后一个词…)或将其替换为Makefile路径)。

This solution will not work if you have "interesting" rule names but will work well for most simple setups. The main downside of a make -qp based solution is (as in other answers here) that if the Makefile defines variable values using functions - they will still be executed regardless of -q, and if using $(shell ...) then the shell command will still be called and its side effects will happen. In my setup often the side effects of running shell functions is unwanted output to standard error, so I add 2>/dev/null after the make command.

这是对jsp非常有用的回答(https://stackoverflow.com/a/45843594/814145)的修改。我喜欢这个想法,不仅要得到目标的列表,还要得到他们的描述。jsp的Makefile将描述作为注释,我发现在目标的描述echo命令中经常会重复。因此,我从每个目标的echo命令中提取描述。

Makefile示例:

.PHONY: all
all: build
    : "same as 'make build'"

.PHONY: build
build:
    @echo "Build the project"

.PHONY: clean
clean:
    @echo "Clean the project"

.PHONY: help
help:
    @echo -n "Common make targets"
    @echo ":"
    @cat Makefile | sed -n '/^\.PHONY: / h; /\(^\t@*echo\|^\t:\)/ {H; x; /PHONY/ s/.PHONY: \(.*\)\n.*"\(.*\)"/    make \1\t\2/p; d; x}'| sort -k2,2 |expand -t 20

make help输出:

$ make help
Common make targets:
    make all        same as 'make build'
    make build      Build the project
    make clean      Clean the project
    make help       Common make targets

注:

与jsp的答案相同,只能列出PHONY目标,这可能适用于您的情况,也可能不适用 此外,它只列出那些有echo或:命令作为recipe的第一个命令的PHONY目标。:表示“什么都不做”。我在这里将它用于那些不需要回声的目标,比如上面所有的目标。 帮助目标还有一个额外的技巧,就是在make帮助输出中添加“:”。