为什么不删除中间文件?

时间:2012-01-19 04:42:20

标签: makefile gnu-make

我遇到GNU make 3.81没有删除中间文件的问题。该问题类似于GNU make Not Deleting Intermediate Files,但该答案并未解决我的问题。我已经将问题提炼到了这个测试用例:

default: 
    @echo no $@ target; exit 1

oncetwice: once twice
    @echo $@: $^

## Uncommenting the following line is sufficient to cause GNU make 3.81 to
## not delete the intermediate 'twice.dep', even if it didn't exist
## previously (i.e., was created by this invocation).
#another: twice.dep

%: %.dep
    @echo $^ >$@

## the following .INTERMEDIATE has no effect re: the twice: twice.dep
## dependency
.INTERMEDIATE: %.dep
%.dep:
    @echo $@ >$@

N.B。命令块必须是制表符缩进的。

也就是说,目标once取决于once.deptwice取决于twice.dep。此外,another还取决于twice.dep。正是这条线导致永远不会删除twice.dep,即使make创建了它,尽管有.INTERMEDIATE行。

发布的Makefile给出:

snafu$ rm -f once* twice*; make oncetwice
oncetwice: once twice
rm once.dep twice.dep

取消注释twice: twice.dep行:

snafu$ rm -f once* twice*; make oncetwice
oncetwice: once twice
rm once.dep

请注意,在第二次调用中,two.dep不是rm' d。

来自信息页面:

.INTERMEDIATE
The targets which .INTERMEDIATE depends on are treated as intermediate files.

[...]

Intermediate files are remade using their rules just like all other
files. But intermediate files are treated differently in two ways.

The first difference [...]

**The second difference is that if make does create b in order to update
something else, it deletes b later on after it is no longer
needed. Therefore, an intermediate file which did not exist before make
also does not exist after make.**

我尝试使用命令块使another: twice.dep成为一个真正的规则。我还尝试过将.INTERMEDIATE指定为模式,文字文件名和两者的变体。我也尝试过使用.PHONY。 make-3.82新闻似乎没有任何相关修复。我目睹的行为看起来更像是.SECONDARY目标。

谢谢,

里斯

2 个答案:

答案 0 :(得分:3)

你不能使用模式作为.INTERMEDIATE特殊目标的先决条件(如果可以的话,它将在手册中记录;如果手册没有说你可以,那么你就不能)。

此外,GNU make 3.81中有一个错误,其中.INTERMEDIATE无法正常工作;这个bug在3.82中修复。如果您更改要使用的文件:

.INTERMEDIATE: twice.dep

(编辑:原始回复说“two.dep”)

而不是“%.dep”并且您切换到GNU make 3.82,您的示例将按预期工作。

答案 1 :(得分:0)

问题在于规则

.INTERMEDIATE: %.dep

不会被解释为模式规则(因为左侧缺少%), 并且%.dep不是文件。

例如,试试这个Makefile:

foo: %.bar
    cat $+ > $@ 

现在创建a.barb.bar并运行make foo