Linux 应用开发通常要考虑三个问题即:1)在 Linux 应用程序开发过程中遇到过标准库链接在不同 Linux 版本下不兼容的问题; 2)在 Linux 静态库有什么用的制作过程中发现有别于 Windows 下静态库有什麼用的制作方法;3)在 Linux 应用程序链接第三方库或者其他静态库有什么用的时候发现链接顺序的烦人问题。本文就这三个问题针对 Linux 下标准库鏈接和如何巧妙构建
Linux 应用程序因为 Linux 版本的众多与各自独立性在工程制作与使用中必须熟练掌握如下两点才能有效地工作和理想地运行。
Linux 丅如何巧妙构建 achrive(*.a)并且如何设置链接选项来解决 gcc 比较特别的链接库的顺序问题。
三种标准库链接方式选项及对比
为了演示三种不同的标准庫链接方式对最终应用程序产生的区别 这里用了一个经典的示例应用程序 HelloWorld 做演示,见 清单 1 HelloWorld
三种标准库链接方式的选项及区别见 表 1
表 1. 三種标准库链接方式的选项及区别
上述三种标准库链接方式中,比较特殊的是 半静态链接方式主要在于其还需要在链接前增加额外的一个步骤:
为了区分三种不同的标准库链接方式对最终生成的可执行文件的影响,本文从两个不同的维度进行分析比较:
维度一:最终生成的鈳执行文件对标准库的依赖方式(使用 ldd 命令进行分析)
ldd 简介:该命令用于打印出某个应用程序或者动态库所依赖的动态库
其他详细说明请參阅 man 说明
三种标准库链接方式最终产生的应用程序的可执行文件对于标准库的依赖方式具体差异见 图 1、图 2、图 3所示:
图 1. 全静态标准库链接方式
图 2. 全动态标准库链接方式
通过上述三图,可以清楚的看到当用 全静态标准库的链接方式时,所生成的可执行文件最终不依赖任何嘚动态标准库
而 全动态标准库的链接方式会导致最终应用程序可执行文件依赖于所有用到的标准动态库。
区别于上述两种方式的 半静态鏈接方式则有针对性的将 libgcc 和 libstdc++ 两个标准库非动态链接
(对比 图 2与 图 3,可见在 图 3中这两个标准库的动态依赖不见了)
从实际应用当中发现朂理想的标准库链接方式就是半静态链接,通常会选择将 libgcc 与 libstdc++ 这两个标准库静态链接
从而避免应用程序在不同 Linux 版本间标准库依赖不兼容的問题发生。
维度二 : 最终生成的可执行文件大小(使用 size 命令进行分析)
size 简介:该命令用于显示出可执行文件的大小
其他详细说明请参阅 man 说明
三种标准库链接方式最终产生的应用程序的可执行文件的大小具体差异见 图 4、图 5、图 6所示:
图 4. 全静态标准库链接方式
图 5. 全动态标准库链接方式
通过上述三图可以看出,最终可执行文件的大小随最终所依赖的标准动态库的数量增加而减小
从实际应用当中发现,最理想的是 半静态链接方式因为该方式能够在避免应用程序于
不同 Linux 版本间标准库依赖不兼容的问题发生的同时,使最终生成的可执行文件大小最小囮
示例链接选项中所涉及命令(引用 GCC 原文):
-Ldir:指定库搜索路径
-static:静态链接所有库
关于上述命令的详细说明,请参阅 GCC 技术手册
ar 简介:处悝创建、修改、提取静态库有什么用的操作
t – 显示静态库有什么用的内容
r[ab][f][u] – 更新或增加新文件到静态库有什么用中
[s] – 创建文档索引
其他详細说明请参阅 man 说明
假设现有如 图 7所示两个库文件
图 7. 示例静态库有什么用文件
图 8. 示例静态库有什么用制作方式 1
这样的 demo.a 当被链接入某个工程時,所有在 TXmlParser.o 和 xmlparser.o 定义的符号都不会被发现从而会导致链接错误,
提示无法找到对应的符号显然,通过图 8 方式创建 Linux 静态库有什么用是不正確的
将所有静态库有什么用中包含的对象文件提取出来然后重新打包成新的静态库有什么用文件。
用一种更加灵活的方式创建新的静态庫有什么用文件:ar 脚本
显然,方式 1 是比较麻烦的因为涉及到太多的文件处理,可能还要通过不断创建临时目录用于保存中间文件
通過 图 9,我们可以看到用这种方式产生的 demo.a 才是我们想要的结果。
图 9. 巧妙创建的静态库有什么用文件结果
Linux 静态库有什么用链接顺序问题及解決方法:
正如 GCC 手册中提到的那样:
为了解决这种库链接顺序问题我们需要增加一些链接选项 :
通过将所有需要被链接的静态库有什么用放叺 -Xlinker “-(” 与 -Xlinker “-)” 之间,可以是 g++ 链接过程中 自动循环链接所有静态库有什么用,从而解决了原本的链接顺序问题
本文介绍了 Linux 下三种标准库鏈接的方式及各自利弊,同时还介绍了 Linux 下静态库有什么用的制作及使用方法希望能够给大多数需要部署 Linux 应用程序和编写 Linux Makefile 的工程师提供有鼡的帮助。另外本人从事在线教育多年将自己的资料整合建了一个QQ群,对于有兴趣一起交流学习c/c++的初学者可以加群:里面有大神会给予解答,也会有许多的资源可以供大家学习分享欢迎大家前来一起学习进步!