我使用了一点 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。
无论如何,我做了一些小技巧来从 makefile 中提取目标,您可以将其包含在 makefile 中。
list: @grep '^[^#[:space:]].*:' Makefile
它将为您提供已定义目标的列表。这只是一个开始——例如,它不会过滤掉依赖项。
> make list list: copy: run: plot: turnin:
如下所示:
sh -c
-f <file>
@
奇怪的是,GNUmake没有 仅 列出 makefile 中定义的目标名称的功能。虽然该-p选项生成包含所有目标的输出,但它会将它们隐藏在许多其他信息中,并且还执行默认目标(可以使用 来抑制-f/dev/null)。
make
-p
-f/dev/null
将以下规则放在 GNU 的 makefile 中make以实现一个名为的目标,该目标list仅按字母顺序列出所有目标名称 - 即:调用为make list:
list
make list
.PHONY: list list: @LC_ALL=C $(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$'
重要提示 :粘贴时, 请确保最后一行缩进了 1 个实际的制表符字符。 (空格 不起作用 )。
请注意,对生成的目标列表进行 排序 是最好的选择,因为 不 排序不会产生有用的排序,因为 不会 保留目标在 makefile 中出现的顺序。 此外,包含多个目标的规则的子目标总是 单独 输出,因此由于排序,通常 不会 彼此相邻出现;例如,如果有其他目标,则以 开头的规则a z:将 没有 目标a并在输出 中彼此相邻z列出。 __
a z:
a
z
规则解释 :
.PHONY: list
PHONY: list
LC_ALL=C
$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null
-Rr
-q
-f $(lastword $(MAKEFILE_LIST))确保与原始调用中相同的 makefile 被定位,无论它是使用-f .... 警告 : 如果您的 makefile 包含include指令,这将中断;为了解决这个问题,在任何指令THIS_FILE := $(lastword $(MAKEFILE_LIST)) 之前 定义变量并使用。include``-f $(THIS_FILE)
-f $(lastword $(MAKEFILE_LIST))
-f ...
include
THIS_FILE := $(lastword $(MAKEFILE_LIST))
include``-f $(THIS_FILE)
:是 故意无效的目标 ,旨在 确保不执行任何命令 ;2>/dev/null抑制生成的错误消息。注意:这仍然依赖于-p打印数据库,GNU make 3.82 就是这种情况。 遗憾的是,GNU make 没有提供 直接打印数据库的选项,而不 执行 默认(或给定)任务;如果您不需要针对特定的 Makefile,您可以按照页面中的建议使用。 __make -p -f/dev/null``man
:
2>/dev/null
make -p -f/dev/null``man
-v RS=
这是一个 awk 习惯用法,它将输入分成连续的非空行块。
/^# File/,/^# Finished Make data base/
匹配包含所有目标的输出中的行范围(从 GNU make 3.82 开始为真) - 通过将解析限制在此范围内,无需处理来自其他输出部分的误报。
if ($$1 !~ "^[#.]")
选择性地忽略块:
#
# Not a target:
.
egrep -v -e '^[^[:alnum:]]' -e '^$@$$'从输出中删除不需要的目标:
egrep -v -e '^[^[:alnum:]]' -e '^$@$$'
'^[^[:alnum:]]'… 不包括 隐藏 目标,按照惯例,隐藏目标是既不以字母也不以数字开头的目标。
'^[^[:alnum:]]'
'^$@$$'
运行make list然后打印所有目标,每个目标都在自己的行上;您可以通过管道xargs创建一个以空格分隔的列表。
xargs