在Make中如何配置规则仅在特定退出码时执行失败?
解决Makefile中自定义退出码判断的问题
这场景太常见了!要实现「命令返回1时规则成功,0或2时失败」的需求,直接用!反转肯定不行——毕竟它只能把非0变0、0变非0,没法区分0和2。咱们得在Makefile里用shell脚本手动捕获并转换退出码,刚好适配你拼写检查的场景。
核心思路
Make的规则判定逻辑很简单:命令返回0=成功,非0=失败。所以我们要做的就是:
- 捕获你拼写检查命令的原始退出码
- 把原始码1转换成0(让Make认为成功)
- 把原始码0/2转换成非0(让Make认为失败)
具体实现
假设你的拼写检查命令是aspell check --mode=text your_doc.txt | grep -n "^\*",可以这样包装成Make规则:
.PHONY: spellcheck spellcheck: @# 开启pipefail确保捕获管道中所有命令的错误(可选但推荐) @set -o pipefail; \ # 执行你的拼写检查命令 aspell check --mode=text your_doc.txt | grep -n "^\*"; \ # 捕获命令的退出码 EXIT_CODE=$$?; \ # 根据退出码转换状态给Make case $$EXIT_CODE in \ 1) \ # 原始返回1,告诉Make规则成功 exit 0; \ ;; \ 0|2) \ # 原始返回0或2,告诉Make规则失败 exit 1; \ ;; \ esac
关键细节解释
.PHONY: spellcheck:标记这个规则不是生成文件,每次执行make spellcheck都会重新运行命令,避免Make误以为spellcheck是个文件而跳过执行。set -o pipefail:默认shell只返回管道最后一个命令的退出码,开启这个选项后,管道的退出码会等于管道中第一个非0的退出码——这样如果aspell本身出错返回2,我们能准确捕获到,而不会被后面grep的状态覆盖。$$?和$$EXIT_CODE:在Makefile里,$是Make的变量符号,所以要引用shell变量必须用$$,不然会被Make解析成自己的变量。case语句:比if-elif更清晰地处理多个退出码的分支,完美适配你需要判断0、1、2三种情况的需求。
简化版本(如果不需要处理管道)
如果你的命令不是管道,或者不需要关心前面命令的错误,可以简化成if判断:
.PHONY: spellcheck spellcheck: @your_spellcheck_command; \ EXIT_CODE=$$?; \ if [ $$EXIT_CODE -eq 1 ]; then exit 0; else exit 1; fi
这样也能实现同样的逻辑,写法更简洁。
内容的提问来源于stack exchange,提问作者iter
相关产品推荐
相关产品推荐

