GNU Makefile变量赋值=,?=,:=和+ =有什么区别?

守給你的承諾、 提交于 2019-12-21 19:48:47

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

任何人都可以清楚地解释变量赋值在Makefiles中是如何工作的。

之间有什么区别:

 VARIABLE = value
 VARIABLE ?= value
 VARIABLE := value
 VARIABLE += value

我已经阅读了GNU Make手册中的部分 ,但是对我来说仍然没有意义。


#1楼

我建议您使用“ make”做一些实验。 这是一个简单的演示,显示了=:=之间的区别。

/* Filename: Makefile*/
x := foo
y := $(x) bar
x := later

a = foo
b = $(a) bar
a = later

test:
    @echo x - $(x)
    @echo y - $(y)
    @echo a - $(a)
    @echo b - $(b)

make test打印:

x - later
y - foo bar
a - later
b - later bar

在这里查看更多详细的解释


#2楼

在以上答案中, 重要的是要了解 “在声明/使用时扩展值”的含义。 给出*.c类的值不需要任何扩展。 只有当命令使用此字符串时,它才可能触发一些glob。 类似地,像$(wildcard *.c)$(shell ls *.c)不需要任何扩展,即使在变量定义中使用:= ,该值也将在定义时完全求值。

在有一些C文件的目录中尝试以下Makefile:

VAR1 = *.c
VAR2 := *.c
VAR3 = $(wildcard *.c)
VAR4 := $(wildcard *.c)
VAR5 = $(shell ls *.c)
VAR6 := $(shell ls *.c)

all :
    touch foo.c
    @echo "now VAR1 = \"$(VAR1)\"" ; ls $(VAR1)
    @echo "now VAR2 = \"$(VAR2)\"" ; ls $(VAR2)
    @echo "now VAR3 = \"$(VAR3)\"" ; ls $(VAR3)
    @echo "now VAR4 = \"$(VAR4)\"" ; ls $(VAR4)
    @echo "now VAR5 = \"$(VAR5)\"" ; ls $(VAR5)
    @echo "now VAR6 = \"$(VAR6)\"" ; ls $(VAR6)
    rm -v foo.c

运行make将触发一个规则,该规则将创建一个名为foo.c的额外(空)C文件,但6个变量中的任何一个都不包含foo.c


#3楼

懒集

VARIABLE = value

变量的常规设置-使用变量时(而不是在声明变量时)递归扩展其中的值

立即设置

VARIABLE := value

使用内部值的简单扩展设置变量-在声明时扩展其中的值。

如果不存在则设置

VARIABLE ?= value

仅在没有值的情况下设置变量

附加

VARIABLE += value

将提供的值附加到现有值(如果变量不存在,则设置为该值)


#4楼

当使用VARIABLE = value ,如果value实际上是对另一个变量的引用,则仅在使用VARIABLE时才确定该值。 最好用一个例子说明:

VAL = foo
VARIABLE = $(VAL)
VAL = bar

# VARIABLE and VAL will both evaluate to "bar"

当您使用VARIABLE := value ,你得到的价值value ,因为它是现在 。 例如:

VAL = foo
VARIABLE := $(VAL)
VAL = bar

# VAL will evaluate to "bar", but VARIABLE will evaluate to "foo"

使用VARIABLE ?= val意味着你只设定的值VARIABLE ,如果 VARIABLE尚未设置。 如果尚未设置,则将值的设置推迟到使用VARIABLE之前(如示例1中所示)。

VARIABLE += value只是将value附加到VARIABLE 。 value的实际值是使用=:=确定其初始设置时的value


#5楼

使用=会为变量分配一个值。 如果变量已经具有值,则将其替换。 使用时将扩展该值。 例如:

HELLO = world
HELLO_WORLD = $(HELLO) world!

# This echoes "world world!"
echo $(HELLO_WORLD)

HELLO = hello

# This echoes "hello world!"
echo $(HELLO_WORLD)

使用:=类似于使用= 。 但是,与其在使用时扩展值,不如在分配期间扩展它。 例如:

HELLO = world
HELLO_WORLD := $(HELLO) world!

# This echoes "world world!"
echo $(HELLO_WORLD)

HELLO = hello

# Still echoes "world world!"
echo $(HELLO_WORLD)

HELLO_WORLD := $(HELLO) world!

# This echoes "hello world!"
echo $(HELLO_WORLD)

使用?=分配当且仅当变量的值没有被先前分配的变量。 如果该变量先前分配了一个空白值( VAR= ), 我认为仍将其视为设置。 否则,功能与=完全相同。

使用+=就像使用= ,但是不是替换值,而是将值附加到当前值后面,并在两者之间留有空格。 如果该变量以前是用:=设置的, 我认为它将被扩展。 我认为,使用它时,结果值会扩展。 例如:

HELLO_WORLD = hello
HELLO_WORLD += world!

# This echoes "hello world!"
echo $(HELLO_WORLD)

如果类似HELLO_WORLD = $(HELLO_WORLD) world! 使用时,将导致递归,这很可能会结束Makefile的执行。 如果使用A := $(A) $(B) ,则结果与使用+=并不完全相同,因为B:=扩展,而+=不会导致B扩展。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!