您的位置:首页 > 运维架构 > Linux

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所在目录;

//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 linker
3、使用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








                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: