后缀
- 静态库
.a
.lib
- 动态库
.so
.dll
g++/gcc编译选项
-o
指定输出目标的文件名-L
表示要链接的库所在目录-l
指定链接时需要的动态库,编译器查找动态库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.a或.so来确定库的名称。-shared
指定生成动态链接库-static
指定生成静态库-fPIC
表示编译为位置独立的代码,用于编译共享库-Wall
生成所有警告信息-ggdb
此选项将尽可能的生成gdb的可以使用的调试信息-g
编译器在编译的时候产生调试信息-c
只激活预处理、编译和汇编,也就是把程序做成目标文件,后缀为.o
静态库
静态链接:链接阶段,会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中。
- 静态库对函数库的链接是放在编译时期完成的;
- 程序在运行时与函数库再无瓜葛,移植方便;
- 浪费空间和资源,因为所有相关的目标文件与牵扯到的函数库被链接合成一个可执行文件。
linux下静态库命名规范必须是lib[name].a
,lib是前缀,是必须的,扩展名为.a
。
创建静态库
- 首先将代码编译成目标文件.o
g++ -c Test.cpp
- 通过ar工具将目标文件打包成.a静态文件
ar -crv libtest.a Test.o
动态库
动态库在程序编译时并不会被链接到目标代码中,而是程序运行时才被载入。不同的应用程序如果调用相同的库,那么在内存里只需要有一份被该共享库的实例,避免了内存上的浪费。
- 动态库把一些库函数的链接载入推迟到程序运行的时期;
- 抗原实现进程之间的资源共享;
- 将一些程序升级变得简单;
- 甚至可以真正做到链接载入完全由程序员在代码中控制。
调试帮助
nm 命令
nm命令可以打印出库中的涉及到的所有符合。
- 在库中被调用,但是没有在库中定义的,用U表示
- 在库中定义的函数,用T表示
- 弱态符合,用W表示,虽然在库中被定义,但是可能被其他库中的同名符合覆盖。
1 | nm libtest.h |
ldd 命令
ldd命令可以查看一个可执行程序依赖的共享库。
1 | ldd libtest.so |