我需要静态库才能进行静态链接吗?

10

在'C'和Linux中,我是否需要静态链接的静态库,或者我已有的共享库就足够了? 如果不是,为什么?(它们不包含相同的数据吗?)

4个回答

11

是的,构建静态链接的可执行文件需要静态库。

静态库是编译对象的捆绑。当您与库进行静态链接时,实际上相当于将该库的编译结果解包到当前项目中,并将其用作自己的对象。

动态库已经被链接。这意味着一些信息(例如重定位)已经被修复并抛弃了。

此外,动态库必须编译为位置独立代码。这不是静态库的限制,并且在某些常见平台(如x86)上会导致性能显着差异。

存在像ELF Statifier这样的工具,试图将动态链接库捆绑到动态链接可执行文件中,但在所有情况下生成正确工作的结果非常困难。


1
感谢您的优秀答案。但是为什么它这么难呢? - Liran Orevi
2
ELF Statifier会加载可执行文件及其所有库,然后对进程内存进行快照。当运行输出映像时,任何可能导致内存布局改变的因素(例如随机化VDSO)都会导致不正确的操作。任何其他方法都需要重新发明动态链接器。 - ephemient
1
为什么重新实现动态链接器会很难呢? 难道不只是重定位库的导入和导出表中的两个表格吗? 它是链接器, 所以它已经在实现静态链接器, 它知道可执行文件和动态库的文件格式等。 - ChrisW
2
静态(编译时)链接器和动态(运行时)链接器的操作非常不同。 静态链接器将对象中对符号的引用重写为固定引用——要么是在同一映像内重新定位的符号,要么是跳转到符号表中正确条目的存根。 动态链接器打开文件并将它们映射到内存的各个部分,填充符号表,然后跳转到初始化代码,具有特定规则。 - ephemient
当使用-bstatic选项时,共享对象会被静态链接到输出文件中。当使用-bdynamic选项时,共享对象会被动态链接。(aix) - nahzor

6

不存在静态编译,只有静态链接。为此,您需要静态库。 静态链接和动态链接的区别在于前者可以在链接时间(编译时间后)解决名称,而后者则在程序开始运行时解决名称。

静态库和动态库可能包含相同的信息,这取决于很多因素。 在选择是静态链接还是动态链接您的代码时非常重要,这通常会影响应用程序架构。


2

你将链接到静态链接程序的所有库都必须是静态变体。虽然动态(libfoo.so)和静态(libfoo.a)库中都有相同的函数,但它们是不同的格式文件,因此您需要匹配类型的程序。


1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接