user5184385
user5184385

Reputation:

Make keeps building the wrong target with VPATH

From the docs, regarding VPATH:

After processing the prerequisites, the target may or may not need to be rebuilt:

a.     If the target does _not_ need to be rebuilt, the path to the
     file found during directory search is used for any
     prerequisite lists which contain this target.  In short, if
     'make' doesn't need to rebuild the target then you use the
     path found via directory search.


b.     If the target _does_ need to be rebuilt (is out-of-date), the
     pathname found during directory search is _thrown away_, and
     the target is rebuilt using the file name specified in the
     makefile.  In short, if 'make' must rebuild, then the target
     is rebuilt locally, not in the directory found via directory
     search.

Illustrating the above, with the following makefile - which is basically the same situation as section b. above - where the vpath-ized target turns outs to be out-of-date, we write the Makefile, as:

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

VPATH = D

all: phony
    echo '$@'

.SILENT: D/all

.PHONY: phony

Running, I get:

echo 'D/all'
D/all

Now, given that above quote that:

"if the target does need to be rebuilt (is out-of-date), the pathname found during directory search is thrown away, and the target is rebuilt using the file name specified in the makefile"

Why, then does Make build D/all, as evident by the output of the command, and not the original (before it was vpath-ized) target?

Upvotes: 1

Views: 647

Answers (1)

IKavanagh
IKavanagh

Reputation: 6187

Simply make builds D/all because you have specified .SECONDARY: D/all which prevents make from "automatically deleting", i.e. throwing away, the pathname of D/all.

If you remove (or comment out) .SECONDARY: D/all and run make --debug on

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

VPATH = D

all: phony
    echo '$@'

.PHONY: phony

the output should be similar to

Reading makefiles...
Updating goal targets....
File 'phony' does not exist.
Must remake target 'phony'.
Successfully remade target file 'phony'.
Prerequisite 'phony' of target 'all' does not exist.
Must remake target 'all'.
Ignoring VPATH name 'D/all'.
echo 'all'
all
Successfully remade target file 'all'.

Here we can clearly see make now throws away the pathname of D/all and rebuilds all locally as per the documentation you've quoted.


.SECONDARY is documented in Special Targets in the GNU Make Documentation.

Upvotes: 1

Related Questions