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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 23:50:04