考虑以下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
$
我相信这会引发一系列隐含的规则:
这正如我所期望的那样正常。
现在假设我稍微修改了一下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”内置隐式规则也没有例外。或者我错过了什么?
答案 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
如果传递多个目标,则会崩溃。