Sorting 在Make中对模式规则进行优先级排序
我有(大致)这个Makefile:Sorting 在Make中对模式规则进行优先级排序,sorting,makefile,Sorting,Makefile,我有(大致)这个Makefile: .PHONY: all .SUFFIXES: OUT = /www/web all: $(OUT)/index.html # rule 1 %.html: %.in build_html $< $@ # rule 2 $(OUT)/%: % cp $< $@ 。假冒:全部 .后缀: OUT=/www/web 全部:$(输出)/index.html #规则1 %.html:%.in 生成html$
.PHONY: all
.SUFFIXES:
OUT = /www/web
all: $(OUT)/index.html
# rule 1
%.html: %.in
build_html $< $@
# rule 2
$(OUT)/%: %
cp $< $@
。假冒:全部
.后缀:
OUT=/www/web
全部:$(输出)/index.html
#规则1
%.html:%.in
生成html$<$@
#规则2
$(输出)/%:%
cp$<$@
此生成文件有一个问题,因为有两种不同的方法来生成$(OUT)/index.html
:
/index.html
(规则1),然后将其复制到$(OUT)
(规则2)/index.in
复制到$(OUT)
(规则2),然后构建$(OUT)/index.html
(规则1)make
始终选择选项1。我如何表明这两个模式规则之间存在优先顺序
(我可以想出一些简单的方法来解决这个问题,但是我想要一个尽可能通用的解决方案——例如,将规则2的模式更改为$(OUT)/%.html:%.html将解决此问题,但失去了一般性,因为如果以后要以相同的方式处理其他类型的文件,我需要重复自己的操作。)A来自GNU Makefile手册:
可能有多个模式规则将满足这些标准。在这种情况下,make将选择具有最短干的规则(即最具体匹配的模式)。如果多个模式规则具有最短的词干,make将选择makefile中找到的第一个
因此,您可以尝试创建规则,以确保较短的茎优先。或者,您可以使用来限制复制内容的范围,例如:
%.html: %.in
build_html $@ $<
$(expected_out) : (OBJS)/% : %
cp $@ $<
在makefile中的某个地方,因为make更喜欢“最短路径”而不是构建对象,在这种情况下,这只是一个模式规则。虽然@John的答案最适合我的用例(我确切地知道哪些文件属于$(OUT)
),但还有另一种解决方案:将所需的中间文件标记为“珍贵”
这还将指示Make不要删除index.html
,否则它会为您删除
这要感谢你的帮助。生成依赖项存在或应该存在的偏好规则,如果文件具有显式规则或是其他规则的依赖项,则生成“应该存在”的文件。即使它是特殊目标(如.SECONDARY
、.INTERMEDIATE
或.PRECIOUS
)的依赖项,这也适用。有关更多信息,请参见。它应该始终喜欢规则1的原样。。。Makefile将选择具有最短词干的规则,在规则1中,词干将是index
,而规则2中,词干将是index.html
。。。(我假设gnu在这里制造)。你看到了不同的东西吗?(对不起,前面的评论应该提到index.in
而不是index.html
,但是index.in
仍然比index
长)。我观察到了不良行为(选项2)。我正在使用GNU Make 3.81。我认为您误解了“最短茎”启发式如何影响构建顺序:它将强制执行不良行为,而不是良好行为!顶级目标是$(OUT)/index.html
,规则1最匹配(最短茎)。规则1说我们需要$(OUT)/index.in
,只有规则2与之匹配。不,茎是与%
匹配的部分。如果目标是/www/web/index.html
,则它将%.html
与%
匹配为/www/web/index
,并将$(OUT)/%
与%
匹配为索引.html
。所以规则#2是较短的词干。如果你想让这个makefile在=3.82时表现相同,你需要先放置规则#2,然后它对所有版本都一样有效。静态模式规则似乎在这里非常有用。我认为你延长阀杆长度的方法是错误的:阀杆只是与%
匹配的部分,使每个案例的长度相同。好的,删除hack。我只是尝试了一下,然后让make选择最短的茎作为第一条要运行的规则,而不是要运行的规则链上最长的茎。
$(OUT)/index.html : index.html
.PRECIOUS: index.html