为什么条件变量赋值设置一个值,而标准赋值却没有?

Bur*_*Ali 3 gnu-make

就此问题而言,条件变量赋值是指?=运算符,而标准赋值是指:=运算符。

我试图通过将命令分配给变量,然后使用来检查命令,以检查是否存在命令,ifdef但是我看到了不同的行为,具体取决于我用来进行初始分配的两个运算符中的哪个。

这是一个简化的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
Run Code Online (Sandbox Code Playgroud)

运行时make,我得到以下结果:

FOO not found
BAR found with value ''
Run Code Online (Sandbox Code Playgroud)

GNU的make文件说,ifdef寻找一个非空值。

为什么这两个赋值运算符的行为和产生的结果不同?

Mik*_*han 5

请查阅GNU Make文档,以注意递归扩展变量简单扩展变量之间的区别。

FOO := $(shell which foo)
Run Code Online (Sandbox Code Playgroud)

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

BAR ?= $(shell which bar)
Run Code Online (Sandbox Code Playgroud)

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

ifndef BAR
    BAR = $(shell which bar)
endif
Run Code Online (Sandbox Code Playgroud)

注意=,不是:=

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

ifdef BAR
    echo "BAR found with value '${BAR}'"
else
    echo "BAR not found"
endif
Run Code Online (Sandbox Code Playgroud)

BAR 被发现具有定义,并且回显其定义的递归扩展值,即“”。

为了得到相同的行为BARFOO,请尝试:

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
Run Code Online (Sandbox Code Playgroud)