首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

linux下静态库跟动态库的创建

2013-11-08 
linux下静态库和动态库的创建linux静态链接库与动态链接库的区别及动态库的创建标准库连接方式示例连接选

linux下静态库和动态库的创建
linux静态链接库与动态链接库的区别及动态库的创建标准库连接方式示例连接选项优点缺点全静态-static -pthread -lrt -ldl不会发生应用程序在 不同 Linux 版本下的标准库不兼容问题。生成的文件比较大,
应用程序功能受限(不能调用动态库等)全动态-pthread -lrt -ldl生成文件是三者中最小的比较容易发生应用程序在
不同 Linux 版本下标准库依赖不兼容问题。半静态 (libgcc,libstdc++)-static-libgcc -L. -pthread -lrt -ldl灵活度大,能够针对不同的标准库采取不同的链接策略,
从而避免不兼容问题发生。
结合了全静态与全动态两种链接方式的优点。比较难识别哪些库容易发生不兼容问题,
目前只有依靠经验积累。
某些功能会因选择的标准库版本而丧失。

上述三种标准库链接方式中,比较特殊的是 半静态链接方式,主要在于其还需要在链接前增加额外的一个步骤:
ln -s `g++ -print-file-name=libstdc++.a`,作用是将 libstdc++.a(libstdc++ 的静态库)符号链接到本地工程链接目录。
-print-file-name 在 gcc 中的解释如下:
-print-file-name=<lib> Display the full path to library <lib>

为了区分三种不同的标准库链接方式对最终生成的可执行文件的影响,本文从两个不同的维度进行分析比较:



图 2. 全动态标准库链接方式
linux下静态库跟动态库的创建

图 3. 半静态(libgcc,libstdc++) 标准库链接方式
linux下静态库跟动态库的创建


通过上述三图,可以清楚的看到,当用 全静态标准库的链接方式时,所生成的可执行文件最终不依赖任何的动态标准库,
全动态标准库的链接方式会导致最终应用程序可执行文件依赖于所有用到的标准动态库。
区别于上述两种方式的 半静态链接方式则有针对性的将 libgcc 和 libstdc++ 两个标准库非动态链接。
(对比 图 2与 图 3,可见在 图 3中这两个标准库的动态依赖不见了)

从实际应用当中发现,最理想的标准库链接方式就是半静态链接,通常会选择将 libgcc 与 libstdc++ 这两个标准库静态链接,
从而避免应用程序在不同 Linux 版本间标准库依赖不兼容的问题发生。



图 5. 全动态标准库链接方式
linux下静态库跟动态库的创建

图 6. 半静态(libgcc,libstdc++) 标准库链接方式
linux下静态库跟动态库的创建


通过上述三图可以看出,最终可执行文件的大小随最终所依赖的标准动态库的数量增加而减小。
从实际应用当中发现,最理想的是 半静态链接方式,因为该方式能够在避免应用程序于
不同 Linux 版本间标准库依赖不兼容的问题发生的同时,使最终生成的可执行文件大小最小化。


从 图 7中可以得知,CdtLog.a 只包含 CdtLog.o 一个对象文件 , 而 xml.a 包含 TXmlParser.o 和 xmlparser.o 两个对象文件
现将 CdtLog.o 提取出来,然后通过 图 8方式创建一个新的静态库 demo.a,可以看出,demo.a 包含的是 CdtLog.o 以及 xml.a,
而不是我们所预期的 CdtLog.o,TXmlParser.o 和 xmlparser.o。这正是区别于 Windows 下静态库的制作。


图 8. 示例静态库制作方式 1
linux下静态库跟动态库的创建

这样的 demo.a 当被链接入某个工程时,所有在 TXmlParser.o 和 xmlparser.o 定义的符号都不会被发现,从而会导致链接错误,
提示无法找到对应的符号。显然,通过图 8 方式创建 Linux 静态库是不正确的。

正确的方式有两种:

    将所有静态库中包含的对象文件提取出来然后重新打包成新的静态库文件。

    用一种更加灵活的方式创建新的静态库文件:ar 脚本

显然,方式 1 是比较麻烦的,因为涉及到太多的文件处理,可能还要通过不断创建临时目录用于保存中间文件。
推荐使用如 清单 2 createlib.sh所示的 ar 脚本方式进行创建:


清单 2 createlib.sh

1[root@backup kongch]# ldconfig2[root@backup kongch]# ./bank3$100

这种方式一劳永逸,不过需要有root权限。

废话这么多,只是因为好记性不如烂笔头。更详细,更准确的使用和描述,还是参见这里吧。


http://www.cnblogs.com/feisky/archive/2010/03/09/1681996.html


http://blog.csdn.net/ast_224/article/details/3988244


1楼u011960402昨天 12:24
写的蛮好的,代码使用代码那个编辑看起来会清晰很多

热点排行