Makefile学习笔记_04_变量定义与使用_常用符号
目录
说明
自学B站某课程的笔记,欢迎小伙伴们共同讨论,若有理解不对的地方也欢迎指出。
https://www.bilibili.com/video/BV1EM41177s1/spm_id_from=333.999.0.0
开发环境:Visual Studio Code + gcc
变量的定义/声明
变量名 := 文件夹名/文件名
cpp := src/main.cpp
obj := objs/main.o
Note: 这里的 src/main.cpp 和 objs/main.o 只是字符串,并不代表真的存在文件。后续示例中会说明,比如我们要用 cpp 生成 obj ,那么 cpp 表示的 main.cpp 文件必须存在,而 obj 表示的 main.o 文件是我们即将通过编译生成的文件,并不存在。
变量的引用
$(变量名)
美刀+圆括号
${变量名}
美刀+花括号
示例
我们通过src
文件夹下的main.cpp
文件编译生成objs
文件夹下的main.o
文件。其中,src
与objs
为同级目录下的文件夹,obj
为空文件夹。
代码如下:
cpp := src/main.cpp #定义变量cpp
obj := objs/main.o #定义变量obj
$(obj) : ${cpp} #引用变量 obj,其中 obj 的依赖是变量 cpp,即 main.o 的依赖是 main.cpp
@g++ -c $(cpp) -o $(obj)
#g++ -c src/main.cpp -o objs/main.o
compile: $(obj) #编译目标obj变量
debug:
@echo $(cpp) #输出变量cpp
@echo $(obj) #输出变量obj
我们可以先通过make debug
命令输出cpp
与obj
两个变量,观测其结果是否正常。
结果显示输出两个字符串,正常。
然后,通过make compile
命令进行编译,编译完成后,空文件夹objs
下会出现main.o
文件。
解释: 以下两段代码是同样的意思,只不过一个是直接通过文件夹/文件名的方式在编译,而另一个是把“文件夹/文件名”这个字符串定义成变量,然后再通过变量来编译。
$(obj) : ${cpp} #引用变量 obj,其中 obj 的依赖是变量 cpp,即 main.o 的依赖是 main.cpp
@g++ -c $(cpp) -o $(obj)
g++ -c src/main.cpp -o objs/main.o
完善上述代码后,完整代码如下:
cpp := src/main.cpp #定义变量cpp
obj := objs/main.o #定义变量obj
$(obj) : ${cpp} #引用变量 obj,其中 obj 的依赖是变量 cpp,即 main.o 的依赖是 main.cpp
@g++ -c $(cpp) -o $(obj)
#g++ -c src/main.cpp -o objs/main.o
compile: $(obj) #编译目标obj变量
clean: #删除objs文件夹
@rm -rf objs
debug:
@echo $(cpp) #输出变量cpp
@echo $(obj) #输出变量obj
.PHONY: clean debug #避免目标与文件夹同名,申明为伪目标。
预定义变量
可以用于替换一些目标以及文件的名字。
$@
: 目标(target)的完整名称$<
: 第一个依赖文件(prerequisties)的名称$^
: 所有的依赖文件(prerequisties),以空格分开,不包含重复的依赖文件
通过预定义变量,可将上述代码中的:
$(obj) : ${cpp}
@g++ -c $(cpp) -o $(obj)
替换成下面代码:
$(obj) : ${cpp}
@g++ -c $< -o $@
常用符号
1. =(常规赋值运算符)
特点: 变量可被反复赋值
a = 64
b = $(a) #这里a为64,b为64
b = 75 #这里b为75
debug:
@echo $(b) #输出b时结果为75
可自行用make debug命令尝试,这里就不贴结果图了。
2. :=(立即赋值运算符)
特点: 变量被赋值后不可更改,即便你重新定义。
a := 64
b := $(a) #这里a为64,b为64
a := 75 #这里a为75
debug:
@echo $(b) #输出b时结果为64 b引用的a,即便a已经重新赋值
3. ?=(默认赋值运算符)
特点:
如果该变量已经定义,则不进行任何操作
如果该变量尚未定义,则求值并分配
a = 64
a ?= 75 #a之前已经被定义过,故:=不进行任何操作
debug:
@echo $(a) #a输出仍然为64
a = #什么都不写,此时默认赋值 空字符
a ?= 75 #a之前已经被定义过,故:=不进行任何操作
debug:
@echo $(a) #a输出为 空字符
a ?= 75 #a之前没被定义过,故:=等同于=
debug:
@echo $(a) #a输出为75
4. +=(累加赋值运算符)
特点: 把多个字符串连接成一个字符串。
a := world!
b := hello
b += $(a)
debug:
@echo $(b) #输出为hello world!
5. \(续行符)
特点: 把多行变成一行。
a := Where does \
AIs intelligence \
come from?
debug:
@echo $(a)
#输出完整的一句话:Where does AIs intelligence come from?