为什么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),否则会重复编译,降低效率
相关推荐
周杰伦fans5 小时前
C# 中的**享元工厂**模式
开发语言·数据库·c#
u***u6855 小时前
C++在系统中的异常处理
java·开发语言·c++
爱学测试的雨果5 小时前
收藏!软件测试面试题
开发语言·面试·职场和发展
文涛是个小白呀5 小时前
Java集合大调研
java·学习·链表·面试
五点六六六5 小时前
双非同学校招笔记——离开字节入职小📕
前端·面试·程序员
川Princess6 小时前
【面试经验】梅赛德斯奔驰X-Seed AI Systems - Autonomous Driving Agent Efficiency二面
面试·职场和发展
安然无虞6 小时前
JMeter性能测试工具·下
开发语言·测试工具·jmeter
4***R2406 小时前
C++在音视频处理中的库
开发语言·c++·音视频
周一上线6 小时前
EDA 中的 DRC检测——并查集优化mincut规则检测
c++·eda·经验·工艺
embrace996 小时前
【C语言学习】结构体详解
android·c语言·开发语言·数据结构·学习·算法·青少年编程