转载自:https://blog.csdn.net/imxiangzi/article/details/45871949/
Linux 库分类
目前可以创建两种 Linux C/C++ 库:
静态库(.a):会被链接进目标代码,并成为应用程序的一部分。
动态共享链接库(.so):这种库只有一种结构,不过可以通过两种方式使用。
I. 运行时动态链接但是静态依赖,在编译/链接阶段这些库需要存在,共享库不会包含到可执行文件中,但是需要在运行时绑定。
II. 在执行过程中使用动态加载链接系统函数进行动态加载/卸载和链接(比如:浏览器插件)。
库命名规范
库通常使用 ‘lib’ 作为命名前缀,这适用于所有 C 标准库。当链接时,在命令行中引用该库将不需要包含该库的前缀或后缀。
考虑下面的链接命令:
gcc src-file.c -lm -lpthread
这个例子中,在链接时需要 math 库和 thread 库,他们保存在 /usr/lib/libm.a 和 /usr/lib/libpthread.a 中。
静态库
如何创建一个静态库(目标代码归档文件):
- 编译
gcc -Wall -c calc_*.c /*编译成*.o中间文件*/
- 创建静态库
ar -cvq libcalc.a calc_*.o /*打包生成*.a静态库文件*/
- 列出静态库中的文件
ar -t libcalc.a
- 静态库的使用
gcc -o calc calc.c libcalc.a /*链接同目录/系统目录下的静态库*/
gcc -o calc calc.c libcalc.a -L/path/to/lib -lcalc /*链接其他目录的静态库*/
动态库
如何创建一个动态库(动态链接对象库文件):
- 编译
gcc -Wall -fPIC -c calc_*.c /*编译与地址无关的*.o中间文件*/
- 创建动态库
gcc -shared -Wl,-soname,libcalc.so.1 -o libcalc.so.1.0.1 *.o
- 创建链接
ln -s /path/to/lib/libcalc.so.1.0.1 /path/to/lib/libcalc.so.1
ln -s /path/to/lib/libcalc.so.1 /path/to/lib/libcalc.so
编译器选项
- Wall:包含警告,请查看 man pages 获得更详细信息。
- fPIC:编译器指令,输出位置无关的代码。
- shared:生成可以在运行时链接到其他应用程序的共享库。
- Wl, options:向链接器传递选项,在这里我们传递里链接器的选项是 -soname libctest.so.1。
- -o 选项:输出操作,在这个例子中共享库的名字将保存为 ‘libctest.so.1.0’。
库符号链接:
编译选项 -lcalc 会使用 libcalc.so 符号链接,运行时绑定会使用libctest.so.1。
编译使用动态链接库的主程序
gcc -Wall -I/path/to/include-files -L/path/to/libraries calc.c -lcalc -o Calc
/*这时库目录中需要有libcalc.so文件,否则编译不过。*/
列出依赖信息:
使用ldd命令可以列出应用程序依赖的共享库信息。
ldd Calc
linux-vdso.so.1 => (0x00007ffe8ffd8000)
libcalc.so.1 => /home/jinzhu/WorkSpace/Calc/libcalc.so.1 (0x00007f03dcdca000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f03dca00000)
/lib64/ld-linux-x86-64.so.2 (0x00007f03dcfcc000)
## 程序的运行
程序运行时需要确保系统能够找个相应的动态链接库。
//找不到库文件的情况
./Calc
./Calc: error while loading shared libraries: libcalc.so.1:
cannot open shared object file: No such file or directory
库路径问题
为了让可执行程序在运行时能找到需要链接的库,需要配置系统使得这些库可以被找到,有以下方法(至少需要其中一种方法):
1. 将包含动态链接库目录的路径加到 /etc/ld.so.conf 文件中。将路径加入到这个文件后需要执行 ldconfig 命令(以 root 账号)来配置链接器运行时绑定。
2. 增加指定目录到库缓存(需要 root 权限):ldconfig -n /opt/lib
。其中 /opt/lib 是包含 libcalc.so 文件的目录。这种方式不会永久在系统中包含相关目录,在系统重启后配置信息会丢失。
3. 配置环境变量 LD_LIBRARY_PATH 执行包含共享库的路径,这可以指定运行时加载器使用该路径解决依赖关系,几种系统的环境变量名称:
示例(bash shell ~/.bashrc ):
if [ -d /opt/lib ];
then
LD_LIBRARY_PATH=/opt/lib:$LD_LIBRARY_PATH
fi
export LD_LIBRARY_PATH