Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does make not consider a target without recipe out of date when updated by a PHONY dependency?

.PHONY: b
c: a
    @touch c
    @echo "Changed"
a: b
b:
    @date +%s > a

Running make with the sample make file causes "Changed" to be printed the 1st time it is run; but "Changed" is only printed then on the 3rd, 5th, etc execution. This is because make doesn't seem to recognize that executing the recipe for target "b" updates a.

Changing the rule with "a" as the target into an empty recipe causes "Changed" to be printed for each time make is run (as you would expect - where phony targets are always considered "out of date"). E.g.

a: b ;

Make should skip the implicit rule search for PHONY targets, but "a" is not PHONY. If no implicit rule is found for "a", is make correct to not consider that "a" may have been changed by its PHONY dependency "b"?

like image 696
CodeButcher Avatar asked Nov 04 '22 14:11

CodeButcher


1 Answers

Make can't analyze the effects of commands, so it is the user's responsibility to organize the rules correctly.

Consider a slightly different case:

d: c b
c: a
    @touch c
    @echo "Changed"
a:
b:
    @date +%s > a

This has the same behavior as your example; there's no way Make could be expected to know that c "really" depends on b. The author of the makefile is at fault.

Now the way it should be written:

c: a
        @touch c
        @echo "Changed"

.PHONY: a
a:
        @date +%s > a

The a rule modifies the file a (and PHONY is there just to force the a rule to run). This is the way to tell make that the @date ... command modifies a. This makefile works correctly.

Your example is midway between these two. If a rule modifies a file which is the target of another rule, the makefile is badly organized, and Make is not at fault. Yes, Make could assume that a target that depends on a PHONY rule may have been updated when that rule is run, but it could just as well assume that any target may have been updated when any rule is run. And if Make were that paranoid, it wouldn't be very efficient.

like image 137
Beta Avatar answered Nov 08 '22 04:11

Beta