为什么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),否则会重复编译,降低效率
相关推荐
AI迅剑9 分钟前
模块二:C++核心能力进阶(5篇)篇二:《多线程编程:C++线程池与原子操作实战》(14万字深度指南)
java·开发语言·c++
代码的余温14 分钟前
Java原子类:CAS与volatile的无锁奥秘
java·开发语言·线程安全
oioihoii17 分钟前
C++中锁与原子操作的区别及取舍策略
java·开发语言·c++
掘金安东尼20 分钟前
🧭 前端周刊第416期(2025年5月26日–6月1日)
前端·javascript·面试
Mikhail_G21 分钟前
Python应用continue关键字初解
大数据·运维·开发语言·python·数据分析
VU-zFaith8701 小时前
C++概率论算法详解:理论基础与实践应用
c++·算法·概率论
wk灬丨1 小时前
Kotlin List 操作全面指南
开发语言·kotlin
小葡萄20251 小时前
黑马程序员C++核心编程笔记--4 类和对象--多态
java·c++·笔记
iCxhust1 小时前
Prj09--8088单板机C语言8253产生1KHz方波(1)
c语言·开发语言·c++·单片机·嵌入式硬件·mcu
源码师傅1 小时前
PHP+mysql 美容美发预约小程序源码 支持DIY装修+完整图文搭建教程
开发语言·mysql·php·预约小程序源码·预约服务系统源码·美容预约小程序源码·美发预约小程序