linux共享库学习笔记(创建、加载)
2017-01-26 11:45
513 查看
一:含义
共享库以.so为后缀(shared object),应用程序执行期间被加载到内存,可同时被多个程序共享使用;
二:分类
real name:真正的库文件,包含库文件完整版本号(Major,Minor,Release);
soname:软链接名字,应用程序运行时使用,只包含共享库的主版本号(主版本号相同,函数接口一致),
因此应用程序的.dynamic段只记录共享库的soname,只要soname一致这个共享库就可以使用;
linker name:在编译链接时使用,gcc的-L选项应该指定为linker name所在目录;
三:创建共享库
1、生成目标文件,-fPIC(position-independent-coding)表示没有绑定具体地址(运行时才能确定),如需要调试,可添加-g选项;
2、生成动态库文件
生成soname为libcalc.so.1(只是指定,并未生成链接文件),real name为libcalc.so.1。
注:(1)前两步可合并 gcc -shared -fPIC -Wl,-soname,libcalc.so.1 -o libcalc.so.1.0 calc.c
(2)关于-Wa、-Wp、-Wl含义如下:
四:加载共享库
1、编译链接路径:编译时链接保证编译通过,该部分不同于静态链接,只是做一些基本的符号链接,不需要拷贝函数定义,搜索路径顺序如下;
(1)-L:指定链接时动态库的路径;
(2)LD_LIBRARY_PATH:指定链接路径;
(3)默认路径:/lib、/usr/lib、/usr/local/lib(有些系统不包含)
2、运行链接路径:程序运行时加载动态库的路径,搜索路径顺序如下:
(1)ELF可执行文件动态段中DT_PATH所指定路径。(编译目标代码时,对gcc加入链接参数-Wl,-rpath指定)
(2)LD_LIBRARY_PATH:指定动态库搜索路径;
(3)/etc/ld.so.cache中缓存的路径。可通过修改配置文件/etc/ld.so.conf中指定的搜索路径来改变;
(4)默认动态库搜索路径/lib,/usr/lib;
3、具体共享库形式
(1)含版本号的共享库,直接写:gcc -o main main.c -L. libcalc.so.1 -Wl,-rpath,./
(2)libxxx.so形式的共享库,写为-lxxx:gcc -o main main.c -L. -lcalc -Wl,-rpath,./
注:(1)C/C++程序里经常会调用到外部库函数,通过LD_LIBRARY_PATH指定共享库路径只适合调试阶段使用,且有时会与系统库冲突,此时我们可以使用第一种方法即编译时加上-Wl,-rpath,该路径会写入ELF文件中。比如gcc -o main main.c -L. libcalc.so.1 -Wl,-rpath,./,程序会在加载libcalc.so.1库时先在当前目录下搜索;
(2)通过ldd命令可查看具体使用的哪个路径下的库;
参考:
http://www.jianshu.com/p/aed2ba9be14f
http://www.linuxidc.com/Linux/2016-06/132669.htm
http://blog.csdn.net/v6543210/article/details/44809405
共享库以.so为后缀(shared object),应用程序执行期间被加载到内存,可同时被多个程序共享使用;
二:分类
real name:真正的库文件,包含库文件完整版本号(Major,Minor,Release);
soname:软链接名字,应用程序运行时使用,只包含共享库的主版本号(主版本号相同,函数接口一致),
因此应用程序的.dynamic段只记录共享库的soname,只要soname一致这个共享库就可以使用;
linker name:在编译链接时使用,gcc的-L选项应该指定为linker name所在目录;
//linker name lrwxrwxrwx 1 cdos chronos 16 1月 5 14:35 libtspi.so -> libtspi.so.1.2.0* //soname lrwxrwxrwx 1 cdos chronos 16 1月 5 14:35 libtspi.so.1 -> libtspi.so.1.2.0* //real name -rwxr-xr-x 1 cdos chronos 417272 1月 5 14:35 libtspi.so.1.2.0*
三:创建共享库
1、生成目标文件,-fPIC(position-independent-coding)表示没有绑定具体地址(运行时才能确定),如需要调试,可添加-g选项;
gcc -c -fPIC -o calc.o -g calc.c
2、生成动态库文件
gcc -shared -Wl,-soname,libcalc.so.1 -o libcalc.so.1.0 calc.o
生成soname为libcalc.so.1(只是指定,并未生成链接文件),real name为libcalc.so.1。
注:(1)前两步可合并 gcc -shared -fPIC -Wl,-soname,libcalc.so.1 -o libcalc.so.1.0 calc.c
(2)关于-Wa、-Wp、-Wl含义如下:
-Wa,<options> Pass comma-separated <options> on to the assembler -Wp,<options> Pass comma-separated <options> on to the preprocessor -Wl,<options> Pass comma-separated <options> on to the linker3、使用ldconfig生成soname文件
ldconfig -n ./
四:加载共享库
1、编译链接路径:编译时链接保证编译通过,该部分不同于静态链接,只是做一些基本的符号链接,不需要拷贝函数定义,搜索路径顺序如下;
(1)-L:指定链接时动态库的路径;
(2)LD_LIBRARY_PATH:指定链接路径;
(3)默认路径:/lib、/usr/lib、/usr/local/lib(有些系统不包含)
2、运行链接路径:程序运行时加载动态库的路径,搜索路径顺序如下:
(1)ELF可执行文件动态段中DT_PATH所指定路径。(编译目标代码时,对gcc加入链接参数-Wl,-rpath指定)
(2)LD_LIBRARY_PATH:指定动态库搜索路径;
(3)/etc/ld.so.cache中缓存的路径。可通过修改配置文件/etc/ld.so.conf中指定的搜索路径来改变;
(4)默认动态库搜索路径/lib,/usr/lib;
3、具体共享库形式
(1)含版本号的共享库,直接写:gcc -o main main.c -L. libcalc.so.1 -Wl,-rpath,./
(2)libxxx.so形式的共享库,写为-lxxx:gcc -o main main.c -L. -lcalc -Wl,-rpath,./
注:(1)C/C++程序里经常会调用到外部库函数,通过LD_LIBRARY_PATH指定共享库路径只适合调试阶段使用,且有时会与系统库冲突,此时我们可以使用第一种方法即编译时加上-Wl,-rpath,该路径会写入ELF文件中。比如gcc -o main main.c -L. libcalc.so.1 -Wl,-rpath,./,程序会在加载libcalc.so.1库时先在当前目录下搜索;
(2)通过ldd命令可查看具体使用的哪个路径下的库;
cdos@chronos:~/calc/dynamic$ ldd main linux-vdso.so.1 => (0x00007ffeba7ee000) libcalc.so.1 => ./libcalc.so.1 (0x00007fcaf56f3000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fcaf5313000) /lib64/ld-linux-x86-64.so.2 (0x000055871d6dd000)
参考:
http://www.jianshu.com/p/aed2ba9be14f
http://www.linuxidc.com/Linux/2016-06/132669.htm
http://blog.csdn.net/v6543210/article/details/44809405
相关文章推荐
- linux0.11学习笔记-技术铺垫-简单AB任务切换程序(2)-可加载执行其他程序的bootloader
- linux0.11学习笔记-技术铺垫-简单AB任务切换程序(2)-可加载执行其他程序的bootloader
- Linux netfilter 学习笔记 之六 ip层netfilter的filter表的创建及其hook函数分析
- 【Linux学习笔记】Linux动态共享对象(动态链接库)装载过程
- Linux程序设计学习笔记----System V进程通信(共享内存)
- [Linux网络编程学习笔记]FIFO的创建和使用
- LINUX编程学习笔记(十四) 创建进程与 父子进程内存空间
- Linux学习笔记——例说makefile 增加系统共享库
- linux 学习笔记--模块的加载与卸载
- linux学习笔记1:使用VM创建一台虚拟机
- Linux进程线程学习笔记:进程创建
- 【linux高级环境编程学习笔记三】共享内存通信
- 【Linux学习笔记】Linux动态共享对象(动态链接库)装载过程
- Linux学习笔记——例说makefile 增加自定义共享库
- 嵌入式linux的学习笔记-共享内存(六)
- Linux进程线程学习笔记:进程创建
- LINUX编程学习笔记(十四) 创建进程与 父子进程内存空间
- 【Linux】Shell学习笔记之二——文件和目录管理(创建、删除、复制、查看)
- Linux操作系统学习_用户进程之由新进程创建到可执行程序的加载
- Linux学习笔记——如何在交叉编译时使用共享库