您的位置:首页 > 其它

进行有效编辑的七种习惯

2011-03-05 20:03 323 查看
第八章 Linux[/b]共享库的组织[/b]

1 [/b]共享库版本[/b]
共享库兼容性[/b]
导致C语言共享库ABI改变的行为有4:
(1) 导出函数行为改变
(2) 导出函数被删除
(3) 导出数据的结构发生改变
(4) 导出函数的接口发生改变
不同版本的编译器、操作系统和硬件平台都ABI兼容都有影响。

共享库版本命名[/b]
使用共享库版本是有效保证共享库兼容的方法之一。Linux的命名规则:libname.so.x.y.z[/b]
x主版本号:不同主版本号的库之间不兼容
y次版本号:增加一些新的借口,原来的符号不变
z发布版本号:库的一些错误的修正、性能的改进
C库由于历史原因,命名为libc-x.y.z.so,动态链接器ld-x.y.z.so

SO-NAME[/b]
在linux中,每个共享库都有一个对应的SO-NAME,这个SO-NAME即共享库的文件名去掉次版本号好发布版本号,保留主版本号。libname.so.x.y.zàlibname.so.x
C库的SO-NAME跟标准一样libc-x.y.z.soàlibc.so.x
动态链接器ld-x.y.z.soàld-linux.so.x
实际上SO-NAME是哥软链接,执行目录中主版本号相同,次版本号和发布版本号最新的共享库。
连接名:[/b]gcc中可以直接使用-lXXX,在相应的目录中搜索libXXX.so.x.y.z库的最新版本。

2 [/b]符号版本[/b]
使用共享库版本不能解决次版本号交会问题[/b]。于是引入了符号的版本机制。
当我们在构建(编译或者链接)应用程序时,链接器可以在程序的最终输出文件中记录下它所用到的版本号集合,注意:程序记录的不是构建时共享库中版本最新的符号集合,而是程序所依赖的集合中版本最小的那个。
在程序运行时,动态链接器会通过程序内记录的的它所依赖的所有共享库的符号集合版本信息,然后判定当前系统共享库符号版本是否满足这些被依赖的符号集合。

Linux[/b]中符号版本的实现[/b]
在linux下,可以如下将符号版本的信息传递到库中。
gcc -shared -fPIC lib.c -Xlinker --version-script lib.ver -o lib.so[/b]
lib.ver是一个符号脚本文件
VERS_1.2{
global:
foo;
local:
*;
};
即foo的符号版本为1.2
当引用这个库生成可执行文件时:
gcc main.c ./lib.so -o main[/b]
于是main中所引用的foo为VER_1.2。这个这个main程序拿到一台只包含地狱VER_1.2的foo的lib.so系统中运行,则会报错。
[/b]
3 [/b]共享库系统路径[/b]
目前大多数包括linux在内的开源操作系统都遵守FHS(File Hierarchy Standard)标准。标准规定,一个系统中主要有3个存放共享库的位置:
(1) /lib,存放系统关键和基础的共享库,如动态链接、C语言运行库和数学库。
(2) /usr/lib,非系统运行时所需要的关键库,如一些开发时用到的库
(3) /usr/local/lib,操作系统本身并不十分相关的库,主要是一些第三方应用程序库。

4 [/b]共享库查找[/b]
动态链接器会按照如下顺序依次装载或者查找共享库:
(1) 由环境变量LD_LIBRARY_PATH指定的路径
(2) 由路径缓存文件/etc/ld.so.cache指定的路径
(3) 默认共享目录,先/usr/lib,再/lib
ld.so.cache由/etc/ld.so.conf生成,ldconfig

5 [/b]环境变量[/b]
LD_LIBRARY_PATH
LD_PRELOAD
LD_DEBUG可以打开动态链接器的调试功能
[/b]
6 [/b]共享库的创建与安装[/b]
共享库的创建[/b]
gcc -shared -fPIC -Wl, -soname, my_soname -o library_name source_file library_files
-Wl将信息传递给链接器,这里表示建立SO-NAME
创建共享库注意事项:
(1) 不要输出共享库总的符号和调试信息去掉,也不要使用GCC的-fomit-frame-pointer,这会影响共享库的调试。
(2) 测试新的共享库,可以使用LD_LIBRARY_PATH或者-Wl,-rpath,没必要删掉原有的系统库。
(3) 如果库有对可执行文件的反向引用,则可执行文件用-Wl,-export-dynamic,这样原动态符号表不会被删减,dlopen()不会找不到所需的符号。

清除符号信息[/b]
$strip libfoo.so
gcc中使用-Wl,-S或者-Wl,-s
-S消除调试符号信息,-s消除所有符号信息
[/b]
共享库的安装[/b]
直接拷贝到/lib或者/usr/lib,运行ldconfig或者运行
$ldconfig -n shared_library_directory

共享库的构建与析构[/b]
GCC提供了一种共享库的构造函数和析构函数,只要在函数声明时加上如下的属性:
__attribute__((constructor))[/b]
__attribute__((destructor))[/b]
[/b]
共享库脚本[/b]
共享库可以是动态链接的ELF共享对象文件(.so),也可以是符合一定规则的链接脚本。与LD链接脚本非常相似。
GROUP( /lib/libc.so.6 /lib/libm.so.2)本文出自 “水手零八” 博客,请务必保留此出处http://lindo.blog.51cto.com/2053922/384521
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: