为什么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),否则会重复编译,降低效率
相关推荐
R-G-B1 天前
【02】C#入门到精通——C# 变量、输入/输出、类型转换
开发语言·c#·c# 变量·c#输入/输出·c#类型转换
星河队长1 天前
C# 软件加密方法,有使用时间限制,同时要防止拷贝
开发语言·c#
史迪奇_xxx1 天前
10、一个简易 vector:C++ 模板与 STL
java·开发语言·c++
2301_801252221 天前
Java中的反射
java·开发语言
Kiri霧1 天前
Rust开发环境搭建
开发语言·后端·rust
weixin-a153003083161 天前
[数据抓取-1]beautifulsoup
开发语言·python·beautifulsoup
mapbar_front1 天前
面试问题—我的问题问完了,你还有什么想问我的吗?
前端·面试
倔强青铜三1 天前
苦练Python第67天:光速读取任意行,linecache模块解锁文件处理新姿势
人工智能·python·面试
小杨同学yx1 天前
有关maven的一些知识点
java·开发语言
我是华为OD~HR~栗栗呀1 天前
华为od-21届考研-C++面经
java·c语言·c++·python·华为od·华为·面试