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