我使用过一些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:
要扩展@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)'
这是对上述问题的另一个回答。
在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/
意思是当你“使标签标签”..它将基于一行脚本完成目标。
我个人为我构建的每个Makefile复制粘贴相同的帮助目标。
.SILENT:
.PHONY: help
## This help screen
help:
printf "Available targets\n\n"
awk '/^[a-zA-Z\-\_0-9]+:/ { \
helpMessage = match(lastLine, /^## (.*)/); \
if (helpMessage) { \
helpCommand = substr($$1, 0, index($$1, ":")-1); \
helpMessage = substr(lastLine, RSTART + 3, RLENGTH); \
printf "%-30s %s\n", helpCommand, helpMessage; \
} \
} \
{ lastLine = $$0 }' $(MAKEFILE_LIST)
我也在这个Github要点中保留了它的副本:
https://gist.github.com/Olshansk/689fc2dee28a44397c6e31a0776ede30
专注于描述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.