Makefile变量赋值

184 篇文章 1 订阅
151 篇文章 2 订阅

:= 的赋值是马上生效,  = 则是等到变量被引用时才递归生效。

makefile1:

bar=456
foo=${bar}
bar=${xxx}
xxx=123

all:
echo ${foo}

echo出的结果是 123, foo的值在 echo 的时候,先被扩展成 ${bar}, 再递归的被扩展成 ${xxx},最终是123

makefile2:

bar=456
foo:=${bar}
bar=${xxx}
xxx=123

all:
echo ${foo}

此时由于 用了 := ,在赋值时候 foo 的值就直接被扩展成 bar 在那个时刻的值,即 456, 最后的echo的结果也就是 456 了。

+= 是在一个变量的值的尾部增加内容,如:

foo = abc
foo += efg

则 foo 的值就是 abc efg

参考:

linux Makefile configure里面 += := -= 这些符号的意思?_百度知道 (baidu.com)

讯飞星火

在Makefile中,变量赋值使用等号(=)进行。例如:

变量名 = 变量值

如果要给变量赋空值,可以使用两个等号(==):

变量名 ==

ChatGPT

在Makefile中,可以使用不同的方式给变量赋值。通常情况下,可以使用 := 或 = 来为变量赋值。如果想要执行`pwd`命令,并将输出赋值给变量,应该使用shell函数来捕获命令输出。
这里有一个例子,展示了如何在Makefile中执行`pwd`命令并将结果赋给一个变量:

CURRENT_DIR := $(shell pwd)

all:
    @echo $(CURRENT_DIR)

当在Makefile中执行`make`命令时,它会打印出当前目录的绝对路径。
需要注意的是:
- := 是立即赋值运算符,它在make解析到该行时立即进行赋值,只被评估一次。
- = 是延迟赋值运算符,赋值语句每次被引用时都会重新评估。
在这个例子中,我们使用 :=,因为我们希望`pwd`命令只在变量定义时执行一次,并且在整个Makefile中保持不变。
如果要在规则执行时检索当前目录路径,可以在规则的命令中直接使用`pwd`:

all:
    @echo $(shell pwd)

在这个例子中,每次执行`all`目标时,`pwd`命令都会被执行一次。

通义灵码

在Makefile中,变量赋值是定义和管理构建过程中使用的各种参数、路径、选项等的重要手段。Makefile提供了多种赋值方式,包括简单赋值(:=)、递归赋值(=)、条件赋值(?=)和追加赋值(+=)。以下是这些赋值方式的详细说明:

  • 简单赋值(:=)
VAR := value

简单赋值使用双冒号(:=)进行,它立即展开赋值右边的值,不进行递归展开。这意味着如果赋值右边含有未定义的变量,Makefile会报错,而不是等待那些变量在后面的规则中被定义。简单赋值适用于不需要递归展开、希望立即确定值的情况,它能够提高Makefile的解析速度和减少意外行为。

  • 递归赋值(=)
VAR = value

递归赋值使用单等号(=)进行,赋值右边的值会在引用该变量时才被展开。如果赋值右边包含未定义的变量,Makefile不会立即报错,而是等到实际使用该变量时再尝试展开。这种赋值方式允许在文件中先声明变量,然后在后续位置定义其依赖的其他变量。递归赋值可能导致更复杂的依赖关系和潜在的延迟展开问题,但如果需要构建复杂的、相互依赖的变量值,它是必需的。

  • 条件赋值(?=)
VAR ?= value

条件赋值同样使用单等号,但在等号前加问号。只有当变量VAR尚未被定义或其值为空时,才会执行赋值操作。如果VAR已经有非空值,条件赋值将被忽略。这种赋值方式常用于为变量提供默认值,避免覆盖用户可能已经通过环境变量或其他方式设置的值。

  • 追加赋值(+=)
VAR += value

追加赋值用于向已有变量的值后面追加新的内容。如果VAR未定义,追加赋值相当于简单赋值。如果VAR已有值,value会被添加到现有值后面,中间以空格分隔。这对于累积编译选项、源文件列表等需要动态增长的值非常有用。

示例

# 简单赋值
DIRECTORIES := src include

# 递归赋值
CFLAGS = -g -Wall
CFLAGS += $(shell pkg-config --cflags libfoo)  # 假设libfoo在后续规则中被检测到

# 条件赋值(为CXXFLAGS提供默认值)
CXXFLAGS ?= -std=c++17

# 追加赋值
SOURCES := main.c util.c
SOURCES += extra.c  # 添加额外源文件

# 使用变量
all: $(OBJS)
    $(CC) $(CFLAGS) $(SOURCES) -o my_program

# 清理变量
clean:
    rm -f $(OBJS) my_program

总结来说,选择合适的赋值方式取决于具体需求:

  • 简单赋值(:=):用于立即确定值且不需要依赖其他变量的场景。
  • 递归赋值(=):用于构建复杂、递归依赖的变量值。
  • 条件赋值(?=):为变量提供默认值,避免覆盖已存在的非空值。
  • 追加赋值(+=):向已有变量值中追加内容,用于累积列表或字符串。

文心一言

在Makefile中,可以使用不同的方法来为变量赋值。下面是几种常见的变量赋值方法:

直接赋值(递归展开式变量):
这是最简单的方式,直接给变量赋一个值。在Makefile中,当使用这种方式赋值的变量在定义它的地方之后被展开时,如果变量被重新定义了,那么它会使用最新的值。

VARIABLE = value
  • 简单赋值(直接展开式变量):

使用:=操作符进行赋值,这种方式会立即展开变量的值,也就是说在赋值的时候变量的值就被确定了,以后不会被重新展开。

VARIABLE := value
  • 条件赋值:

可以使用条件语句来为变量赋值,这通常与ifdef、ifndef、ifeq等条件指令结合使用。

ifeq ($(DEBUG),1)  
DEBUG_FLAGS = -g -O0  
else  
DEBUG_FLAGS = -O2  
endif
  • 命令行赋值:

在make命令行上可以直接给变量赋值,这将覆盖Makefile中的任何赋值。

make VARIABLE=value
  • 使用环境变量:

Makefile中的变量可以引用环境变量。如果没有在Makefile中给变量赋值,那么make会使用相应的环境变量的值(如果存在的话)。

VARIABLE = $(ENV_VARIABLE)
  • 追加值:

使用+=操作符可以向变量追加值,而不是覆盖它。

VARIABLE += more_value

在使用变量时,可以使用${VARIABLE}或$(VARIABLE)语法来引用它们。注意,$符号在Makefile中有特殊含义,所以如果想在变量值中使用字面的$符号,需要使用$$来转义它。 

例如:

all:
    @echo $$HOME

在这个例子中,`$$HOME`将输出当前用户的主目录环境变量`$HOME`,因为`$$会被Make解释为一个单一的$。如果只写了$HOME`,Make会尝试将`HOME`作为Makefile中的变量解释,可能会导致不是想要的结果,或者是变量未定义错误。
当Make解析这个规则时,它会将$$替换为一个$,因此实际执行的命令是echo $HOME,这将正确地打印出环境变量HOME的值。 


下面是一个简单的Makefile示例,展示了不同的变量赋值方法: 

# 直接赋值(递归展开式)  
SIMPLE_VAR = simple_value  
  
# 简单赋值(直接展开式)  
IMMEDIATE_VAR := immediate_value  
  
# 条件赋值  
ifeq ($(DEBUG),1)  
  DEBUG_FLAGS = -g -O0  
else  
  DEBUG_FLAGS = -O2  
endif  
  
# 追加值  
EXTRA_FLAGS = -Wall  
EXTRA_FLAGS += -Wextra  
  
# 使用环境变量(假设 ENV_VAR 已经在环境中定义)  
ENV_BASED_VAR = $(ENV_VAR)  
  
all:  
    @echo "SIMPLE_VAR: ${SIMPLE_VAR}"  
    @echo "IMMEDIATE_VAR: ${IMMEDIATE_VAR}"  
    @echo "DEBUG_FLAGS: ${DEBUG_FLAGS}"  
    @echo "EXTRA_FLAGS: ${EXTRA_FLAGS}"  
    @echo "ENV_BASED_VAR: ${ENV_BASED_VAR}"

在这个例子中,`SIMPLE_VAR`使用递归展开式赋值,`IMMEDIATE_VAR`使用直接展开式赋值,`DEBUG_FLAGS`根据条件赋值,`EXTRA_FLAGS`通过追加赋值来累加标志,而`ENV_BASED_VAR`则使用环境变量进行赋值。运行`make`命令时,这些变量会被展开并打印出来。

在这个Makefile中:

  1. SIMPLE_VAR使用了递归展开式的直接赋值。如果在后续Makefile中重新给SIMPLE_VAR赋值,那么all目标中引用的SIMPLE_VAR将会使用最新的值。

  2. IMMEDIATE_VAR使用了直接展开式的简单赋值(:=)。这意味着IMMEDIATE_VAR的值在赋值时就被确定了,后续对IMMEDIATE_VAR的修改不会影响all目标中引用的值。

  3. DEBUG_FLAGS使用了条件赋值。根据DEBUG变量的值来决定赋给DEBUG_FLAGS的是-g -O0还是-O2

  4. EXTRA_FLAGS首先被赋值为-Wall,然后追加了-Wextra,所以最终它的值是-Wall -Wextra

  5. ENV_BASED_VAR使用了环境变量赋值。它的值将会从环境变量ENV_VAR中取得。如果ENV_VAR没有在环境中定义,那么ENV_BASED_VAR将会是空的。

当运行make命令时,这些变量的值会被打印出来。如果想要改变DEBUG_FLAGS的值,可以在命令行上通过make DEBUG=1来设置DEBUG变量的值,从而改变DEBUG_FLAGS的值。同样地,如果已经在环境中定义了ENV_VAR,那么ENV_BASED_VAR将会从环境中取得相应的值。

Kimi

在Makefile中,变量赋值是构建系统的核心部分,它允许你定义一些值,这些值可以在Makefile的其他部分中被引用。以下是几种常见的变量赋值方法:

  1. 直接赋值:

    VARIABLE = value
  2. 使用变量的值进行赋值:

    VARIABLE = $(另一些变量或表达式)
  3. 条件赋值 (?=): 仅当变量之前没有被赋值时才赋值。

    VARIABLE ?= value
  4. 追加赋值 (+=): 将值追加到变量的末尾。

    VARIABLE += value
  5. 替换赋值 (:=): 为变量赋一个值,即使它之前已经被赋值了。

    VARIABLE := value
  6. 命令替换: 使用shell命令的输出作为变量的值。

    VARIABLE = $(shell command)
  7. 参数化赋值 (?=+=): 可以结合参数化目标使用。

    .PHONY: default default: VAR ?= new-value
  8. 使用通配符 (wildcard, patsubst, subst, strip 等): 这些函数可以用于更复杂的变量赋值和处理。

    SOURCES := $(wildcard *.c)
  9. 使用foreach: 对一系列值进行迭代并生成变量。

    $(foreach v, $(1 2 3), $(v):=something)
  10. 使用shell命令: 直接在Makefile中执行shell命令并赋值。

    CURRENT_DIR := $(shell pwd)

下面是一个包含多种赋值方法的Makefile示例:

# 直接赋值
CC = gcc

# 使用变量的值进行赋值
CFLAGS = -Wall -O2

# 条件赋值
ifeq ($(CC),)
    CC ?= cc
endif

# 追加赋值
CFLAGS += -std=gnu99

# 替换赋值
override CFLAGS := $(CFLAGS) -pedantic

# 命令替换
GIT_REV := $(shell git rev-parse --short HEAD)

# 使用通配符
SOURCES := $(wildcard *.c)

# 使用foreach
FILES := $(foreach src,$(SOURCES),obj/$(src:.c=.o))

# 打印变量
print-%: ; @echo $* = $($*)

.PHONY: all clean print-variables

all: print-variables

clean:
	rm -f obj/*.o

print-variables:
	$(foreach v,CC CFLAGS SOURCES GIT_REV FILES,$(call print-%,$v))

在这个Makefile中,我们定义了多个变量,包括使用不同方法赋值的变量,并在print-variables目标中打印了它们的值。使用make print-variables可以查看这些变量的值。

请注意,Makefile中变量赋值的顺序很重要,因为变量的值可能依赖于之前已经定义的其他变量。此外,:=?=操作符在不同上下文中的行为可能不同,override关键字可以用来确保变量在目标中被重新赋值。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
makefile 实例分析 Makefile 语法分析 第一部分 VERSION = 2# 给变量VERSION赋值 PATCHLEVEL = 6# 给变量PATCHLEVEL赋值 SUBLEVEL = 22# 给变量SUBLEVEL赋值 EXTRAVERSION = .6# 给变量EXTRAVERSION赋值 NAME = Holy Dancing Manatees, Batman!# 给变量NAME赋值 # *DOCUMENTATION*# To see a list of typical targets execute "make help"# More info can be located in ./README# Comments in this file are targeted only to the developer, do not# expect to learn how to build the kernel reading this file. # Do not:# o use make's built-in rules and variables#    (this increases performance and avoid hard-to-debug behavour);# o print "Entering directory ...";MAKEFLAGS += -rR --no-print-directory# 操作符“+=”的作用是给变量(“+=”前面的MAKEFLAGS)追加值。# 如果变量(“+=”前面的MAKEFLAGS)之前没有定义过,那么,“+=”会自动变成“=”;# 如果前面有变量(“+=”前面的MAKEFLAGS)定义,那么“+=”会继承于前次操作的赋值符;# 如果前一次的是“:=”,那么“+=”会以“:=”作为其赋值符# 在执行make时的命令行选项参数被通过变量 “MAKEFLAGS”传递给子目录下的make程序。# 对于这个变量除非使用指示符“unexport”对它们进行声明,它们在整个make的执行过程中始终被自动的传递给所有的子make。# 还有个特殊变量SHELL与MAKEFLAGS一样,默认情况(没有用“unexport”声明)下在整个make的执行过程中被自动的传递给所有的子make。
Makefile脚本中,变量赋值可以通过使用等号(=)或冒号等号(:=)来完成。等号赋值是简单的赋值操作,而冒号等号赋值是递归赋值,它会在赋值时展开变量的引用。例如,变量赋值可以如下所示: ``` VAR = value ``` 或者 ``` VAR := value ``` 其中,VAR是变量名,value是要赋给变量的值。等号赋值会在使用变量时才进行展开,而冒号等号赋值会在赋值时就展开变量的引用。 此外,还可以使用自动变量、预定义变量和环境变量赋值。自动变量是在每个规则中自动生成的变量,例如$@表示目标文件名,$^表示所有依赖文件名。预定义变量是由Make工具提前定义好的变量,可以直接在Makefile中使用,例如CFLAGS表示编译选项。环境变量是系统的环境变量,可以通过export关键字将其传递到Makefile中。 总结起来,Makefile脚本中的变量赋值可以使用等号或冒号等号进行简单赋值或递归赋值,还可以使用自动变量、预定义变量和环境变量赋值。 #### 引用[.reference_title] - *1* *3* [Makefile命令与变量](https://blog.csdn.net/Suffocatingg/article/details/127922649)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [makefile 变量赋值方式](https://blog.csdn.net/wuyiyu_/article/details/130555532)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

109702008

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值