预编译 ->编译->汇编->链接
流程介绍 预编译 阶段操作
- 展开头文件
- 替换宏
- 消除注释
结果:生成.i结尾的预处理文件
编译 阶段操作
源代码翻译成汇编代码
结果:生成.s结尾的汇编文件
汇编 阶段操作
将汇编文件翻译为二进制文件
结果:生成.c结尾的二进制文件
链接 阶段操作
将多个二进制文件与所需要的库连接起来
结果:生成可执行的二进制文件
gcc工作流程动图展示
可以通过一条语句直接生成二进制可执行文件
gcc xxx.c -o xxx //自动完成 预编译->编译->汇编->链接 gcc xxx.c //生成a.out 因为没有指定生成名gcc常用参数
| 参数 | 作用呢 |
|---|---|
| -E | 预处理指定文件,但不编译 |
| -S | 编译指定源文件但不汇编 |
| -c | 编译汇编指定源文件,但不链接 |
| -o [file1] [file2] 或[file2] -o [file1] | 将file2编译成file1 (-o后跟生成文件) |
| -I(大写i) | 指定include包含文件的搜索目录,使用场景:include包含的文件不在当前目录下,需要指定搜索目录 |
| -g | 生成调试信息 ,使用场景:gdb调试 |
| -D | 编译的时候指定一个宏, 使用场景: 控制日志输出 |
| -w | 不生成任何警告信息 |
| -Wall | 生成所有警告信息 |
| -On | n取值为1-3,表示编译器的优化级别,0表示没有优化,3优化级别最高 |
| -l | 编译时指定使用库, 使用场景:使用静态库/动态库 |
| -L | 指定搜索库路径 |
| -fPIC/fpic | 生成与位置无关的代码 |
| -shared | 生成共享目标文件 |
| -std | 指定C标准 ,windows一般默认为c99,linux默认GNU C,使用方法 -std=c99 |
本质:一个程序
作用:
- 便于传输
- 保护知识产权
Linux静态库命名格式:libxxx.a
Windows静态库命名格式:libxxx.lib
静态库生成方式:
- 将源文件转化为.o文件(汇编文件)
gcc -c xxx.c ....
- 创建静态库
ar rcs 静态库的名字(libxxx.a) 原材料(.o文件)
- 发布
头文件 (告诉用户如何使用) +静态库 (底层实现)
使用语法
gcc xxx.c -o xxx -L [库所在目录] -l [库名字(掐头去尾)] //掐头去尾指 若静态库名字为libxxx.a,则-l xxx即可动态库
动态库特点:
- 动态库有执行权限
- 动态库地址不定,加载到动态库加载区,使用的是相对地址
Linux静态库命名格式:libxxx.so
Windows静态库命名格式:libxxx.dll
动态库的生成方式
- 将源文件转化为.o文件(汇编文件)
gcc -c -fpic xxx.c...
- 生成动态库
gcc -shared [汇编文件] -o [动态库名]
- 发布
头文件 (告诉用户如何使用) +静态库 (底层实现)
使用语法
gcc xxx.c -L [库所在目录] -l [库名字(掐头去尾)] -o xxx //掐头去尾指 若静态库名字为libxxx.so,则-l xxx即可
动态库最终生成的可执行程序中不包含动态库的代码,使用的时候才加载,所以动态连接器会有一个搜索库的操作。
查看程序是否能搜索到动态库
ldd xxx
当动态连接器搜索不到动态库时有如下解决方法
动态链接器搜索次序:
- LD_LIBRARY_PATH环境变量
- /etc/ld.so.cache
- /lib 、/usr/lib
解决方法1
LD_LIBRARY_PATH=[动态库绝对路径]:$LD_LIBRARY_PATH
但是这种是临时的,不长久
长久的方法:
修改 用户级别 ~./bashrc 或者 系统级别的配置文件 /etc/profile
在配置文件后添加
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:[动态库绝对路径]
.~/.bashrc //让当前终端重新加载配置信息
解决方法2
通过修改ld.so.conf来间接修改 /etc/ld.so.cache
sudo vim /etc/ld.so.conf
#添加动态库的绝对路径
sudo ldconfig #ld.so.conf的数据更新到 /etc/ld.so.cache中
解决方法3
将动态库的软连接放到 /lib 目录或/usr/lib目录
#直接拷贝 sudo cp /xxx/xxx/libxxx.so /usr/lib #创建软连接(推荐) sudo ln -s /xxx/xxx/libxxx.so /usr/lib/libxxx.so动态库与静态库总结
静态库
| 优点 | 缺点 |
|---|---|
| 打包加载速度快 | 相同库文件可能在内存中被加载多次,浪费资源 |
| 发布程序无需提供库文件 | 程序迭代麻烦 |
动态库
| 优点 | 缺点 |
|---|---|
| 资源共享 | 加载速度慢 |
| 程序迭代升级简单 | 发布程序需要提供依赖的库 |
| 控制何时加载动态库 |
静态库使用场景:
源文件量小
动态库使用场景
源文件量大



