Why .PHONY:target and not target:.PHONY?
I still don't understand why "phony" rules in Makefiles have ".PHONY" as their target. It would be much more logical as a prerequisite.
Do I have to elaborate on this? If A
depends on B
and B
is phony, then A
is phony too. So the dependency graph .PHONY
← B
→ A
is waay surprising compared to .PHONY
→ B
→ A
. (Another argument is that an implementation of make
must handle the .PHONY
target very special.)
While this critique may seem rather theoretical (to pointless) - "since make is so ancient, its syntax is here to stay". But I am not proposing any syntax change, there is an alternative:
With GNU Make (at least), the following Makefile declares a phony target_A
:
target_A: _PHONY
touch target_A
_PHONY:
#noop
Question 1 : This is so simple and clean, surely I am not its first inventor. In fact, given this alternative, why did make
ever need the special syntax?
It seems to me that this would also quite nicely solve questions about wildcards in phony targets, and could even shed some light on .PHONY's meaning when beginners doubt.
Question 2 : Can you think of any circumstance where this approach is inferior? (Is invoking make .PHONY
of any use?)
(I should mention that while I have invoked other make
s, GNU Make is the only implementation that I have some experience with - reading and writing Makefiles.)
One big problem with using target_A: .PHONY
is that it makes it much harder to use many of make's built-in variables. Take this common recipe as an example:
%.a: $(OBJ_FILES)
$(LD) $(LFLAGS) -o $@ $^
The $^
variable pulls in everything that's listed as a prerequisite. If .PHONY
was also listed there then it would be passed to the linker on the command-line, which would probably not result in anything good happening. Using meta-targets like .PHONY
as prerequisites makes these built-in variables significantly less useful, as they require a lot of extra processing like $(filter-out .PHONY,$^)
every time they are used. Inverting the relationship and instead making .PHONY
the target is a bit awkward for the sake of thinking about dependency trees, but it cleans up the rest of the makefile.
上一篇: CAML“NOT IN”查询