最近接触了一下linux运行make生成so的过程,总结了一些关于Makefile的符号含义说明。
linux 执行make之后的过程:
读取当前目录下的 Makefile 文件,并将 Makefile 文件中的第一个目标作为其执行的“终极目标”,开始处理第一个规则(终极目标所在的规则)。
按顺序处理依赖文件,不存在则根据依赖文件的创建规则创建,存在且源文件更新则重新创建,源文件未更新则不变。
一般格式为:
目标:依赖文件
规则
读取当前目录下的 Makefile 文件,并将 Makefile 文件中的第一个目标作为其执行的“终极目标”,开始处理第一个规则(终极目标所在的规则)。
按顺序处理依赖文件,不存在则根据依赖文件的创建规则创建,存在且源文件更新则重新创建,源文件未更新则不变。
一般格式为:
目标:依赖文件
规则
需要制定准确的文件依赖关系规则,否则会出错。一般Makefile文件的编写是通过定义变量和函数,通用地编译多个文件。
CFLAGS、CXXFLAGS 编译器的选项,涵盖编译和汇编过程,前者为C,后者为C++。
定义变量名如SRC=one two three,使用$(SRC)来进行替换。
递归赋值 = 变量以最终一个为准,前面即使是其他值也被替换为最终值
简单赋值 := 变量为当前值,不受最终值影响
追加赋值 += 间隔空格追加
条件赋值 ?= 变量未定义则赋值,已定义则跳过
$@ --代表目标文件(target)
$^ --代表所有的依赖文件(components)
$< --代表第一个依赖文件(components中最左边的那个)。
$% --仅当目标是函数库文件中,表示规则中的目标成员名。
比如:编译全部.c
test:*.c
gcc -o $@ $^
wildcard 这个函数在我们引用变量的时候,会帮我们展开。
比如:
OBJ=$(wildcard src/*.c)
test:$(OBJ)
gcc -o $@ $^
strip 去除多余空格的函数和调试信息,可以隐藏未指定暴露的函数。
CFLAGS的参数:
O2 编译器优化级别
-fPIC 编译阶段,用于生成动态库,编译器输出位置无关目标码,适用于动态连接,在多进程时共享同一份程序。
-g 产生调试信息,给调试器用,可以用-g3这个级别可以调试宏;如果调试器是gdb,建议使用-ggdb或者-ggdb3。
-pipe 编译会有几个阶段,每个阶段生成临时文件给下一个阶段使用,使用这个选项避免了文件读写而使用管道在内存中进行。
-Wshadow 当局部变量覆盖全局变量时,会警告。
-Wpointer-arith 对函数指针或者void *类型的指针进行算术操作时给出警告。
-Wl,-soname 是为了提高新老版本库的兼容性,通过soname指定我们所希望的库版本。
-D_GNU_SOURCE Linux下的信号量/读写锁文件进行编译。
-D_FORTIFY_SOURCE 定义该宏引起执行一些轻质检查采用各种串和存储器操作功能时,以检测某些缓冲区溢出的错误。
O2 编译器优化级别
-fPIC 编译阶段,用于生成动态库,编译器输出位置无关目标码,适用于动态连接,在多进程时共享同一份程序。
-g 产生调试信息,给调试器用,可以用-g3这个级别可以调试宏;如果调试器是gdb,建议使用-ggdb或者-ggdb3。
-pipe 编译会有几个阶段,每个阶段生成临时文件给下一个阶段使用,使用这个选项避免了文件读写而使用管道在内存中进行。
-Wshadow 当局部变量覆盖全局变量时,会警告。
-Wpointer-arith 对函数指针或者void *类型的指针进行算术操作时给出警告。
-Wl,-soname 是为了提高新老版本库的兼容性,通过soname指定我们所希望的库版本。
-D_GNU_SOURCE Linux下的信号量/读写锁文件进行编译。
-D_FORTIFY_SOURCE 定义该宏引起执行一些轻质检查采用各种串和存储器操作功能时,以检测某些缓冲区溢出的错误。
LDFLAGS 是传递给链接器的选项。
格式为-Wl,XX 选项传递给链接器。
-Wl,--hash-style=gnu 使用gnu风格的符号散列表格式。
-Wl,--no-undefined 如果so里有未定义符号,编译不通过。
-shared 生成共享目标。
-Wl,-Bsymbolic-functions so中的符号都不会被外部所调用,原本通过plt/got调用的函数改为直接通过相对地址调用,结合version_script选择导出函数。
-Wl,--version-script=$(LIBSCRIPTS) 使用version_script来明确指定哪些符号要使用本地的(完成静态链接),哪些不限定本地(走符号表)。
-Wl,--as-needed 忽略链接时没有用到的动态库。
-Wl,--allow-shlib-undefined 允许在动态库中存在未解析到的函数。
-shared-libgcc 链接动态库libgcc。
-MMD 生成文件关联的信息,输出将导入到.d的文件里面。
格式为-Wl,XX 选项传递给链接器。
-Wl,--hash-style=gnu 使用gnu风格的符号散列表格式。
-Wl,--no-undefined 如果so里有未定义符号,编译不通过。
-shared 生成共享目标。
-Wl,-Bsymbolic-functions so中的符号都不会被外部所调用,原本通过plt/got调用的函数改为直接通过相对地址调用,结合version_script选择导出函数。
-Wl,--version-script=$(LIBSCRIPTS) 使用version_script来明确指定哪些符号要使用本地的(完成静态链接),哪些不限定本地(走符号表)。
-Wl,--as-needed 忽略链接时没有用到的动态库。
-Wl,--allow-shlib-undefined 允许在动态库中存在未解析到的函数。
-shared-libgcc 链接动态库libgcc。
-MMD 生成文件关联的信息,输出将导入到.d的文件里面。