【发布时间】:2012-10-13 15:03:02
【问题描述】:
我有以下生成文件:
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/%/abc.txt 时生成DIR/%/def.xtx;否则只生成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/3 和n = 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) 中可能是错误的。
【问题讨论】:
-
我可能错了,但我认为
%永远不会匹配带有/的东西。因此,假设以上是您的全部Makefile,您没有任何匹配DIR/3/def.txt的规则,make应该抱怨“不知道如何构建 DIR/3/def.txt”或类似的东西。 -
它 [%] 确实与
/匹配;否则DIR/0/a.txt、DIR/1/b.txt和DIR/2/c不会被触及;但他们确实如此。 -
学到了一些新东西......它似乎确实有效。那么,也许
DIR/3/def.xtx没有被创建,因为第三条规则缺少mkdir部分?由于它是DIR/3/abc.txt的先决条件,因此需要在目录存在之前先构建它,因此规则 1 中的mkdir在尝试运行规则 3 之前不会发生。 -
是的,这是一个错误,但是 make 不会查看配方来查找它必须执行的配方。如果它起作用,触摸至少会抱怨该目录不存在。