Board logo

标题: Linux 动态库与静态库制作及使用详解 [打印本页]

作者: yuyang911220    时间: 2015-7-28 20:15     标题: Linux 动态库与静态库制作及使用详解

标准库的三种连接方式及静态库制作与使用方法
                                                                 Linux 应用开发通常要考虑三个问题,即:1)在 Linux 应用程序开发过程中遇到过标准库链接在不同 Linux 版本下不兼容的问题; 2)在 Linux 静态库的制作过程中发现有别于 Windows 下静态库的制作方法;3)在 Linux 应用程序链接第三方库或者其他静态库的时候发现链接顺序的烦人问题。本文就这三个问题针对 Linux 下标准库链接和如何巧妙构建 achrive(*.a) 展开相关介绍。
两个要知道的基本知识       Linux 应用程序因为 Linux 版本的众多与各自独立性,在工程制作与使用中必须熟练掌握如下两点才能有效地工作和理想地运行。         
三种标准库链接方式选项及对比为了演示三种不同的标准库链接方式对最终应用程序产生的区别,这里用了一个经典的示例应用程序 HelloWorld 做演示,见 清单 1 HelloWorld。整个工程可以在文章末尾下载。                 
清单 1. HelloWorld #include <stdio.h>  #include <iostream>  using std::cout;  using std::endl;  int main(int argc, char* argv[])  {   printf("HelloWorld!(Printed by printf)\n");   cout<<"HelloWorld!(Printed by cout)"<<endl;   return 0;  }
三种标准库链接方式的选项及区别见 表 1
表 1. 三种标准库链接方式的选项及区别标准库连接方式示例连接选项优点缺点全静态-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>      
为了区分三种不同的标准库链接方式对最终生成的可执行文件的影响,本文从两个不同的维度进行分析比较:
维度一:最终生成的可执行文件对标准库的依赖方式(使用 ldd 命令进行分析) ldd 简介:该命令用于打印出某个应用程序或者动态库所依赖的动态库
涉及语法:ldd [OPTION]...  FILE...
其他详细说明请参阅 man 说明。         
三种标准库链接方式最终产生的应用程序的可执行文件对于标准库的依赖方式具体差异见 图 1图 2图 3所示:                         
图 1. 全静态标准库链接方式图 2. 全动态标准库链接方式图 3. 半静态(libgcc,libstdc++) 标准库链接方式
通过上述三图,可以清楚的看到,当用 全静态标准库的链接方式时,所生成的可执行文件最终不依赖任何的动态标准库,
全动态标准库的链接方式会导致最终应用程序可执行文件依赖于所有用到的标准动态库。
区别于上述两种方式的 半静态链接方式则有针对性的将 libgcc 和 libstdc++ 两个标准库非动态链接。
(对比 图 2图 3,可见在 图 3中这两个标准库的动态依赖不见了)           
从实际应用当中发现,最理想的标准库链接方式就是半静态链接,通常会选择将 libgcc 与 libstdc++ 这两个标准库静态链接,
从而避免应用程序在不同 Linux 版本间标准库依赖不兼容的问题发生。          
维度二 : 最终生成的可执行文件大小(使用 size 命令进行分析) size 简介:该命令用于显示出可执行文件的大小
涉及语法:size objfile...
其他详细说明请参阅 man 说明。          
三种标准库链接方式最终产生的应用程序的可执行文件的大小具体差异见 图 4图 5图 6所示:                         
图 4. 全静态标准库链接方式图 5. 全动态标准库链接方式图 6. 半静态(libgcc,libstdc++) 标准库链接方式
通过上述三图可以看出,最终可执行文件的大小随最终所依赖的标准动态库的数量增加而减小。
从实际应用当中发现,最理想的是 半静态链接方式,因为该方式能够在避免应用程序于
不同 Linux 版本间标准库依赖不兼容的问题发生的同时,使最终生成的可执行文件大小最小化。




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0