DEV Community

Cover image for What's the meaning of .PHONY in a Makefile?
Alexandru Năstase
Alexandru Năstase

Posted on • Edited on • Originally published at alexandrunastase.com

What's the meaning of .PHONY in a Makefile?

TLDR: What does .PHONY actually do?

.PHONY is used to mark a target as phony. That means a target that doesn't take into consideration for execution any file that matches its name.

Let's say we have a target called clear-cache, which removes the cache of an application

clear-cache:
    rm -rf cache/*
Enter fullscreen mode Exit fullscreen mode

Which results in the following command:

command line result 1

The cache removal cli command will be run fine most of the time, but let's check what happens if we add a file with the same name as the target at the same level as the Makefile

command line result 2

Now when running make clear-cache again we get:

command line result 3

The Makefile says basically that it has the target file already and doesn't need
to execute

This default behavior is not what we expect in this case and we want to override it. This is when the .PHONY directive comes to the rescue. Let's update our example to use it

.PHONY: clear-cache
clear-cache:
    rm -rf cache/*
Enter fullscreen mode Exit fullscreen mode

After marking the target as phony, the command behaves as expected

command line result 4

Pro tip: Another way to mark the targets as phony is to have them all in place list rather than above each of them like:

clear-cache:
    rm -rf cache/*
clear-build:
    rm -rf build/*

.PHONY: clear-cache clear-build
Enter fullscreen mode Exit fullscreen mode

Conclusion

In order to override the default behavior in Makefile and use some targets like command runners you can use .PHONY.

References:

Cross-posted from my blog : What's the meaning of .PHONY in a Makefile

Top comments (4)

Collapse
 
Sloan, the sloth mascot
Comment deleted
Collapse
 
richardrichardson profile image
RichardRichardson

It is really well explained.

Collapse
 
thi3rry profile image
Thierry Poinot

Does the default behavior works with folder of the name of a target ?
E.g. : make build wont run if a build folder already exists ?

Collapse
 
alexandrunastase profile image
Alexandru Năstase

Your assumption is correct. The command will behave the same with a folder or a file of the same name as the target. So you will get this message 'build' is up to date and the command will not be executed, unless you mark the target as phony

Another option could be to try github.com/casey/just which is similar to Make, but has a lot less gotchas. It wasn't so wide-spread before but now you find the package in most distros from what I saw