Why is make not deleting intermediate files?

試著忘記壹切 提交于 2020-03-23 07:42:28

问题


I'm having problems with GNU make 3.81 not deleting intermediate files. The issue is similar to GNU make Not Deleting Intermediate Files, but that answer doesn't solve my problem. I've distilled the issue to this test case:

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. command blocks must be tab-indented.

That is, the target once depends on once.dep and twice depends on twice.dep. In addition, another also depends on twice.dep. It is this line that causes twice.dep to never be removed, even if make created it and despite the .INTERMEDIATE line.

The Makefile as posted gives:

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

Uncommenting the twice: twice.dep line:

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

Notice that twice.dep is not rm'd in the second invocation.

From the info pages:

.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.**

I've tried making another: twice.dep a real rule with a command block. I've also tried variations of specifying .INTERMEDIATE as a pattern, a literal filename, and both. I've also tried using .PHONY. make-3.82 NEWS doesn't appear to have any relevant fixes. The behavior I'm witnessing looks more like that described for .SECONDARY targets.

Thanks,

Reece


回答1:


You cannot use a pattern as a prerequisite of the .INTERMEDIATE special target (if you could, it would be documented in the manual; if the manual doesn't say you can, then you can't).

Further, GNU make 3.81 had a bug in it where .INTERMEDIATE wasn't working properly; this bug is fixed in 3.82. If you change your file to use:

.INTERMEDIATE: twice.dep

(edit: original reply said "two.dep")

rather than "%.dep" and you switch to GNU make 3.82, your example will work as you expect.




回答2:


The problem is that the rule

.INTERMEDIATE: %.dep

is not interpreted as a pattern rule (because it lacks a % on the left hand side), and %.dep is not a file.

For example, try this Makefile:

foo: %.bar
    cat $+ > $@ 

Now create a.bar and b.bar and run make foo.



来源:https://stackoverflow.com/questions/8921099/why-is-make-not-deleting-intermediate-files

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!