This is the documentation of version 1.18. You may want the documentation of the stable version (2.0) or of the well tested 2.1 development snapshot or our homepage.

Phony targets

Often it is convenient to put commands into the makefile that don't actually build a file, but are somehow logically associated with the build process. For example, a very common procedure in makefiles is something like this:


install: our_program
	install -m 0755 our_program $(prefix)/bin
	install -m 0644 *.png $(prefix)/share/our_program/icons

.PHONY: install

When someone types makepp install, then makepp first builds our_program, then runs the commands associated with the install target. The install command simply copies its arguments to the specified directory, and sets the file's protection to the indicated value. So it copies our_program into /usr/local/bin, and some associated data files into /usr/local/share/our_program/icons. But this doesn't create a file called install in the current directory.

The install target here is called a phony target because makepp treats it as if it were a real file, but it is not actually a file, it's just a trick for forcing makepp to build its dependencies and then run some commands.

That's what the line

.PHONY: install

is for. It tells makepp that it really shouldn't expect the file ./install to exist after the commands have executed. If you forget the phony declaration, then makepp will expect the file install to exist after executing the commands, and it will complain loudly if it does not.

You can also write the phony declaration like this:

$(phony install): our_program

and then omit the .PHONY: install line. This means that you can declare the target as phony on the same line as you define it, which may make your makefiles more readable.

Phony targets are extremely common in makefiles. In almost all makefiles, the first target is the phony target all, like this:

$(phony all): program1 program2 program3

If no target is specified on the command line, makepp attempts to build the first target in the file. If your makefile makes more than just one program, you most likely want to build all of the programs by default. In this example, if the programmer just types makepp without any arguments, makepp attempts to build all, which forces it to build all three programs from this directory.

Here is a sample makefile fragment that illustrates some commonly used phony targets:

PROGRAMS	:= combobulator discombobulator

$(phony all): $(PROGRAMS)	# All is the first target, so it's the default.

combobulator: $(COMBOBULATOR_OBJS)
	$(CXX) $(inputs) -o $(output)

discombobulator: $(DISCOMBOBULATOR_OBJS)
	$(CXX) $(inputs) -o $(output)

# This target makes sure everything is compiled, and then puts the
# programs into a place where everyone can access them.  We make the
# directories if they don't exist yet.
prefix	:= /usr/local

$(phony install): all
	test -d $(prefix) || mkdir $(prefix)
	test -d $(prefix)/bin || mkdir $(prefix)/bin
	for prog in $(PROGRAMS); do \
	  install -m 0755 $$prog $(prefix)/bin; \
	test -d $(prefix)/share || mkdir $(prefix)/share
	test -d $(prefix)/share/combobulate || mkdir -p $(prefix)/share/combobulate
	for icon in *.xbm; do \
	  install -m 0644 $$icon $(prefix)/share/combobulate; \
# Note the use of the double dollar sign to pass a single dollar sign to
# the shell.  Note also the backslashes at the end of a line to indicate
# that a shell command continues to the next line.

# This target gets rid of all the junk that gets built during compiles.
# (Note that this could be done more thoroughly with the
# only-targets function.)
$(phony clean):
	rm -f $(PROGRAMS) *.o

# This target makes a source distribution for shipping out to someone.
VERSION := 3.14

$(phony distribution):
	rm -rf combobulate-$(VERSION)	# Get rid of previous junk, if any.
	mkdir combobulate-$(VERSION)
	cp *.c *.h Makefile README INSTALL combobulate-$(VERSION)
	tar cf - combobulate-$(VERSION) | gzip -9c > combobulate-$(VERSION).tar.gz
	rm -rf combobulate-$(VERSION)

# This target runs regression tests to make sure the program(s) are
# doing what they are supposed to do.
$(phony test): $(PROGRAMS)
	noecho for testfile in *.test; do \
	   ./combobulate $$testfile | ./discombobulate - > junk_output; \
	  if cmp -s junk_output $$testfile; then \
	    echo passed $$testfile; \
	  else \
	    echo failed $$testfile; \
	  fi; \
# If "noecho" is the first word of the action, the action itself is not
# printed before it is executed.  In this case, printing the action
# would merely clutter up the screen so it is very common to suppress
# printing for such long commands.

Tutorial index | Next (multiple directories) | Previous (pattern rules)
Last modified: Tue Dec 26 19:35:54 PST 2000