makefile:隐式规则:相同的目标不同的先决条件

时间:2012-10-23 15:56:27

标签: makefile gnu-make

我有以下makefile:

all: DIR/0/a.txt DIR/1/b.txt DIR/2/c.txt DIR/3/abc.txt

DIR/%/abc.txt: DIR/%/def.xtx # rule #1
    mkdir -p $(@D)
    touch $@

DIR/%.txt: # rule #2
    mkdir -p $(@D)
    touch $@

DIR/%.xtx:
    touch $@

每当生成DIR/%/def.xtx时,我想生成DIR/%/abc.txt;否则只生成DIR/%.txt

使用GNU Make 3.81上面的makefile,只生成DIR/3/abc.txt并且不生成DIR/%/def.xtx

遵循GNU make用户手册中的“隐式规则搜索算法”,我们得到:

  

(1)将t拆分为名为d的目录部分,其余部分称为n。例如,如果t是'src / foo.o',则d是'src /',n是'foo.o'。

适用于DIR/3/abc.txtd = DIR/3n = abc.txt

  

(2)列出其目标与t或n匹配的所有模式规则。如果目标模式包含斜杠,则与t匹配;否则,反对n。

规则#1和#2匹配。

  

(3)如果该列表中的任何规则不是匹配任何规则,则从列表中删除所有非终结匹配任何规则。

不确定:列表中没有删除任何规则。

  

(4)从列表中删除所有没有食谱的规则。

没有删除任何规则。

  

(5)对于列表中的每个模式规则:

     

(5.a)找到词干s,它是t或n的非空位部分,与目标模式中的'%'匹配。

对于规则#1,s = 3。 对于规则#2,s = 3/abc

  

(5.b)用s代替'%'计算先决条件名称;如果目标模式不包含斜杠,则将d附加到每个先决条件名称的前面。

对于规则#1,它变为:DIR/3/abc.txt: DIR/3/def.xtx 规则#2没有先决条件。

  

(5.c)测试是否存在所有先决条件或应该存在。 (如果在makefile中提到文件名作为目标或作为显式先决条件,那么我们说它应该存在。)

不确定:规则DIR/3/def.xtx提到DIR/%.xtx:

经过长时间的长篇解释后,我认为(5.c)可能错了。

1 个答案:

答案 0 :(得分:4)

来自the manual

  

一条规则,其先决条件实际存在或始终被提及   优先于具有必须由之前的先决条件的规则   链接其他隐含规则。

您的规则#1需要链接,您的规则#2没有先决条件,因此在尝试构建DIR/3/abc.txt时,Make会在#1上选择#2。

修改

如果您能够拥有目录列表:

DIRS := DIR/0 DIR/1 DIR/2 DIR/3

然后你可以使用static pattern rule

来完成
all: DIR/0/a.txt DIR/1/b.txt DIR/2/c.txt DIR/3/abc.txt

ABC_TXT := $(addsuffix /abc.txt, $(DIRS))

$(ABC_TXT): DIR/%/abc.txt : DIR/%/def.xtx

DIR/%.txt:
    mkdir -p $(@D)
    touch $@

DIR/%.xtx:
    touch $@

(它也避免了.txt规则的重复!)