GCC工作流程及编译选项
gcc编译选项 | 说明 |
---|---|
-E | 预处理指定的源文件,不进行编译 |
-S | 编译指定的源文件,不进行汇编 |
-c | 编译、汇编指定的源文件,不进行链接 |
-o [file1] [file2] / [file1] -o [file2] | 将文件file2编译成可执行文件file1 |
-I [directory] | 指定include文件的搜索目录 |
-g | 在编译的时候,生成调试信息,该程序可以被调试器调试 |
-D | 在程序编译的时候,指定一个宏 |
-w | 不生成任何警告信息 |
-Wall | 生成所有的警告信息 |
-On | n取值0~3,为优化等级,-O0表示没有优化,-O1为缺省值,-O3优化级别最高 |
-l | 在程序编译的时候,指定使用的库 |
-L | 指定编译的时候,搜索库的路径 |
-fpic/fPIC | 生成与位置无关的代码 |
-shared | 生成共享目标文件,通常用在建立共享库时 |
-std | 指定编译标准,如-std=c++20 |
静态库制作和使用
命名规则
Linux:libxxx.a
1
2
3lib:固定前缀
xxx:库名
.a:固定后缀Windows:libxxx.lib
静态库的制作
- gcc设置编译选项-c获得.o文件
- 将.o文件打包,使用ar工具(archive)
1
2
3
4ar rcs libxxx.a xxx.o xxx.o
r - 将文件插入备存文件中
c - 建立备存文件
s - 索引
静态库的使用
编译时设置编译选项 -l [库名] 指定使用的静态库,-L [路径] 指定静态库查找路径。
动态库的制作和使用
命名规则
Linux:libxxx.so
1
2
3
4lib:固定前缀
xxx:库名
.so:固定后缀
在Linux下动态库是可执行文件Windows:libxxx.dll
动态库的制作
gcc得到.o文件,要设置与位置无关
1
gcc -c -fpic/fPIC file1.c file2.c
gcc得到动态库
1
gcc -shared file1.o file2.o -o libcalc.so
动态库的使用
与静态库不同,动态库不会将库中的代码打包到可执行文件中,而是保存动态库的相关信息,在程序运行时将动态库加载到内存里。
系统加载可执行代码的时候能够知道依赖的库名,但还需要知道绝对路径,该路径需要从系统的动态载入器获取。对于elf格式的可执行程序,是由ld-linux.so来完成的,搜索顺序为 DT_RPATH段$\to$环境变量LD_LIBRARY_PATH$\to$/etc/ld.so.cache文件列表$\to$/lib/,/usr/lib/,找到库文件后将其载入内存。
添加环境变量的命令为1
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:动态库所在的绝对路径
临时添加环境变量只需在终端中输入命令,用户级永久化需要在根目录下.bashrc文件最后添加以上命令,然后输入以下指令以启用配置。1
2
3source .bashrc
或
. .bashrc
Makefile文件命名和规则
文件命名
makefile或者Makefile
Makefile规则
一个Makefile文件中可以有一个或者多个规则
- 目标:最终要生成的文件(伪目标除外)
- 依赖:生成目标所需要的文件或目标
- 命令:通过执行命令对依赖操作生成目标(命令前必须Tab缩进)
1
2
3目标 ...: 依赖 ...
命令(Shell 命令)
...
Makefile中的其它规则一般都是为第一条规则服务的
- 命令在执行前,需要先检查规则中的依赖是否存在
- 如果存在,执行命令
- 如果不存在,向下检查其他规则,检查有没有一个规则是用来生成该依赖的,如果找到了,则执行该规则中的命令
检测更新,在执行规则中的命令时,会比较目标和依赖文件的时间
- 如果依赖的时间比目标的时间晚,需要重新生成目标
- 如果依赖的时间比目标的时间早,目标不需要更新,对应规则中的命令不需要被执行
自定义变量
变量名=变量值- 预定义变量(只能在规则的命令中使用)
AR:归档维护程序的名称,默认值为ar
CC:C编译器的名称,默认值为cc
CXX:C++编译器的名称,默认值为g++
\$@:目标的完整名称
\$<:第一个依赖文件的名称
\$^:所有的依赖文件 - 获取变量的值
$(变量名) - 模式匹配
对于目标和依赖,使用%通配符表示一个字符串,如%.o:%.c - 伪目标
1
2.PHONY:目标
声明目标为伪目标
函数
$(wildcard PATTERN…)
- 功能:获取指定目录下指定类型的文件列表
- 参数:PATTERN指的是某个或多个目录下的对应的某种类型的文件,如果有多个目录,一般使用空格间隔
- 返回:得到的若干个文件的文件列表,文件名之间使用空格间隔
- 示例:
1
2$(wildcard *.c ./sub/*.c)
返回值格式:a.c b.c c.c
$(patsubst \
,\ ,\ ) - 功能:查找\
中的单词(单词以“空格”、“Tab”、“回车”或“换行”分隔)是否符合模式\ ,如果匹配的话,则以\ 替换 - \
可以包括通配符%,表示任意长度的字符串。如果\ 中也包含%,那么两个%的值将相同。 - 返回:函数返回被替换过后的字符串
- 示例:
1
2$(patsubst %.c, %.o, x.c bar.c)
返回值格式:x.o bar.o
- 功能:查找\