Makefile文件的一些说明

 最近接触了一下linux运行make生成so的过程,总结了一些关于Makefile的符号含义说明。 
 linux 执行make之后的过程: 
 读取当前目录下的 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 定义该宏引起执行一些轻质检查采用各种串和存储器操作功能时,以检测某些缓冲区溢出的错误。
 
 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的文件里面。
posted @ 2020-04-22 15:54  linguinost  阅读(484)  评论(0编辑  收藏  举报