多任务构建场景下make报错后未终止的问题咨询
问题背景
在Linux系统执行大型并行构建任务(命令:make --jobs=3 -f Makefile),升级至make 4.3后构建失败情况减少,但存在两个核心问题:
- 构建报错后make未立即终止,仍会等待未完成的作业
- 构建服务器脚本中执行该命令时,返回码始终为成功,导致后续问题定位困难
附报错日志:
error 30-May-2023 11:14:14 Fatal error: can't create linux64/BoundaryConditionServer.o: No such file or directory
error 30-May-2023 11:14:14 Assembler messages:
error 30-May-2023 11:14:14 Fatal error: can't create linux64/BcsCollect.o: No such file or directory
build 30-May-2023 11:14:14 g++ -c -W -Wno-sign-compare -Wno-deprecated -Wno-non-virtual-dtor -Wpointer-arith -Wno-switch -std=c17 -ffor-scope -pipe -fno-gnu-keywords -foperator-names -pthread -Wno-long-long -Wextra -Wno-missing-field-initializers -O3 <> -c -W -Wno-sign-compare -Wno-deprecated -Wno-non-virtual-dtor -Wpointer-arith -Wno-switch -std=c++17 -ffor-scope -pipe -fno-gnu-keywords -foperator-names -pthread -Wno-long-long -Wextra -Wno-missing-field-initializers -O3 <
build 30-May-2023 11:14:15 g>
error 30-May-2023 11:14:16 make[1]: *** [Makefile:18: linux64/BcsCollect.o] Error 2
error 30-May-2023 11:14:16 make[1]: *** Waiting for unfinished jobs....
error 30-May-2023 11:14:19 make[1]: *** [Makefile:21: linux64/BoundaryConditionServer.o] Error 2
问题解答
1. 报错后终止是否为make的默认行为?
不是立刻终止,make的默认并行行为是:遇到第一个错误后,不会立刻杀死正在运行的子作业,而是等待所有未完成的作业结束后,再终止并返回错误码。日志中的make[1]: *** Waiting for unfinished jobs....就是这个默认行为的体现。
但正常情况下,make最终会返回非0的错误码,而非成功码。如果脚本中返回码为成功,大概率是脚本本身的错误处理逻辑导致(比如用了make ... || true忽略错误,或者后续命令覆盖了返回码)。
2. 多任务运行时是否需要特殊处理?
需要,针对不同需求可以做以下调整:
让make遇到错误后立刻终止所有作业
使用--stop(简写-S)选项,该选项在make 3.81及以上版本支持(你的make 4.3完全兼容),命令改为:make --jobs=3 --stop -f Makefile这样某个子作业失败时,make会立刻终止所有正在运行的并行作业,而不是等待它们完成。
确保make返回正确的错误码
- 检查构建脚本,确保没有忽略make的错误(比如避免使用
make ... || true这类语句) - 若Makefile中存在子make调用,必须使用
$(MAKE)而非直接写make,确保错误码能正确传递到顶层make进程
- 检查构建脚本,确保没有忽略make的错误(比如避免使用
解决构建失败的根本原因
日志中报错是无法创建.o文件,核心原因是linux64目录不存在或权限不足。可以在Makefile中添加目录依赖,确保编译前目录存在:# 确保linux64目录存在 linux64: mkdir -p $@ # 让所有目标文件依赖linux64目录 linux64/%.o: | linux64这样可以从根源上减少此类构建失败。
内容的提问来源于stack exchange,提问作者nobs

