我使用过一些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:
这是对上述问题的另一个回答。
在MacOSX上测试,终端只使用cat和awk
cat Makefile | awk '!/SHELL/ && /^[A-z]/ {print $1}' | awk '{print substr($0, 1, length($0)-1)}'
将像下面这样输出make文件:
target1
target2
target3
在Makefile中,它应该是相同的语句,确保使用$$variable而不是$variable来转义变量。
解释
猫吐出里面的东西
| -管道解析输出到下一个awk
awk -运行正则表达式,排除“shell”,只接受“A-z”行,然后打印出$1第一列
Awk—再次从列表中删除最后一个字符“:”
这是一个粗略的输出,你可以用AWK做更多有趣的事情。尽量避免sed,因为它在bsd变体中不一致,即一些在*nix上工作,但在MacOSX等bsd上失败。
More
您应该能够将此(经过修改)添加到make的文件中,添加到默认的bash-completion文件夹/usr/local/etc/bash-completion.d/
意思是当你“使标签标签”..它将基于一行脚本完成目标。
这里有很多可行的解决方案,但正如我喜欢说的,“如果值得做一次,就值得再做一次。”
我确实赞成使用(tab)(tab)的建议,但正如一些人指出的那样,您可能没有补全支持,或者,如果您有许多包含文件,您可能想要一种更简单的方法来知道目标定义在哪里。
我还没有测试下面的子制作…我认为这行不通。我们知道,递归是有害的。
.PHONY: list ls
ls list :
@# search all include files for targets.
@# ... excluding special targets, and output dynamic rule definitions unresolved.
@for inc in $(MAKEFILE_LIST); do \
echo ' =' $$inc '= '; \
grep -Eo '^[^\.#[:blank:]]+.*:.*' $$inc | grep -v ':=' | \
cut -f 1 | sort | sed 's/.*/ &/' | sed -n 's/:.*$$//p' | \
tr $$ \\\ | tr $(open_paren) % | tr $(close_paren) % \
; done
# to get around escaping limitations:
open_paren := \(
close_paren := \)
我喜欢它是因为:
通过包含文件列出目标。
输出原始动态目标定义(用模替换变量分隔符)
在新行上输出每个目标
似乎更清楚了(主观意见)
解释:
MAKEFILE_LIST中的foreach文件
输出文件的名称
包含冒号的Grep行,不缩进,没有注释,也不以句号开头
排除立即赋值表达式(:=)
切、排序、缩进和切规则依赖项(冒号后)
蒙格变量分隔符以防止扩展
样例输出:
= Makefile =
includes
ls list
= util/kiss/snapshots.mk =
rotate-db-snapshots
rotate-file-snapshots
snap-db
snap-files
snapshot
= util/kiss/main.mk =
dirs
install
%MK_DIR_PREFIX%env-config.php
%MK_DIR_PREFIX%../srdb
我最喜欢的答案是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)
要扩展@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)'