我有
%.foo
文件位于 $(A)
目录中,并带有附加的 year/month
子结构,例如 $(A)/2014/05/x.foo
等。使用 Makefile,我想将其保留在 ./converter
所在的目录中,我想将目录 %.foo
中的所有 $(A)/*/*/
文件转换为镜像 $(B)/*/*/
结构。额外的复杂性是,不幸的是,converter
将%.foo
文件转换为具有两个扩展名的文件,即%.bar.baz
,并且此行为无法更改。我应该如何正确构建 $(B)
文件对 $(A)
文件的依赖关系?我应该如何写%.bar.baz: %.foo
规则?
这个问题与这个问题类似。 我尝试过
AF := $(shell find $(A) -name \*.foo)
BF := $(patsubst $(A)/%.foo,$(B)/%.bar.baz,$(AF))
all: $(BF)
.PHONY: all
$(B)/%.bar.baz: %.foo
mkdir -p $(@D)
./convert $< $@ || rm $@
但是有了
make
或 gmake
我就明白了
make: *** No rule to make target 'b/2014/05/x.bar.baz', needed by 'all'. Stop.
这个规则是错误的:
$(B)/%.bar.baz: %.foo
mkdir -p $(@D)
./convert $< $@ || rm $@
让我们看看 make 会对你想要构建的目标做什么,
b/2014/05/x.bar.baz
。 Make 将寻找与此匹配的目标模式,它会找到 $(B)/%.bar.baz
(因为 $(B)
扩展为 b
),所以该模式确实是 b/%.bar.baz
。
给定这个模式,词干(与
%
匹配的部分)是什么?将会是2014/05/x
。
鉴于该词干,当先决条件模式为
%.foo
时 make 查找的先决条件是什么?我们更换茎,我们得到 2014/05/x.foo
。
因此 make 查找文件
2014/05/x.foo
,但该文件不存在。存在的文件是 a/2014/05/x.foo
(我假设:您实际上并没有向我们显示 A
或 B
变量的值)。由于先决条件文件不存在,并且 make 无法找到构建它的方法,因此 make 判定此模式规则不匹配。由于此模式不匹配,因此 make 将查找其他一些匹配的模式规则。由于没有其他模式规则匹配,因此 make 告诉您它不知道如何构建此目标b/2014/05/x.bar.baz
。
所以简单的答案是,不要忘记将目录
$(A)
添加到先决条件中:
$(B)/%.bar.baz: $(A)/%.foo
mkdir -p $(@D)
./convert $< $@ || rm $@