Make:当二进制是中间目标时,隐式规则链被破坏

时间:2013-11-18 16:40:26

标签: makefile gnu-make

考虑以下Makefile:

%.o.gz: %.o
    gzip $<

如果hello.c存在于同一目录中,我可以使用目标hello.o.gz调用make:

$ make hello.o.gz
cc    -c -o hello.o hello.c
gzip hello.o
$ 

我相信这会引发一系列隐含的规则:

  • 内置隐式规则,将.c编译为.o
  • makefile中给出的隐式规则,用于gzip .o文件

这正如我所期望的那样正常。

现在假设我稍微修改了一下makefile:

%.gz: %
    gzip $<

这里的想法是使用“compile .c to binary”内置隐式规则,然后gzip生成的二进制文件。我希望能够像这样调用make:

$ make hello.gz
make: *** No rule to make target `hello.gz'.  Stop.
$

但它不起作用。

有趣的是,如果我调用make两次,一次构建二进制文件,然后一次gzip,它确实有效,所以这似乎与规则链接有关:

$ make hello
cc     hello.c   -o hello
$ make hello.gz
gzip hello
$ 

为什么我不能将“编译.c到二进制”内置隐式规则放入链中,而我可以将“编译.c到.o”隐式规则放入链中?

我是否可以通过某种方式修改隐式gzip规则以使其正常工作?

我已经阅读了make文档的Chains of Implicit Rules部分,但据我所知,“compile .c to binary”内置隐式规则也没有例外。或者我错过了什么?

2 个答案:

答案 0 :(得分:2)

我相信你正在击中这个behvaior,因为你正在使用匹配任何规则(也就是说,目标是%而没有限制的规则)。处理这些规则有许多特殊情况,因为如果没有这些特殊情况,在隐式规则搜索期间需要检查的规则数量将会大许多个数量级。

有关对匹配任何规则的限制的信息,请参阅http://www.gnu.org/software/make/manual/html_node/Match_002dAnything-Rules.html

答案 1 :(得分:0)

到目前为止,我能提出的最佳解决方法是:

ifneq (,$(wildcard $(MAKECMDGOALS:%.gz=%.c)))
$(MAKECMDGOALS): %.gz: %
    gzip $<
endif

如果传递多个目标,则会崩溃。