make: Phony Targets
1
1 4.6 Phony Targets
1 =================
1
1 A phony target is one that is not really the name of a file; rather it
1 is just a name for a recipe to be executed when you make an explicit
1 request. There are two reasons to use a phony target: to avoid a
1 conflict with a file of the same name, and to improve performance.
1
1 If you write a rule whose recipe will not create the target file, the
1 recipe will be executed every time the target comes up for remaking.
1 Here is an example:
1
1 clean:
1 rm *.o temp
1
1 Because the 'rm' command does not create a file named 'clean', probably
1 no such file will ever exist. Therefore, the 'rm' command will be
1 executed every time you say 'make clean'.
1
1 In this example, the 'clean' target will not work properly if a file
1 named 'clean' is ever created in this directory. Since it has no
1 prerequisites, 'clean' would always be considered up to date and its
1 recipe would not be executed. To avoid this problem you can explicitly
1 declare the target to be phony by making it a prerequisite of the
11 special target '.PHONY' (⇒Special Built-in Target Names Special
Targets.) as follows:
1
1 .PHONY: clean
1 clean:
1 rm *.o temp
1
1 Once this is done, 'make clean' will run the recipe regardless of
1 whether there is a file named 'clean'.
1
1 Phony targets are also useful in conjunction with recursive
1 invocations of 'make' (⇒Recursive Use of 'make' Recursion.). In
1 this situation the makefile will often contain a variable which lists a
1 number of sub-directories to be built. A simplistic way to handle this
1 is to define one rule with a recipe that loops over the sub-directories,
1 like this:
1
1 SUBDIRS = foo bar baz
1
1 subdirs:
1 for dir in $(SUBDIRS); do \
1 $(MAKE) -C $$dir; \
1 done
1
1 There are problems with this method, however. First, any error
1 detected in a sub-make is ignored by this rule, so it will continue to
1 build the rest of the directories even when one fails. This can be
1 overcome by adding shell commands to note the error and exit, but then
1 it will do so even if 'make' is invoked with the '-k' option, which is
1 unfortunate. Second, and perhaps more importantly, you cannot take
11 advantage of 'make''s ability to build targets in parallel (⇒
Parallel Execution Parallel.), since there is only one rule.
1
1 By declaring the sub-directories as '.PHONY' targets (you must do
1 this as the sub-directory obviously always exists; otherwise it won't be
1 built) you can remove these problems:
1
1 SUBDIRS = foo bar baz
1
1 .PHONY: subdirs $(SUBDIRS)
1
1 subdirs: $(SUBDIRS)
1
1 $(SUBDIRS):
1 $(MAKE) -C $@
1
1 foo: baz
1
1 Here we've also declared that the 'foo' sub-directory cannot be built
1 until after the 'baz' sub-directory is complete; this kind of
1 relationship declaration is particularly important when attempting
1 parallel builds.
1
1 The implicit rule search (⇒Implicit Rules) is skipped for
1 '.PHONY' targets. This is why declaring a target as '.PHONY' is good
1 for performance, even if you are not worried about the actual file
1 existing.
1
1 A phony target should not be a prerequisite of a real target file; if
1 it is, its recipe will be run every time 'make' goes to update that
1 file. As long as a phony target is never a prerequisite of a real
1 target, the phony target recipe will be executed only when the phony
11 target is a specified goal (⇒Arguments to Specify the Goals
Goals.).
1
1 Phony targets can have prerequisites. When one directory contains
1 multiple programs, it is most convenient to describe all of the programs
1 in one makefile './Makefile'. Since the target remade by default will
1 be the first one in the makefile, it is common to make this a phony
1 target named 'all' and give it, as prerequisites, all the individual
1 programs. For example:
1
1 all : prog1 prog2 prog3
1 .PHONY : all
1
1 prog1 : prog1.o utils.o
1 cc -o prog1 prog1.o utils.o
1
1 prog2 : prog2.o
1 cc -o prog2 prog2.o
1
1 prog3 : prog3.o sort.o utils.o
1 cc -o prog3 prog3.o sort.o utils.o
1
1 Now you can say just 'make' to remake all three programs, or specify as
1 arguments the ones to remake (as in 'make prog1 prog3'). Phoniness is
1 not inherited: the prerequisites of a phony target are not themselves
1 phony, unless explicitly declared to be so.
1
1 When one phony target is a prerequisite of another, it serves as a
1 subroutine of the other. For example, here 'make cleanall' will delete
1 the object files, the difference files, and the file 'program':
1
1 .PHONY: cleanall cleanobj cleandiff
1
1 cleanall : cleanobj cleandiff
1 rm program
1
1 cleanobj :
1 rm *.o
1
1 cleandiff :
1 rm *.diff
1