MakeFile:
基本格式:
target : prerequisties
[tab键]command
- target:目标文件,可以是ObjectFile,也可以是执行文件,还可以是一个标签(Label),对于标签这种特性,在后续的“伪目标”章节中会有叙述
- prerequisties : 要生成那个target所需要的文件或是目标。
- command:是make需要执行的命令
Makefile规则:
- make会在当前目录下找到一个名字叫做Makefile或者makefile的文件
- 如果找到,他会找文件中第一个目标文件(target),并把这个文件作为最终的目标文件。
- 如果target不存在,或者target依赖的.o文件的修改时间要比这个target文件新,就会执行后面所定义的命令command来生成target这个文件。
- 如果target依赖的.o也存在make会在当前文件中找到target为.o文件的依赖性,再根据那个规则生成.o文件
伪目标:
-
“伪目标”不是一个文件,只是一个标签(可以理解为命令)。我们要显示的指明这个“目标”才能让其生效
-
“伪目标”的取名不能和文件名重名,否则不会执行命令
-
因此为了避免和文件重名的情况,我们可以使用一个特殊的标记.PHONY来显示地指明一个目标是“伪目标”,向make说明,不管是否有这个文件,这个目标就是“伪目标”
.PHONY : clean
Makefile的变量:
变量在声明时就要给予初值,而在使用时,需要给在变量名前加上$符号,并用小括号()把变量包起来。
-
变量的定义
cpp := src/main.cpp obj := objs/main.o
-
变量的引用
$(obj) : ${cpp} @gcc -c $(cpp) -o $(obj) compile : $(obj)
-
预定义变量
- $@:目标(target)的完整名称
- $<:第一个依赖文件的名称
- $^:所有依赖文件,以空格分开,不包含重复的依赖文件
cpp := src/main.cpp obj := objs/main.o $(obj) : ${cpp} @gcc -c $< -o $@ @echo $^ compile : $(obj) .PHONY complie
Makefile常用符号:
-
=
- 简单的赋值运算
- 用于将右边的值分配给左边的变量
- 如果在后面的语句中重新定义了该变量,则将使用新的值
HOME = src/main.c HOME = a debug : @echo $(HOME) # HOME的值会被覆盖当运行make debug后会输出a
-
:=
- 立即赋值运算符
- 用于在定义变量时立即求值
- 该值在定义后不再更改(此处不能那个更改为,符号右边为变量引用)
HOME := src/main.c TEST := $(HOME) HOME := a debug : @echo $(TEST) $(HOME)
-
?=
- 默认赋值运算符
- 如果变量已定义,则不用进行任何操作
- 如果变量尚未定义,则求值并分配
-
累加+=
CXXFLAGS := -m64 -fpic -g CXXFLAGS += -O0 debug : @echo $(CXXFLAGS)
-
\
- 续行符
L := asdasdasdasdasdasdada\ fgfgfdgdd\ asdafgdfgf # 上述变量L的值为:asdasdasdasdasdasdadafgfgfdgddasdafgdfgf
-
*与%
*
:通配符表示匹配任意的字符串,可以用在目录名或文件名中%
:通配符表示匹配任意字符串,并将匹配到的字符串作为变量使用
makefile常用函数:
-
函数的调用与变量的使用非常相似,也是以"$"来标识,语法:
$(fn,args)or${fn,args}
shell
$(shell <command> <args>)
- 名称:shell命令函数——shell
- 功能:调用shell 命令command
- 返回值:执行shell命令的结果
示例
# shell 指令,src 文件夹下找到 .cpp 文件
cpp_srcs := $(shell find src -name "*.cpp")
# shell 指令, 获取计算机架构
HOST_ARCH := $(shell uname -m)
subst
$(subst <from>,<to>,<text>)
- 作用:对
所指的字符串中的字符串替换为中的字符串 - 返回:替换后的字符串
patsubst
$(patsubst <pattern>,<replacement>,<text>)
- 作用:从 text 中取出 patttern, 替换成 replacement
- 返回:函数返回被替换过后的字符串
区别:subst与patsubst的区别为:patsubst可进行模式字符串匹配,即可以使用%来匹配
foreach
$(foreach <var>,<list>,<text>)
- 把字串<list>中的元素逐一取出来,执行<text>包含的表达式
- 返回:<text>所返回的每个字符串所组成的整个字符串(以空格分隔)
示例
library_paths := /datav/shared/100_du/03.08/lean/protobuf-3.11.4/lib \
/usr/local/cuda-10.1/lib64
library_paths := $(foreach item,$(library_paths),-L$(item))
I_flag := $(include_paths:%=-I%) #等价上面的那一句,foreach另一种形式
dir
$(dir <names...>)
- 功能:
- 从文件名序列中取出目录部分。目录部分是指最后一个反斜杠(“/”)之前
的部分。如果没有反斜杠,那么返回“./”。 - 返回:返回文件名序列的目录部分。
notdir
$(notdir <names...>)
- 功能:与dir相反,他提取的是文件名,而非目录名
- 返回:返回文件名
wildcard
$(wildcard PATTERN……)
-
功能:获取指定模式的文件列表。它的主要作用是帮助你获取符合特定模式的文件名,然后在构建过程中使用这些文件。
-
返回:匹配到的文件名
*与%的使用区分:
*
通配符在文件名模式匹配和wildcard
函数中使用,用于匹配任意字符序列。%
通配符主要用于模式规则(Pattern Rules)和patsubst
函数中,用于在规则和字符串替换中表示通配符。
makefile编译可执行文件实例:
参考博客:https://blog.csdn.net/weixin_51633491/article/details/132218249