我有一个makefile,其规则可产生多个输出。要变通解决此规则的问题,该问题通常在并行运行时多次运行,因此我使用了一个虚拟的“时间戳文件”。我也有一个规则,该规则取决于此“多输出”规则的输出之一。
当所有这些都从干净状态运行时,一切正常。但是,如果更新了多输出规则的源,则不会运行其他规则,直到再次运行Make。
我已经查看了调试输出,但是并没有取得太大进展。似乎Make可能正在缓存多输出文件先前版本的旧时间戳?
希望以下内容能充分说明问题。
$ cat Makefile
all: data.txt
multioutput.stamp: sourcefile.txt
touch multioutput1.txt
touch multioutput2.txt
touch $@
FILES=multioutput1.txt multioutput2.txt
$(FILES): multioutput.stamp
data.txt: multioutput1.txt
touch data.txt
$ touch sourcefile.txt
$ make
touch multioutput1.txt
touch multioutput2.txt
touch multioutput.stamp
touch data.txt
$ touch sourcefile.txt # update
$ make # data.txt is not updated!!
touch multioutput1.txt
touch multioutput2.txt
touch multioutput.stamp
$ make # except when it's run again??
touch data.txt
我在这里做错了什么,我应该怎么做?
您对make撒谎。不要那样做。
一旦您运行了规则的配方,make会检查该配方是否实际更新了文件。如果尚未更改,则不必重新创建将文件作为依赖项列出的任何目标。
这里您没有给出multioutput1.txt
的任何配方,仅给出了依赖项:
multioutput1.txt: multioutput.stamp
Make知道无法更新multioutput1.txt
。
Force make通过提供multioutput1.txt
的显式配方来检查依赖性。即使是一个空的人也会这样做:
${FILES}: multioutput.stamp ;
[是,这就是;
的含义-配方的第一行在同一行之后。
说“此配方创建两个文件”的唯一方法是使用模式规则。则不需要multioutput.stamp
。
.PHONY: all
all: data.txt
%1.txt %2.txt:
touch $*1.txt
touch $*2.txt
data.txt: multioutput1.txt multioutput2.txt
touch data.txt
配方中的$*
会扩展为依赖项行中匹配的%
。
为什么要使data.txt
依赖于两个multioutput文件?在这里,我认为如果缺少multioutput1
或multioutput2
中的任何一个,我们可能应该运行配方来创建两者。YMMV。
YMMV,但我不喜欢模式规则。他们对我来说太武断了。
我们注意到multioutput1.txt
和multioutput2.txt
中的一个总是比另一个年轻。假设使用现代文件系统,它们将永远不会具有相同的时间戳。
.PHONY: all
all: data.txt
multioutput2.txt: start.stamp
touch $@
touch multioutput2.txt
multioutput1.txt: multioutput2.txt ;
data.txt: multioutput1.txt
touch data.txt