In terms of Make, a phony target is simply a target that is always out-of-date, so whenever you ask make <phony_target> , it will run, independent from the state of the file system.
$@ is the name of the target being generated, and $< the first prerequisite (usually a source file). You can find a list of all these special variables in the GNU Make manual.
When you type make or make [target] , the Make will look through your current directory for a Makefile. This file must be called makefile or Makefile . Make will then look for the corresponding target in the makefile. If you don't provide a target, Make will just run the first target it finds.
A simple makefile consists of "rules" with the following shape: target ... : dependencies ... command ... ... A target is usually the name of a file that is generated by a program; examples of targets are executable or object files.
If really all targets are PHONY, this is a bit pointless. make
is meant for "do what is necessary to update my output", and if the answer to what is necessary? is always the same, simple scripts would do the same job with less overhead.
That being said, I could imagine a situation where all targets intended to be given at the commandline should be PHONY -- Let's assume you want to build some documents like this:
all: doc1.pdf doc2.pdf doc3.pdf doc4.pdf doc5.pdf
manuals: doc3.pdf doc4.pdf
faqs: doc1.pdf
designdocs: doc2.pdf
apidocs: doc5.pdf
developerdocs: doc2.pdf doc5.pdf
userdocs: doc1.pdf doc3.pdf doc4.pdf
%.pdf: %.md
$(somedocgenerator) -o $@ $<
Then you could do the following:
.PHONY: all $(MAKECMDGOALS)
This would dynamically make any target given at the command line PHONY. Note you have to include your default target here as this could be invoked without giving it explicitly, by simply typing make
.
I would not recommend this approach because it has two drawbacks:
make
.make
a specific output file like here make doc3.pdf
.So, better go with the approach to have one line declaring all the PHONY targets. If your Makefile
is really huge, you could split it in several files and use include
-- and have one .PHONY:
line in each file.
One way to do it:
.PHONY: $(shell sed -n -e '/^$$/ { n ; /^[^ .\#][^ ]*:/ { s/:.*$$// ; p ; } ; }' $(MAKEFILE_LIST))
Works perfectly even for targets mentioned as dependencies.
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