我使用过一些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也是如此。

其他回答

对于讨厌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.

我把上面提到的几个答案编译成这个,它也可以为每个目标生成一个很好的描述,它也适用于有变量的目标。

Makefile示例:

APPS?=app1 app2

bin: $(APPS:%=%.bin)
    @# Help: A composite target that relies only on other targets

$(APPS:%=%.bin): %.bin:
    @# Help: A target with variable name, value = $*

test:
    @# Help: A normal target without variables

# A target without any help description
clean:

# A hidden target
.hidden:

help:
    @printf "%-20s %s\n" "Target" "Description"
    @printf "%-20s %s\n" "------" "-----------"
    @make -pqR : 2>/dev/null \
        | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' \
        | sort \
        | egrep -v -e '^[^[:alnum:]]' -e '^$@$$' \
        | xargs -I _ sh -c 'printf "%-20s " _; make _ -nB | (grep -i "^# Help:" || echo "") | tail -1 | sed "s/^# Help: //g"'

示例输出:

$ make help
Target               Description
------               -----------
app1.bin             A target with variable name, value = app1
app2.bin             A target with variable name, value = app2
bin                  A composite target that relies only on other targets
clean
test                 A normal target without variables

它是如何工作的:

make help目标的顶部部分与mklement0在这里发布的工作完全相同——如何在makefile中获得目标列表?

在获得目标列表之后,它运行make <target> -nB作为每个目标的演练,并解析以@# Help:开头的最后一行,用于目标的描述。或者一个空字符串被打印在一个格式化好的表格中。

正如你所看到的,变量甚至在描述中进行了扩展,这在我的书中是一个巨大的奖励:)。

我最喜欢的答案是Chris Down在Unix & Linux Stack Exchange上发布的。我将引用。

这是make的bash完成模块获取列表的方式: 使得qp | awk - f ': ' ' / ^ [a-zA-Z0-9] [^ $ # \ / \ t =]*:([^=]|$)/ { 分(1美元,/ /);(我的)打印一个[我]}’ 它输出以换行符分隔的目标列表,不进行分页。

用户Brainstone建议使用sort -u来删除重复的条目:

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

来源:如何列出所有的目标在使?(unix和linux SE)

我用这个:

make -npq .DEFAULT 2> /dev/null | \
      awk -v RS= -F: '$1 ~ /^[^#%]+$/ { print $1 }'

它是bash补全脚本功能的一个非常简化的版本。

这可能会产生很多假阳性,但就我的目的而言,我宁愿有假阳性而不是假阴性。

Bash脚本

这里有一个非常简单的方法在bash中做到这一点——基于@cibercitizen1上面的评论:

grep : Makefile | awk -F: '/^[^.]/ {print $1;}'

参见@Marc更权威的回答。还有2377,它说明了make的Bash完成模块是如何完成的。