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

GNU Make:如何避免其他目标出错时删除已成功生成的中间文件

构建出错时保留Make已生成的中间文件

问题背景

现有如下Makefile:

.RECIPEPREFIX = +
.ONESHELL:

all: one

vars := one.a two.a three.a
.INTERMEDIATE: $(vars)

one: $(vars)
+ touch $@

%.a: %.b
+ touch $@

%.b:
+ if [ "$@" = "three.b" ];
+ then
+   exit 1;
+ fi
+ touch $@

所有目标构建耗时较长,正常情况下.INTERMEDIATE标记的中间文件会被自动清理,符合预期。但当某目标构建出错(如示例中three.b生成失败)时,Make会停止并删除所有已成功生成的中间文件,并行构建时该问题影响更严重。需要实现构建出错时保留已成功生成的中间文件的需求。

解决方案

方案1:用.SECONDARY替代.INTERMEDIATE

将Makefile中的.INTERMEDIATE: $(vars)替换为:

.SECONDARY: $(vars)

.SECONDARY是Make的特殊目标,标记的文件永远不会被自动删除——不管构建成功还是失败,已生成的中间文件都会保留。如果需要清理这些文件,可以手动添加clean目标:

clean:
+ rm -f $(vars) one

执行make clean即可完成清理。

方案2:-k参数配合自定义清理逻辑

如果希望正常构建完成时自动清理中间文件,出错时保留产物,可以采用以下方式:

  1. 执行Make时添加-k(或--keep-going)参数:
    make -k
    
    该参数会让Make在遇到错误时继续尝试构建其他可完成的目标,同时不会删除已成功生成的中间文件。
  2. 保留原.INTERMEDIATE配置,同时添加自定义清理目标,在构建成功后手动执行清理(如果需要)。

原理说明

  • .INTERMEDIATE的核心特性:只要文件不再被任何目标依赖,无论构建成功与否,都会被Make自动删除。
  • .SECONDARY的核心特性:标记的文件不会被Make自动删除,仅能通过手动清理或其他规则删除。
  • -k参数的作用:让Make忽略单个目标的失败,继续构建其他依赖链,同时保留已生成的所有中间产物。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 11:04:58