为什么Makefile中的clean需要.PHONY

原因一:避免Makefile检查时间戳

前置知识:makefile在依赖文件没有改变时不会执行编译命令

bash 复制代码
#第一次执行,OK
[root@VM-16-14-centos ~]# make
g++  -E main.cc -o main.i
g++  -S main.i -o main.s
g++  -c main.s -o main.o
g++  main.o -o main

#第二次执行,源文件没有被修改,为了效率make不会执行编译
[root@VM-16-14-centos ~]# make
make: `main' is up to date.

当目录中存在名为clean的文件时,若未声明.PHONYmake clean会检查该文件的时间戳。由于clean目标通常没有依赖文件,Make会认为该目标已是最新状态,从而跳过命令执行。

makefile 复制代码
# 未声明.PHONY时,若存在clean文件:
$ touch clean
$ make clean
make: 'clean' is up to date.  # 命令未执行

.PHONY声明后,无论文件是否存在,make clean都会执行其命令。例如:

makefile 复制代码
.PHONY: clean
clean:
    rm -f *.o main

即使存在clean文件,也会强制删除目标文件。

情况 未声明.PHONY 声明.PHONY
目录中存在clean文件 命令被跳过 命令强制执行
clean文件 命令正常执行 命令正常执行

原因二:优化性能(次要)

在Makefile中,.PHONY目标通过跳过隐含规则搜索来提升性能,其原理和优化效果可分为以下四个层面:


场景 未声明.PHONY 声明.PHONY
目标文件已存在 检查时间戳(约0.5ms) 直接执行命令(0ms)
多级依赖链 递归检查所有依赖 仅执行命令不检查依赖
并行编译(make -j) 可能因规则搜索阻塞线程 减少线程竞争

  1. 必须声明为.PHONY的目标
    • cleaninstall等不生成文件的操作
    • 入口目标如all(避免与all文件冲突)
  2. 不应声明的情况
    • 实际需要生成文件的目标(如main.o),否则会重复编译,降低效率
相关推荐
雪碧透心凉_1 分钟前
while 循环与循环嵌套
开发语言·python
乐观勇敢坚强的老彭8 分钟前
信奥C++一维数组笔记
开发语言·c++·笔记
码上有光10 分钟前
异常和智能指针
java·大数据·c++·servlet·异常·智能指针
这就是佬们吗16 分钟前
Python入门⑤-异常处理、文件操作与实战项目
开发语言·数据库·python·算法·pycharm
王维同学22 分钟前
[原创][Windows C++]Explorer Shell 扩展、图标覆盖与 COM 服务器定位
c++·windows·注册表
code_pgf25 分钟前
C++ 工程架构设计规范
c++·机器人
asdzx6728 分钟前
Python PDF 拆分实战指南:单页拆分与按需页码范围拆分
开发语言·python·pdf
C++ 老炮儿的技术栈32 分钟前
基于MFC+原生GDI手动自绘仪表盘控件
c语言·c++·visual studio·控件·工业控制·gdi·自绘
孬甭_38 分钟前
C++ vector
开发语言·c++
小肝一下1 小时前
3. 单链表
c语言·数据结构·c++·算法·leetcode·链表·dijkstra