我(大致)这个Makefile:
.PHONY: all
.SUFFIXES:
OUT = /www/web
all: $(OUT)/index.html
# rule 1
%.html: %.in
build_html $< $@
# rule 2
$(OUT)/%: %
cp $< $@
这个Makefile有一个问题,因为有两种不同的方法来构建$(OUT)/index.html
:
./index.html
(规则1),然后将其复制到$(OUT)
(规则2)。./index.in
复制到$(OUT)
(规则2),然后构建$(OUT)/index.html
(规则1)。我希望make
总是更喜欢选项1.如何指出这两种模式规则之间存在首选顺序?
(我可以想到一些hacky方法来完成这个特定情况,但我想要一个尽可能通用的解决方案 - 例如,将规则2的模式更改为$(OUT)/%.html: %.html
将修复问题,但失去了普遍性,因为如果我想以后以同样的方式处理其他类型的文件,我需要重复自己。)
答案 0 :(得分:1)
GNU Makefile手册中的quote:
多个模式规则可能符合这些标准。在这种情况下,make将选择具有最短词干的规则(即,最具体匹配的模式)。如果多个模式规则具有最短的词干,则make将选择在makefile中找到的第一个。
因此,您可以尝试创建规则,以确保较短的词干优先。或者,您可以使用static pattern rules来限制复制内容的范围,如下所示:
%.html: %.in
build_html $@ $<
$(expected_out) : (OBJS)/% : %
cp $@ $<
然后根据您的需要预填充$(expected_out)
。最后,您可以添加:
$(OUT)/index.html : index.html
在makefile中的某个地方,因为make更喜欢构建对象的“最短路径”,在这种情况下,这只是一个模式规则。
答案 1 :(得分:1)
虽然@ John的答案最适合我的用例(我确切知道$(OUT)
中的文件属于哪个),但还有另一种解决方案:将所需的中间文件标记为“珍贵”。
.PRECIOUS: index.html
这也将指示Make不要删除index.html
,否则它会为你做。
这要归功于Make's algorithm for choosing implicit rules。制定依赖存在或应该存在的规则,如果文件具有明确规则或者是另一规则的依赖关系,则应该存在“应该存在”的文件。即使它是.SECONDARY
,.INTERMEDIATE
或.PRECIOUS
等特殊目标的依赖项,这也适用。有关详情,请参阅manual section on "Chains of Implicit Rules"。