我使用过一些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目标的简单语法,并有一个干净的输出,我选择了以下方法:
help:
@grep -B1 -E "^[a-zA-Z0-9_-]+\:([^\=]|$$)" Makefile \
| grep -v -- -- \
| sed 'N;s/\n/###/' \
| sed -n 's/^#: \(.*\)###\(.*\):.*/\2###\1/p' \
| column -t -s '###'
#: Starts the container stack
up: a b
command
#: Pulls in new container images
pull: c d
another command
make-target-not-shown:
# this does not count as a description, so leaving
# your implementation comments alone, e.g TODOs
also-not-shown:
因此,将上面的文件作为Makefile来处理并运行它会给您带来类似于
> make help
up Starts the container stack
pull Pulls in new container images
命令链的解释:
First, grep all targets and their preceeding line, see https://unix.stackexchange.com/a/320709/223029.
Then, get rid of the group separator, see https://stackoverflow.com/a/2168139/1242922.
Then, we collapse each pair of lines to parse it later, see https://stackoverflow.com/a/9605559/1242922.
Then, we parse for valid lines and remove those which do not match, see https://stackoverflow.com/a/8255627/1242922, and also give the output our desired order: command, then description.
Lastly, we arrange the output like a table.
正如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,并且希望以一致的、自记录的方式生成帮助文本,则此技术可能会有用。
要扩展@jsp给出的答案,甚至可以使用$(eval)函数计算帮助文本中的变量。
下面提议的版本增强了以下属性:
将扫描任何生成文件(甚至包括在内)
是否会在帮助注释中引用扩展活动变量
为真实目标添加文档锚(前缀为# TARGETDOC:)
添加列标头
所以要记录,请使用这种形式:
RANDOM_VARIABLE := this will be expanded in help text
.PHONY: target1 # Target 1 help with $(RANDOM_VARIABLE)
target1: deps
[... target 1 build commands]
# TARGETDOC: $(BUILDDIR)/real-file.txt # real-file.txt help text
$(BUILDDIR)/real-file.txt:
[... $(BUILDDIR)/real-file.txt build commands]
然后,在你的makefile文件的某处:
.PHONY: help # Generate list of targets with descriptions
help:
@# find all help in targets and .PHONY and evaluate the embedded variables
$(eval doc_expanded := $(shell grep -E -h '^(.PHONY:|# TARGETDOC:) .* #' $(MAKEFILE_LIST) | sed -E -n 's/(\.PHONY|# TARGETDOC): (.*) # (.*)/\2 \3\\n/'p | expand -t40))
@echo
@echo ' TARGET HELP' | expand -t40
@echo ' ------ ----' | expand -t40
@echo -e ' $(doc_expanded)'
我最喜欢的答案是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)