2

我有以下生成文件:

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.xtxDIR/%/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.txt,d = DIR/3n = abc.txt.

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

规则#1 和#2 匹配。

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

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

(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 中将文件名作为目标或明确的先决条件提到,那么我们说它应该存在。)

NOT SURE:DIR/3/def.xtx被规则提及DIR/%.xtx:

经过这么长时间的解释,我的观点是我在(5.c)中可能是错误的。

4

1 回答 1

4

手册中,

其先决条件实际存在或被提及的规则始终优先于具有必须通过链接其他隐式规则建立的先决条件的规则。

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

编辑:

如果您可以忍受目录列表:

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

那么你可以使用静态模式规则来做到这一点:

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!)

于 2012-10-23T16:47:35.530 回答