.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"?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With