GNU Make is a utility used to manage the building process. To specify its dependency, a target is separated by a colon :
from its prerequisites. Only when one of the prerequisite in the right side has a last modified date later than the target in the left side, will the recipe be executed.
However, people often define a special target clean
with recipe:
.PHONY: clean
This target cleans all the compiled files, by, for example:
clean:
rm -rf ./*.pdf
What does .PHONY
mean here? While clean
isn’t a real object, but an action, if there is a file named clean
on the same directory (certainly not a good name to choose), than Make won’t execute the recipe of clean
, thinking it is up to date. But if we declare it phony, or fake, its recipe no longer depends on actual files.
While this scenario assumes that clean
has no prerequisites, What is it like when it has? Since a phony target doesn’t even have a last modified date, is the recipe still always executed?
Out of curiosity, I conducted some experiments. Consider the makefile as follows. (Recall that a recipe should be indented by a tab.)
all: alice bob
@echo recipe \'all\' executed.
alice:
touch alice
bob:
touch bob
Suppose alice
and bob
are both absent:
$ make
touch alice
touch bob
recipe 'all' executed.
$ make
recipe 'all' executed.
Suppose alice
and bob
are both absent:
$ make
touch alice
touch bob
recipe 'all' executed.
$ touch all
$ make
make: 'all' is up to date.
Now add this line in the end of the makefile:
.PHONY: all
Suppose alice
and bob
are both absent:
$ make
touch alice
touch bob
recipe 'all' executed.
$ touch all
$ make
recipe 'all' executed.
In conclusion, if a target is the prerequisite of the phony target, then its recipe will always be executed. Of course, before executing the recipe, its own prerequisites must exist and up to date as usual. A phony target is therefore considered older than everything, a “file as old as time”.
❧ Chinese version written October 31, 2016; English version translated January 31, 2017; revised July 31, 2021