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

GNU Makefile依赖已构建但目标需重执行才编译的问题排查

Make构建依赖生成后不执行目标规则的问题分析

问题现象

  • 首次执行make时会报错file not found: src/cross-tile.o,但再次执行make即可完成完整构建
  • 在src目录执行make TARGET_CC=cc ../src/cross-tile.o,首次执行仅会生成依赖文件tile.c(通过运行tilemap工具生成),不会编译生成cross-tile.o;第二次执行该命令则会成功生成目标文件

复现步骤

  • 克隆仓库后执行sh sys/android/setup.sh(仅完成Makefile的复制操作)
  • 进入src目录执行make TARGET_CC=cc ../src/cross-tile.o,观察首次执行的输出结果
  • 再次执行上述命令,确认cross-tile.o是否生成

关键配置与规则

项目中TARGETPFX变量设置为../src/cross-,最初使用的是以下隐式规则组合:

# 仅声明目标依赖,未指定编译命令
$(TARGETPFX)tile.o: ../src/tile.c

# 通用的.c文件编译为.o文件的隐式规则
%.o: %.c
    $(TARGET_CC) -c -o $@ $<

将其修改为显式规则后,问题得到解决:

$(TARGETPFX)tile.o: ../src/tile.c
    $(TARGET_CC) -c -o $(TARGETPFX)tile.o ../src/tile.c

原因分析

问题的核心在于Make的隐式规则匹配逻辑和仅依赖声明规则的行为:

  1. 原配置中的$(TARGETPFX)tile.o: ../src/tile.c只是一个依赖声明——它仅告知Make../src/cross-tile.o依赖于../src/tile.c,但没有提供生成目标文件的具体编译命令。
  2. 首次执行时,Make检测到../src/tile.c不存在,会优先执行生成该依赖的规则(通过项目中的tilemap工具生成tile.c)。
  3. 当tile.c生成完成后,Make需要寻找能编译生成../src/cross-tile.o的规则,但默认的%.o: %.c隐式规则有严格的文件名匹配要求:目标文件的主名称(如cross-tile)必须与依赖的.c文件主名称(如tile)完全一致。也就是说,该隐式规则只会尝试寻找../src/cross-tile.c来编译生成目标,但实际存在的是../src/tile.c,因此规则完全不匹配,Make找不到可执行的编译命令。
  4. 首次执行时,Make在完成依赖生成后不会重新触发规则扫描与匹配逻辑,因此直接终止流程,cross-tile.o未被生成。而修改为显式规则后,我们直接指定了编译命令,强制使用../src/tile.c来编译生成../src/cross-tile.o,完全绕过了隐式规则的文件名匹配限制,因此无论首次还是后续执行,都能正常生成目标文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.08 00:15:54