Others have already quoted the GNU make manual and given example Makefiles. I'd like to add two situations that benefit from order-only prerequisites.
First, directories as targets. You want to create a file bin/package.jar
, and you want to create bin
if necessary. This Makefile fragment looks good:
bin/package.jar: bin
jar cfm $@ manifest.txt $(CLASSES)
bin:
mkdir $@
But it has a potential flaw. If bin
is ever newer than bin/package.jar
, then make will rebuild bin/package.jar
when it doesn't need to. Yet bin
's modification time changes if any files change inside it! This can happen for unexpected reasons in larger Makefiles. The manual describes this:
In this situation, you want the directory to be created before any
targets are placed into it but, because the timestamps on directories
change whenever a file is added, removed, or renamed, we certainly
don’t want to rebuild all the targets whenever the directory’s
timestamp changes. One way to manage this is with order-only
prerequisites: make the directory an order-only prerequisite on all
the targets:
bin/package.jar: | bin
jar cfm $@ manifest.txt $(CLASSES)
bin:
mkdir $@
Second, checking if a file exists but ignoring its contents. Suppose you want the same Makefile to create manifest.txt
, checking for a Java source file and putting its name inside manifest.txt
. Again, use an order-only prerequisite:
MAINCLASS=Coffee
manifest.txt: | $(MAINCLASS).java
echo "Main-Class: $(MAINCLASS)" > $@
# Other targets may use $(MAINCLASS).java or $(MAINCLASS).class
manifest.txt
requires $(MAINCLASS).java
to exist. But changing the contents of $(MAINCLASS).java
(which changes its modification time, which is what make uses) should not rebuild manifest.txt
.