You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何第二次及后续make执行时最后一个.c文件未重新编译?

问题原因分析

核心问题出在将obj目录作为普通依赖,而非仅顺序依赖(order-only prerequisite),结合目录的修改时间特性导致了该现象:

1. 目录修改时间的特性

文件系统中,目录的修改时间(mtime)会在目录内新增、删除文件时被更新,更新为操作发生的时间——而非目录本身的内容(比如目录权限)修改时才更新。

2. 首次编译的时间线

  • 初始状态下obj目录为空,make首先执行创建obj目录的规则。
  • 随后逐个编译a.c到e.c,生成对应的.o文件存入obj目录:每生成一个.o文件,obj目录的mtime就会被更新一次。最终obj目录的mtime等于生成e.o时的时间。
  • 由于e.o是最后生成的文件,它的mtime和obj目录的mtime几乎完全一致(甚至略晚一点,因为写入文件需要消耗少量时间)。

3. 后续编译的判定逻辑

make会检查每个.o文件的依赖是否比目标文件更新:

  • 对于a.o到d.o:它们的mtime都早于obj目录的mtime(obj目录的mtime是最后生成e.o时的时间,远晚于这些早期生成的.o的时间),所以make判定依赖(obj目录)比目标新,会重新编译对应的.c文件;而每次重新编译生成新的.o时,又会再次更新obj目录的mtime。
  • 对于e.o:它的mtime不早于obj目录的mtime,同时src/e.c也没有被修改,make判定所有依赖都没有比e.o新,因此不会重新编译e.c。

解决方法

将obj目录改为仅顺序依赖,即在规则中用| obj替代直接写obj,这样make只会确保obj目录存在,不会检查它的修改时间,既避免不必要的重复编译,也不会出现单个文件不编译的异常。

内容的提问来源于stack exchange,提问作者tahzibi.jafar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 06:22:31