[C/C++]: 浅谈share library

1.关于so的三个名字

soname: version number,由ldconfig -n $library_directory生成,程序加载依赖的名字,

library安装好之后,根据realname生成soname

realname: soname的基础上增加minor number和release number

linkername: 以so结尾,没有version number,也没有minor number和release number,

ldconfig对于开发程序时你要链接的library不做出任何假定,不会自动生成linkername

有如下的指向关系

soname -> realname

linkername -> realname

例子如下所示

soname      ----> /usr/lib/libreadline.so.3 -> /usr/lib/libreadline.so.3.0

realname    ----> /usr/lib/libreadline.so.3.0

linkername  ----> /usr/lib/libreadline.so   -> /usr/lib/libreadline.so.3

所以一般的情况是

linkername -> soname -> realname

2.在文件系统当中的位置

(1).对于GNU standards的对顶,规定发布源代码的时候

/usr/local/lib

/usr/local/bin

(2).对于FHS standards的规定

/lib            ------> 系统启动所需要的

/usr/lib        ------> 大部分的libraries

/usr/local/lib  ------> 不属于系统部分的libraries

(3).其他的特例library的分布

/usr/X11R6/lib  ------> X-window

/lib/security   ------> PAM modules

/usr/libexec    ------> 只能通过libraries调用的programs

/usr/local/libexec ---> 只能通过libraries调用的programs

3.如何使用

执行一个ELF文件的时候,program loader(/lib/ld-linux.so.X,程序加载器)寻找并加载ELF

文件所需要的所有libraries,搜寻的目录在/etc/ld.so.conf当中指定

/etc/ld.so.preload文件当中指示那些预加载的,优先级高于一般libraries的库

为了提高加载效率,不用每次执行一个程序都去搜索,便有了文件/etc/ld.so.cache

每次有新的libraries加入或者删除一些libraries,都应该运行ldconfig,更新

文件/etc/ld.so.cache

4.相关的环境变量

(1).LD_LIBRARY_PATH,指定在标准的libraries目录之前,首先搜寻的libraries目录。

(2).LD_PRELOAD,这个变量的作用类似于/etc/ld.so.preload

对于LD_LIBRARY_PATH,主要用来development和testing使用。在HP-UX用的是SHLIB_PATH,在AIX当中用的是LIBPATH

有一篇文章说,"Why LD_LIBRARY_PATH is Bad",这个值得看看。

对于setuid和setgid的EFL程序,LD_LIBRARY_PATH是被忽略的。

/lib/ld-linux.so.2 --library-path PATH EXECUTABLE

上面在ELF文件执行的时候,指定PATH。

(3).LD_DEBUG=files/libs/bindings/versions/help

通过这个变量的设置会显示share library函数调用时候的更加详细信息

(4).其它变量的处理

最好参看program loader的源代码,在Linux系统当中,也就是/etc/ld-linux.so.X的源代码

5.相关的操作工具

(1).ldconfig

/etc/ld.so.conf

/etc/ld.so.cache

(2).ldd

ldd,列出某个程序依赖的shared library,不要对某个不信任的程序进行ldd,因为ldd的工作方式是

首先,设置某个变量,LD_TRACE_LOADED_OBJECTS

然后,执行这个程序

6.动手实践操作

(1).建立自己的share library

$ gcc -fPIC -g -c a.c

$ gcc -fPIC -g -c b.c

$ gcc -shared -Wl,-soname,libmystuff.so.1 -o libmystuff.so.1.0.1 a.o b.o -lc

$ ldconfig -n .

建立mystuff.h,里面extern一些函数

(2).建立用于测试的程序

测试程序,包含mystuff.h,然后就可以调用里面的函数

寻找某个linkername,依次顺序是

-L参数指定 --> LIBRARY_PATH指定 --> /usr/local/lib和/usr/lib

$ gcc test.c -L . -lmystuff

或者这样子

$ LIBRARY_PATH=.:$LIBRARY_PATH gcc test.c -lmystuff

(3).运行测试程序

$ LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH a.out

否则,会出现无法找到某个share library的运行错误

7.关于static library

1.代码连接到可执行程序当中

2.执行速度比shared library快1-5%

3.ar rcs my_library.a file1.o file2.o

8.参考

http://tldp.org/HOWTO/Program-Library-HOWTO/

你可能感兴趣的:([C/C++]: 浅谈share library)