user5184385
user5184385

Reputation:

Make deletes my target. Why?

From the docs:

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. make reports the deletion to you by printing a rm -f command showing which file it is deleting.

Now, a makefile, like this:

$(shell rm -rf x D)
$(shell mkdir D)
$(shell touch D/x)

VPATH = D

all: x ;

x:: phony
    @echo '$@'

.INTERMEDIATE: D/x

.PHONY: phony

Running:

$ make
D/x
rm D/x

$ ls D/x
ls: cannot access D/x: No such file or directory

Now, given the above quote, that Make removes only an "intermediate file which did not exist before", we have here a clear case, where:

  1. The target did exist before running Make.
  2. Make did not create the target.

Still, Make feels that it is appropriate to delete this file. A thing that it was not asked to do. So why does it?

Compare it to the following simple makefile:

$(shell rm -rf x)
$(shell touch x)

x ::
    @echo '$@'

.INTERMEDIATE: x

Running:

$ make
x

$ ls x
x

Simple as that! Make did not remove a file that:

  1. It did not create!
  2. Existed, before running Make

Because, the all point of intermediate files removal is, to quote the documentation above:

Therefore, an intermediate file which did not exist before make also does not exist after make.

Nothing else!

So, how come in the first example, does Make go-around and deletes pre-existing files?

Upvotes: 2

Views: 44

Answers (1)

IKavanagh
IKavanagh

Reputation: 6187

Description of Execution

In your first example whilst D/x did exist before executing make because you have specified phony as a prerequisite make must remake D/x as the target phony does not exist. So make created the intermediate file D/x and according to your quote it

deletes D/x when it is no longer needed.

after having remade all. The path of execution make takes is

  • all does not exist, so we must check x
  • make finds D/x but phony does not exist
  • make remakes phony and now we must remake D/x as it depends on phony which has been updated
  • make remakes the intermediate file D/x (which we must now delete when it is no longer needed)
  • make can now create all, and finally
  • make deletes the intermediate file D/x

Relation to Documentation

The key part of the documentation you have quoted is the first sentence.

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.

This is exactly what happens in your example. make creates D/x and so it must delete D/x later on when it is not needed.

Explanation of Documentation Interpretation

I think you need to be a little careful of your interpretation of the documentation. By stating 'Therefore' they are not saying make will not delete a file that already existed. They are simply saying as a consequence of make updating an intermediate file which did not previously exist it will delete it when it is finished. They are still leaving the possibility that an intermediate file existed before make was executed that it had to update and subsequently deletes.


I think I should stress this a bit more. Given the quote

Therefore, an intermediate file which did not exist before make also does not exist after make.

this does not mean make wont delete files that existed beforehand.

Upvotes: 1

Related Questions