假设我们有以下Makefile:
.PHONY: build
build:
cd .. && make
%.hl.a.json: %.c
touch $@
%.hl.b.json: %.hl.a.json
touch $@
%.x.p.json: %.hl.b.json
touch $@
%.x.hl.a.json: %.x.p.json
touch $@
%.x.hl.b.json: %.x.hl.a.json
touch $@
.PHONY: clean
clean:
$(RM) *.json
我们假设我们有一个名为small.c
的文件,我想构建small.hl.b.json
。但是,运行make small.hl.b.json
(使用GNU Make 3.81)会给我:
$ make small.x.hl.b.json
make: *** No rule to make target `small.x.hl.b.json'. Stop.
但是,Makefile适用于构建生成
的small.x.hl.a.json
$ make small.x.hl.a.json
touch small.hl.a.json
touch small.hl.b.json
touch small.x.p.json
touch small.x.hl.a.json
rm small.x.p.json small.hl.a.json small.hl.b.json
因此,如果我首先运行make small.x.hl.a.json
,然后然后 make small.x.hl.b.json
,那么一切正常。
现在它变得有趣了。如果我执行以下操作:
$ make small.x.hl.a.json
touch small.hl.a.json
touch small.hl.b.json
touch small.x.p.json
touch small.x.hl.a.json
rm small.x.p.json small.hl.a.json small.hl.b.json
$ make clean
rm -f *.json
$ make small.x.hl.b.json
make: *** No rule to make target `small.x.hl.b.json'. Stop.
它不起作用。但如果我这样做, 就会起作用:
$ make small.x.hl.a.json
touch small.hl.a.json
touch small.hl.b.json
touch small.x.p.json
touch small.x.hl.a.json
rm small.x.p.json small.hl.a.json small.hl.b.json
$ make clean small.x.hl.b.json
rm -f *.json
touch small.hl.a.json
touch small.hl.b.json
touch small.x.p.json
touch small.x.hl.a.json
touch small.x.hl.b.json
rm small.x.p.json small.hl.a.json small.hl.b.json
有人能告诉我发生了什么事吗?为什么我不能直接构建small.x.hl.b.json
,而必须首先构建small.x.hl.a.json
和然后 small.x.hl.b.json
?
答案 0 :(得分:0)
我可能错了,如果有人能提供更好的答案,我会删除这个答案,但这对我来说就像GNUMake 3.81中的错误一样:
首先考虑目标small.x.hl.b.json
,找到两个与之匹配的模式规则:
%.hl.b.json: %.hl.a.json # call this rule 2
...
%.x.hl.b.json: %.x.hl.a.json # call this rule 5
...
请注意,这两个规则都具有相同的先决条件,即small.x.hl.a.json
。
看起来Make然后犯了一个错误。 (这是我出去的地方。)它正在寻找一种构建small.x.hl.a.json
的方法,记住它已经使用了规则2和5,但是没有记住它们是并行替代品,而不是顺序步骤。稍后,当Make需要small.hl.b.json
时,唯一要服务的规则是规则2,其中拒绝理由是它不能在链中使用相同的模式规则两次。不要紧,这个调用会使用一个较短的词干,更不用说有问题的链实际上是两个链,其中一个尚未使用规则2,Make认为这是一个死胡同。
这也符合其他实验的结果。 Make可以在没有这种自我碰撞的情况下构建small.x.hl.b.json
,一旦构建了该目标,Make就可以在一个步骤中构建small.x.hl.b.json
,而不会产生麻烦的链。
答案 1 :(得分:0)
我找到了一个教程说:
首先尝试使用短杆的规则,如果存在平局,则会选择首先出现的规则。
所以我尝试交换规则的顺序以便.x。目标首先出现,然后一切正常!