为什么条件变量赋值设置了值但标准赋值没有?

时间:2016-02-28 15:53:32

标签: gnu-make

出于这个问题的目的,通过条件变量赋值我的意思是?=运算符和标准赋值我的意思是:=运算符。

我试图通过将命令分配给变量然后使用ifdef检查它来检查命令是否存在,但我看到不同的行为取决于我用来执行初始赋值的两个运算符中的哪一个。 / p>

这是一个简化的Makefile示例。请注意,我的系统上既不存在foo也不存在bar,因此我希望这两项检查都能触发"未找到"分支。

FOO := $(shell which foo)
BAR ?= $(shell which bar)

all:
ifdef FOO
    echo "FOO found with value '${FOO}'"
else
    echo "FOO not found"
endif
ifdef BAR
    echo "BAR found with value '${BAR}'"
else
    echo "BAR not found"
endif

当我运行make时,我得到了这个结果:

FOO not found
BAR found with value ''

GNU make documentation表示ifdef会查找非空值。

为什么这两个赋值运算符的行为和它们产生的内容不同?

1 个答案:

答案 0 :(得分:5)

咨询GNU Make documentation以注意两者之间的区别 递归扩展变量简单扩展变量

FOO := $(shell which foo)

使用FOO的简单扩展值定义$(shell which foo), 这是空字符串。因此ifdef FOO将评估错误。

BAR ?= $(shell which bar)

将BAR定义为$(shell which bar),除非它已经定义。它缩写为

ifndef BAR
    BAR = $(shell which bar)
endif

请注意=,而不是:=

假设尚未定义BAR,其定义变为$(shell which bar),而不是空字符串。 因此在:

ifdef BAR
    echo "BAR found with value '${BAR}'"
else
    echo "BAR not found"
endif
发现

BAR具有定义和递归扩展值 它的定义是回应的,即''。

要从BAR获取与FOO相同的行为,请尝试:

FOO := $(shell which foo)
BAR ?= $(shell which bar)
BAR := $(BAR)

all:
ifdef FOO
    echo "FOO found with value '${FOO}'"
else
    echo "FOO not found"
endif
ifdef BAR
    echo "BAR found with value '${BAR}'"
else
    echo "BAR not found"
endif