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).lddldd,列出某个程序依赖的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/