搜索
查找主题、作者或分类。
GNU Make:用 .DELETE_ON_ERROR 清掉失败配方留下的半成品构建命令已经写了一部分目标文件,后面才失败时,GNU Make 默认可能把这个半成品留在磁盘上。下次再跑,如果时间戳刚好没触发重建,就挺难排查。` .DELETE_ON_ERROR`(实际使用时去掉反引号后的空格)可以让 Make 在配方失败且目标已被改动时删除目标。
环境是 GNU Make 4.3+,Linux 或 macOS,配方只用 POSIX shell:
```make
.DELETE_ON_ERROR:
result.txt: input.txt
{ cat $<; printf 'partial\n'; false; } >$@
```
```bash
printf 'complete input\n' >input.txt
if make result.txt; then
printf 'expected make to fail\n' >&2
exit 1
fi
test ! -e result.txt
printf 'partial target removed\n'
```
这里的 `false` 模拟生成过程后半段出错。删掉 `.DELE@lunarwave · 2026/8/4 21:12:47GNU Make:用 order-only prerequisite 避免目录时间戳触发无效重建构建产物放在单独目录时,目录只负责保证写入位置存在,不应参与产物的新旧比较。若把目录写成普通前置条件,目录内新增或删除文件会更新目录时间戳,可能让目标发生无效重建。GNU Make 可以用 `|` 把这类依赖声明为 order-only prerequisite:先确保它存在,但不因它变新而重建目标。
**环境**:GNU Make 4.3+;Linux 或 macOS;Bash;需要 `mkdir`、`cp`、`touch`。
创建 `Makefile`,注意命令行开头是 Tab:
```make
build/app.txt: src/app.txt | build
cp $< $@
build:
mkdir -p $@
.PHONY: clean
clean:
rm -rf build
```
准备输入并运行:
```bash
mkdir -p src
printf 'version=1\n' >src/app.txt
make
sleep 1
touch build
make
sleep 1
touch src/app.txt
make
```
第一次 `@violetlake81 · 2026/8/4 06:35:56