如何获得makefile中的目标列表? [英] How do you get the list of targets in a makefile?
问题描述
我曾经用过rake(一个Ruby make程序),它可以选择获取所有可用目标的列表,例如
I've used rake a bit (a Ruby make program), and it has an option to get a list of all the available targets, eg
> 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中似乎没有选择这样做.
but there seems to be no option to do this in GNU make.
显然,自2007年以来,几乎已经有了相应的代码- http://www.mail-archive.com/help-make@gnu.org/msg06434.html .
Apparently the code is almost there for it, as of 2007 - http://www.mail-archive.com/help-make@gnu.org/msg06434.html.
无论如何,我几乎没有办法从makefile中提取目标,您可以将其包含在makefile中.
Anyway, I made little hack to extract the targets from a makefile, which you can include in a makefile.
list:
@grep '^[^#[:space:]].*:' Makefile
它将为您提供已定义目标的列表.这只是一个开始-例如,它不会筛选出依赖项.
It will give you a list of the defined targets. It's just a start - it doesn't filter out the dependencies, for instance.
> make list
list:
copy:
run:
plot:
turnin:
推荐答案
- 使用更强大的命令来提取目标名称,从而有望防止出现任何误报(并且还消除了不必要的
sh -c
) - 始终不会将目标文件定位在 current 目录中;遵守用
-f <file>
明确指定的makefile
- 排除隐藏目标-按照惯例,这些目标的名称均不以字母或数字开头
- 使单个伪造目标
- 为命令加上
@
前缀,以防止在执行前被回显
- uses a more robust command to extract the target names, which hopefully prevents any false positives (and also does away with the unnecessary
sh -c
) - does not invariably target the makefile in the current directory; respects makefiles explicitly specified with
-f <file>
- excludes hidden targets - by convention, these are targets whose name starts neither with a letter nor a digit
- makes do with a single phony target
- prefixes the command with
@
to prevent it from being echoed before execution
奇怪的是,GNU make
没有仅列出在makefile中定义的目标名称的功能. -p
选项产生的输出包括所有目标,但是将它们包含在许多其他信息中.
Curiously, GNU make
has no feature for listing just the names of targets defined in a makefile. The -p
option produces output that includes all targets, but buries them in a lot of other information.
在GNU make
的makefile中放置以下规则,以实现名为list
的目标,该目标仅按字母顺序列出所有目标名称-即:以make list
的身份调用:>
Place the following rule in a makefile for GNU make
to implement a target named list
that simply lists all target names in alphabetical order - i.e.: invoke as make list
:
.PHONY: list
list:
@$(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个实际制表符缩进.(空格不是 工作).
Important: On pasting this, make sure that the last line is indented by exactly 1 actual tab char. (spaces do not work).
请注意,排序目标结果列表是最佳选择,因为 not 排序不会产生有用的排序,因为目标出现在其中的顺序生成文件未保存 .
同样,包含多个目标的规则的子目标始终不变地分别输出 ,因此,由于排序,通常 not 会彼此相邻出现;例如,如果有其他目标,则以a z:
开头的规则将 not 的目标a
和z
彼此相邻列出的 .
Note that sorting the resulting list of targets is the best option, since not sorting doesn't produce a helpful ordering in that the order in which the targets appear in the makefile is not preserved.
Also, the sub-targets of a rule comprising multiple targets are invariably output separately and will therefore, due to sorting, usually not appear next to one another; e.g., a rule starting with a z:
will not have targets a
and z
listed next to each other in the output, if there are additional targets.
规则解释:
- .
PHONY: list
- 将目标列表声明为假目标,即一个 not 引用一个文件,因此应无条件调用 ). li>
- .
PHONY: list
- declares target list a phony target, i.e., one not referring to a file, which should therefore have its recipe invoked unconditionally
$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null
- 再次调用
make
以便打印和解析从makefile派生的数据库:-
-p
打印数据库 -
-Rr
禁止包含内置规则和变量 -
-q
仅测试目标的最新状态(不进行任何修改),但是它本身并不能在所有情况下都阻止执行配方命令;因此: -
-f $(lastword $(MAKEFILE_LIST))
确保与原始调用相同的makefile成为目标文件,无论它是通过-f ...
隐式还是显式目标文件.
注意事项 :如果您的makefile包含include
指令,则此操作会中断;要解决此问题,请在任何include
指令之前在变量THIS_FILE := $(lastword $(MAKEFILE_LIST))
之前定义,并改用-f $(THIS_FILE)
. -
:
是一个故意无效的目标,旨在确保不执行任何命令;2>/dev/null
禁止显示结果错误消息.注意:尽管如此,这仍然依赖于-p
打印数据库,从GNU make 3.82开始就是这种情况.可悲的是,GNU make没有提供直接选择来只是打印数据库,而没有也执行默认(或给定)任务.如果不需要定位特定的Makefile,则可以按照man
页中的建议使用make -p -f/dev/null
.
- Invokes
make
again in order to print and parse the database derived from the makefile:-p
prints the database-Rr
suppresses inclusion of built-in rules and variables-q
only tests the up-to-date-status of a target (without remaking anything), but that by itself doesn't prevent execution of recipe commands in all cases; hence:-f $(lastword $(MAKEFILE_LIST))
ensures that the same makefile is targeted as in the original invocation, regardless of whether it was targeted implicitly or explicitly with-f ...
.
Caveat: This will break if your makefile containsinclude
directives; to address this, define variableTHIS_FILE := $(lastword $(MAKEFILE_LIST))
before anyinclude
directives and use-f $(THIS_FILE)
instead.:
is a deliberately invalid target that is meant to ensure that no commands are executed;2>/dev/null
suppresses the resulting error message. Note: This relies on-p
printing the database nonetheless, which is the case as of GNU make 3.82. Sadly, GNU make offers no direct option to just print the database, without also executing the default (or given) task; if you don't need to target a specific Makefile, you may usemake -p -f/dev/null
, as recommended in theman
page.
-v RS=
- 这是一个awk惯用法,它将输入分成连续的非空行块.
- 匹配包含所有目标的输出中的行范围(从GNU make 3.82开始为true)-通过将解析限制为该范围,无需处理来自其他输出节的误报.
- 选择性地忽略块:
-
#
...忽略非目标,其目标块以# Not a target:
开头
-
.
...忽略特殊目标
- Selectively ignores blocks:
#
... ignores non-targets, whose blocks start with# Not a target:
.
... ignores special targets
-
'^[^[:alnum:]]'
...不包括隐藏的目标,按照惯例,这些目标既不是字母也不是数字. -
'^$@$$'
...排除了list
目标本身
'^[^[:alnum:]]'
... excludes hidden targets, which - by convention - are targets that start neither with a letter nor a digit.'^$@$$'
... excludes thelist
target itself
运行
make list
然后打印所有目标,每个目标都在其自己的行上;否则,将显示所有目标.您可以通过管道连接到xargs
来创建以空格分隔的列表.Running
make list
then prints all targets, each on its own line; you can pipe toxargs
to create a space-separated list instead.这篇关于如何获得makefile中的目标列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
-
-