Makefile字符串比较结果异常:空变量触发存在分支
问题
我需要在Makefile中检查系统是否存在rocq程序,存在则将变量COQC设为rocq c,不存在则设为coqc。写了如下代码:
OUTPUT=$(shell which rocq 2>/dev/null) ifneq ($(OUTPUT), "") COQC=rocq c else COQC=coqc endif COQC := $(COQC)" -R . Mendelson" all: @echo [$(COQC)] @echo [$(OUTPUT)]
运行输出却显示:
[rocq c -R . Mendelson] []
明明$(OUTPUT)是空的,却走了存在分支,这是哪里错了?
解答
问题根源
问题出在which命令的返回值和Makefile的空值判断逻辑上:
- 当
which找不到目标程序时,标准输出是空,但$(shell ...)会保留命令执行后的换行符,也就是说OUTPUT变量实际存的是一个空行(不是完全的空字符串)。 - 你写的
ifneq ($(OUTPUT), "")是在判断OUTPUT是否等于空字符串,但带换行符的空行和空字符串不相等,所以条件判定为真,走了rocq c的分支。
修复方法
方法1:用strip清理空白后判断
用Makefile的strip函数去掉OUTPUT里的换行、空格等空白字符,再判断是否为空:
OUTPUT=$(shell which rocq 2>/dev/null) ifneq ($(strip $(OUTPUT)),) COQC=rocq c else COQC=coqc endif COQC := $(COQC)" -R . Mendelson" all: @echo [$(COQC)] @echo [$(OUTPUT)]
方法2:直接检查命令退出码(更推荐)
which找不到程序时会返回非0退出码,直接通过这个退出码判断更可靠,还不用保存输出:
ifeq ($(shell which rocq >/dev/null 2>&1; echo $$?),0) COQC=rocq c else COQC=coqc endif COQC := $(COQC)" -R . Mendelson" all: @echo [$(COQC)]
内容的提问来源于stack exchange,提问作者user4035
相关产品推荐
相关产品推荐

