为什么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),否则会重复编译,降低效率
相关推荐
程序员的世界你不懂14 分钟前
Jmeter的元件使用介绍:(四)前置处理器详解
开发语言·python·jmeter
倔强青铜三17 分钟前
苦练Python第35天:数据结构挑战题,实战演练
人工智能·python·面试
你的电影很有趣18 分钟前
lesson24:Python的logging模块
开发语言·python
刚入坑的新人编程29 分钟前
暑期算法训练.8
数据结构·c++·算法·面试·哈希算法
倔强青铜三32 分钟前
苦练Python第32天:Python百宝箱,collections模块5大杀器
人工智能·python·面试
倔强青铜三32 分钟前
苦练Python第33天:斜杠 / 与星号 * 的魔法——彻底搞懂函数参数顺序
人工智能·python·面试
倔强青铜三33 分钟前
苦练Python第31天:enumerate、zip与元组解包
人工智能·python·面试
TalkU浩克1 小时前
C++中使用Essentia实现STFT/ISTFT
开发语言·c++·音频·istft·stft·essentia
awonw1 小时前
[python][flask]flask静态资源
开发语言·python·flask