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

GNU Makefile重复生成已有目标问题求助

问题根源

你的Makefile存在两个关键问题,导致每次执行make都会重新构建目标:

1. 错误使用$?自动变量

$?代表所有比目标文件更新的依赖文件。当foo.o已经存在且foo.cpp没有被修改时,$?是空值,此时编译命令会变成:

g++ -std=c++14 -Wall -Wextra -pedantic -O0 -c

这个命令缺少源文件参数,会触发编译错误,Make会判定目标构建失败,因此每次运行make都会重新尝试构建。

即使依赖文件有更新,$?在多依赖场景下也容易出问题,对于单依赖的目标文件规则,更适合用$<(代表第一个依赖文件),它总能准确获取到对应的源文件。

2. 未明确指定输出目标文件

虽然-c参数会让g++默认生成与源文件同名的.o文件,但如果编译命令中没有明确用-o $@指定输出为目标文件($@代表当前规则的目标),一旦出现路径或参数异常,可能导致生成的文件并非预期的目标文件,Make会因为找不到正确的目标文件而重复构建。

修正后的Makefile
# Compiler: g++ for C++ source files
CC = g++

# Compiler flags:
CFLAGS = -std=c++14 -Wall -Wextra -pedantic -O0 -c

foo.o: foo.cpp
    $(CC) $(CFLAGS) -o $@ $<

bar.o: bar.cpp
    $(CC) $(CFLAGS) -o $@ $<

foobar: foo.o bar.o
    $(CC) -o $@ $^
关键修正点说明
  • 用$<替代$?:确保编译命令始终能获取到对应的源文件,避免空参数错误。
  • 添加-o $@:明确指定输出为当前规则的目标文件,保证生成的文件与Make跟踪的目标一致。
  • 最终链接规则用$^替代$?:$^代表所有依赖文件(这里是foo.o bar.o),而$?只会包含比foobar更新的依赖,用$^更可靠。

这样修改后,Make会正常根据文件时间戳判断是否需要重新构建,只有当源文件比目标文件新时,才会执行编译或链接操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 15:25:41