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

如何让Makefile的my-rule仅在sub-dir变更时重建且等待其完成?

解决Makefile中my-rule重复重建的问题

你的问题根源在于sub-dir被标记为.PHONY目标——Make会把伪目标认定为总是需要重新构建,所以不管子目录实际有没有变更,依赖它的my-rule每次都会被触发执行。要实现"等待sub-dir完成且仅在其变更时重建my-rule",我们需要给子目录的构建状态一个可追踪的实体标记,具体修改如下:

修改后的Makefile

# 定义一个标记文件,用来记录子目录的构建完成时间
SUB_DIR_MARK := .sub-dir-built

all: my-rule

# 让my-rule依赖标记文件,而非直接依赖伪目标
my-rule: $(SUB_DIR_MARK)
	g++ main.cpp -o my-rule

# 子目录构建完成后更新标记文件
$(SUB_DIR_MARK):
	$(MAKE) -C sub-dir
	touch $@

# 伪目标用于手动触发子目录清理/重建
.PHONY: sub-dir clean-sub-dir
sub-dir: $(SUB_DIR_MARK)

clean-sub-dir:
	$(MAKE) -C sub-dir clean
	rm -f $(SUB_DIR_MARK)

关键改动说明

  • 引入标记文件.sub-dir-built:这个文件的修改时间会记录子目录最后一次构建完成的时间,Make可以通过对比它和my-rule的时间戳来决定是否重建my-rule。
  • 调整依赖关系:让my-rule直接依赖标记文件,而非原来的伪目标sub-dir,这样只有当标记文件更新(即子目录确实发生了构建)时,my-rule才会重新编译。
  • 保留伪目标的便利性:保留.PHONY: sub-dir,但让它依赖标记文件,这样你依然可以通过make sub-dir手动触发子目录构建,同时不会影响自动依赖判断。
  • 添加清理规则:新增clean-sub-dir规则,用于清理子目录产物和标记文件,确保下次构建能重新触发完整流程。

验证效果

  • 第一次执行make:会先构建子目录,生成标记文件,再编译my-rule。
  • 子目录无变更时再次执行make:Make发现标记文件比my-rule新(或者两者时间一致),会跳过my-rule的编译。
  • 修改子目录中的文件后执行make:子目录会重新构建,标记文件被更新,my-rule随之重新编译。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:43:17