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

GNU Make:如何执行前置预备操作且不触发目标重复构建?

核心问题原因

你遇到的重复构建问题,根源是被.PHONY标记的directories属于伪目标,make 会默认伪目标每次执行后都已更新,所有依赖它的普通文件目标都会被强制触发重建,这就是 Foo 每次都重复链接的原因。

最优解决方案:使用 Order-Only 依赖

GNU make 专门提供了 Order-Only 依赖用于处理这种「仅当依赖不存在时才执行,依赖存在时不触发目标重建」的场景,依赖项写在竖线|之后即可。

你只需要修改obj/%.o的模式规则,将obj目录设为 Order-Only 依赖即可:

# 其余原有规则保持不变
obj/%.o : %.cpp | obj
    $(COMPILE.cc) $(OUTPUT_OPTION) $<

这种方案的优势:

  • 无论执行make all还是make clean Foo,生成.o文件前都会自动检查obj目录是否存在,不存在则自动创建
  • 不会因为obj目录的时间戳变化触发.o重编译,更不会导致Foo重复链接
  • 不需要额外添加伪目标,也不需要手动执行前置准备步骤

兼容旧版 make 的方案

如果需要兼容不支持 Order-Only 依赖的旧版本 make,可以直接在模式规则中用mkdir -p自动创建目录,不需要手动写目录存在判断逻辑:

# 其余原有规则保持不变
obj/%.o : %.cpp
    @mkdir -p $(@D)
    $(COMPILE.cc) $(OUTPUT_OPTION) $<

其中自动变量$(@D)代表目标文件所在的目录,即使后续你新增了多级子目录的编译目标,这行代码也能通用,前缀@是避免打印mkdir命令的执行日志,保持输出干净。

内容的提问来源于stack exchange,提问作者Joseph Larson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 04:15:04