我使用过一些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:

当前回答

这还远远不够干净,但对我来说还行。

make -p 2&>/dev/null | grep -A 100000 "# Files" | grep -v "^$" | grep -v "^\(\s\|#\|\.\)" | grep -v "Makefile:" | cut -d ":" -f 1

我使用make -p来转储内部数据库,沟渠stderr,使用快速和肮脏的grep -A 100000来保持输出的底部。然后我用几个grep -v来清除输出,最后使用cut来获得冒号之前的内容,即目标。

这对于我的大多数makefile上的助手脚本来说已经足够了。

编辑:添加grep -v Makefile,这是一个内部规则

其他回答

这个对我很有帮助,因为我想看到make目标所需的构建目标(以及它们的依赖关系)。我知道make目标不能以“。”字符开头。我不知道支持什么语言,所以我使用了egrep的括号表达式。

cat Makefile | egrep "^[[:alnum:][:punct:]]{0,}:[[:space:]]{0,}[[:alnum:][:punct:][:space:]]{0,}$"

正如mklement0所指出的,GNU-make中缺少列出所有Makefile目标的功能,他的回答和其他回答提供了实现这一点的方法。

然而,最初的帖子也提到了rake,它的任务开关做的事情与仅仅在rakefile中列出所有任务略有不同。Rake只会给您一个有相关描述的任务列表。没有描述的任务将不会被列出。这使得作者既可以提供定制的帮助描述,也可以省略某些目标的帮助。

如果您想模拟rake的行为,为每个目标提供描述,有一个简单的技术可以做到这一点:在注释中嵌入您想列出的每个目标的描述。

你可以把描述放在目标旁边,或者像我经常做的那样,放在目标上面的PHONY规范旁边,就像这样:

.PHONY: target1 # Target 1 help text
target1: deps
    [... target 1 build commands]

.PHONY: target2 # Target 2 help text
target2:
    [... target 2 build commands]

...                                                                                                         

.PHONY: help # Generate list of targets with descriptions                                                                
help:                                                                                                                    
    @grep '^.PHONY: .* #' Makefile | sed 's/\.PHONY: \(.*\) # \(.*\)/\1 \2/' | expand -t20

它会屈服

$ make help
target1             Target 1 help text
target2             Target 2 help text

...
help                Generate list of targets with descriptions

你也可以在这里找到一个简短的代码示例。

同样,这不能解决在Makefile中列出所有目标的问题。例如,如果您有一个大的Makefile,它可能是生成的或由其他人编写的,并且您想要一种快速的方法来列出它的目标,而不需要深入研究它,那么这将没有帮助。

但是,如果您正在编写Makefile,并且希望以一致的、自记录的方式生成帮助文本,则此技术可能会有用。

这个帮助目标只打印带有##后跟描述的目标。这允许同时记录公共目标和私有目标。使用. default_goal使帮助更容易被发现。

只使用sed, xargs和printf,这是非常常见的。

使用< $(MAKEFILE_LIST)允许将makefile命名为makefile以外的名称,例如makefile .github

您可以在printf中定制输出以满足您的偏好。这个示例的设置是为了匹配OP对rake样式输出的请求

在剪切和粘贴下面的make文件时,不要忘记将4个空格缩进改为制表符。

# vim:ft=make
# Makefile

.DEFAULT_GOAL := help
.PHONY: test help

help:  ## these help instructions
    @sed -rn 's/^([a-zA-Z_-]+):.*?## (.*)$$/"\1" "\2"/p' < $(MAKEFILE_LIST) | xargs printf "make %-20s# %s\n"

lint: ## style, bug and quality checker
    pylint src test

private: # for internal usage only
    @true

test: private ## run pytest with coverage
    pytest --cov test


下面是上面Makefile的输出。注意,私有目标没有得到输出,因为它的注释只有一个#。

$ make
make help                # these help instructions
make lint                # style, bug and quality checker
make test                # run pytest with coverage

这还远远不够干净,但对我来说还行。

make -p 2&>/dev/null | grep -A 100000 "# Files" | grep -v "^$" | grep -v "^\(\s\|#\|\.\)" | grep -v "Makefile:" | cut -d ":" -f 1

我使用make -p来转储内部数据库,沟渠stderr,使用快速和肮脏的grep -A 100000来保持输出的底部。然后我用几个grep -v来清除输出,最后使用cut来获得冒号之前的内容,即目标。

这对于我的大多数makefile上的助手脚本来说已经足够了。

编辑:添加grep -v Makefile,这是一个内部规则

这显然在很多情况下都不起作用,但如果你的Makefile是由CMake创建的,你可能可以运行make help。

$ make help
The following are some of the valid targets for this Makefile:
... all (the default if no target is provided)
... clean
... depend
... install
etc