有三种类型的文件。为方便起见,我们称它们为type1(* .1文件),type2(* .2文件)和type3(* .3文件)。 Type2是通过运行某个命令从type1生成的; type3是通过运行某个其他命令从type2生成的。
Type2文件会老化并变为无效,因此会不时删除。
我有以下规则:
%.2 : %.1
cmd1 $< -o $@
%.3 : %.2
cmd2 $< > $@
现在如果xyz.1和xyz.3存在(xyz.1 不比 xyz.3更新),并且xyz.2已被删除,则运行make xyz.3
只是说一切都是最新的,没有什么需要做的。
如果我touch xyz.1
然后运行make
,一切都按预期工作。
我需要 make xyz.3
首先创建type2文件,然后重新创建type3文件。有没有办法做到这一点?
版本:
更新1:更清楚地了解了正在使用的模式规则(感谢指出这一点,@路易斯),并且每种类型都存在多个文件。
答案 0 :(得分:2)
问题是由于使用了模式:
all: foo.3
%.2: %.1
touch $@
%.3: %.2
touch $@
在这种情况下,make foo.3; rm foo.2; make foo.3
将不导致重新生成foo.2
和foo.3
。事实上,Makefile
以上的make
会在创建foo.2
之后删除foo.3
,因为foo.2
是一个中间目标,那就是make
与中间目标有关。 (见here。)
解决方案很简单,将foo.2
列为明确目标:
all: foo.3
foo.2: %.2: %.1
touch $@
%.3: %.2
touch $@
通过明确列出foo.2
,它不再被视为中间人。上面使用的语法记录为here。据推测,规则适用的文件不止一个,因此更通用的解决方案是:
# Get all files that end in `.1` from the filesystem.
type1_files:=$(wildcard *.1)
# For each file that ends in `.1` we want a corresponding file that ends in `.3`.
type3_files:=$(type1_files:%.1=%.3)
all: $(type3_files)
# For each file that ends in `.1` we want a corresponding file that ends in `.2`.
type2_files:=$(type1_files:%.1=%.2)
# All files that end in `.2` are explicit targets to which this rule applies.
$(type2_files): %.2: %.1
touch $@
%.3: %.2
touch $@
答案 1 :(得分:0)
以下按预期工作:
type2 : type1
@echo building $@ from $<
touch $@
type3 : type2
@echo building $@ from $<
touch $@
结果:
$ touch type1
$ make type3
building type2 from type1
touch type2
building type3 from type2
touch type3
$ rm type2
$ make type3
building type2 from type1
touch type2
building type3 from type2
touch type3
除非你告诉它,否则不应将type2
视为中间人,因此你的例子不会出现问题。尝试制作一个测试用例。