19.6. Phony Targets
The makefile in Example 19-4 also illustrates several different ways of using targets. The targets debug, testing, production, clean, and symbols are not names of files to be generated. Nonetheless, the rules clearly define the behavior of a command like make production or make clean symbols debug. Targets that are not the names of files to be generated are called phony targets .
In Example 19-4, the phony target clean has a command script, but no prerequisites. Furthermore, its command script doesn't actually build anything: on the contrary, it deletes files generated by other rules. We can use this target to clear the board before rebuilding the program from scratch. In this way, the phony targets testing and production ensure that the executable is linked from object files made with the desired compiler options by including clean as one of their prerequisites.
You can also think of a phony target as one that is never supposed to be up to date: its command script should be executed whenever the target is called for. This is the case with cleanas long as no file with the name clean happens to appear in the project directory.
Often, however, a phony target's name might really appear as a filename in the project directory. For example, if your project's products are built in subdirectories, such as bin and doc, you might want to use subdirectory names as targets. But you must make sure that make rebuilds the contents of a subdirectory when out of date, even if the subdirectory itself already exists.
For such cases, make lets you declare a target as phony regardless of whether a matching filename exists. The way to do so is to is to add a line like this one to your makefile, making the target a prerequisite of the special built-in target .PHONY:
Or, to use an example with a subdirectory name, suppose we added these lines to the makefile in Example 19-4:
.PHONY: bin bin: circle $(MKDIR) $@ $(CP) $< $@/ $(CHMOD) 600 $@/$<
This rule for the target bin actually does create bin in the project directory. However, because bin is explicitly phony, it is never up to date. make puts an up-to-date copy of circle in the bin subdirectory even if bin is newer than its prerequisite, circle.
You should generally declare all phony targets explicitly, as doing so can also save time. For targets that are declared as phony, make does not bother looking for appropriately named source files that it could use with implicit rules to build a file with the target's name. An old-fashioned, slightly less intuitive way of producing the same effect is to add another rule for the target with no prerequisites and no commands:
bin: circle $(MKDIR) $@ $(CP) $< $@/ $(CHMOD) 600 $@/$< bin:
The .PHONY target is preferable if only because it is so explicit, but you may see the other technique in automatically generated dependency rules, for example.