Makefile中.PHONY的作用是什么

Makefile中.PHONY的作用是什么

技术背景

在Makefile里,默认的目标是“文件目标”,也就是用于从其他文件构建新文件。Make默认其目标是一个文件,这让编写Makefile变得相对容易。不过,有时我们希望Makefile执行的命令并不对应文件系统中的物理文件,像常见的“clean”和“all”目标就是如此。

实现步骤

未使用.PHONY的情况

假设在Makefile里有如下规则:

1
2
clean:
rm -rf *.o

要是当前目录下存在名为clean的文件,当执行make clean时,Make会认为该目标与这个文件关联,只有当文件相对于其依赖项看起来不是最新时,才会执行相应命令。若文件已存在且依赖项未改变,Make就不会执行rm -rf *.o命令。

使用.PHONY的情况

在Makefile中添加.PHONY声明:

1
2
3
.PHONY: clean
clean:
rm -rf *.o

这样,即便存在名为clean的文件,执行make clean时,Make也会忽略该文件,直接执行rm -rf *.o命令。

核心代码

示例1:基本的.PHONY使用

1
2
3
.PHONY: clean
clean:
rm -rf *.o

示例2:多个.PHONY目标

1
2
3
4
5
6
7
8
9
.PHONY: all clean distclean

all : prog1 prog2

clean :
rm -rf *.o

distclean :
rm -rf prog1 prog2

示例3:使用::声明伪目标

1
2
3
4
5
6
7
all :: prog1 prog2

clean ::
rm -rf *.o

distclean ::
rm -rf prog1 prog2

最佳实践

一般而言,Makefile中所有不会生成与目标同名输出文件的目标都应声明为伪目标。常见的伪目标有allinstallcleandistclean等。例如:

1
2
3
4
5
6
7
8
9
10
11
12
.PHONY: all install clean distclean

all: program

install:
cp program /usr/local/bin

clean:
rm -rf *.o program

distclean: clean
rm -f config.h

常见问题

伪目标依赖关系的问题

当一个物理目标依赖于伪目标,而伪目标又依赖于另一个物理目标时,可能会出现意外情况。比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
all: fileall

fileall: file2 filefwd
echo file2 file1 >fileall

file2: file2.src
echo file2.src >file2

file1: file1.src
echo file1.src >file1
echo file1.src >>file1

.PHONY: filefwd
.PHONY: filefwd2

filefwd: filefwd2

filefwd2: file1
@echo "Produced target file1"

prepare:
echo "Some text 1" >> file1.src
echo "Some text 2" >> file2.src

在这个例子中,fileall通过伪目标间接依赖于file1,由于伪目标总是被视为更新过,所以fileall总会被重新构建。若将fileall的依赖从filefwd改为file1,则fileall仅在依赖目标相对于它过期时才会被重新构建。

目标捕获规则的问题

在Makefile中使用目标捕获规则时,伪目标的声明会影响规则的执行。例如:

1
2
3
4
5
6
7
8
9
10
11
superclean: clean andsomethingelse

blah: superclean

clean:
@echo clean

%:
@echo catcher $@

.PHONY: superclean

若未声明superclean为伪目标,执行make superclean时,会触发cleanandsomethingelsecatcher superclean;声明后,make superclean就不会触发catcher superclean


Makefile中.PHONY的作用是什么
https://119291.xyz/posts/2025-05-13.the-purpose-of-dot-phony-in-makefile/
作者
ww
发布于
2025年5月13日
许可协议