gnu-make之为什么条件变量赋值会设置一个值,而标准赋值却不会

shihaiming 阅读:745 2025-06-02 22:19:02 评论:0

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

我试图通过将命令分配给变量然后使用 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 

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

FOO not found 
BAR found with value '' 

GNU make documentation表示 ifdef 寻找非空值。

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

请您参考如下方法:

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

FOO := $(shell which foo) 

$(shell which foo)的简单扩展值定义FOO, 这是空字符串。因此 ifdef FOO 的计算结果为 false。

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 


标签:程序员
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号