是否在构建时发生任何特定于静态链接的事情

Does anything happen at build time that is specific to static linking

本文关键字:静态 链接 于静态 构建 任何特 是否      更新时间:2023-10-16

我尝试使用链接器中的static选项静态链接一些构建的库。我正在使用SCons编译/链接库。我的印象是静态构建发生在链接时,因此链接什么并不重要。我遇到了一堆错误,想知道注定要静态链接到库的.o文件和注定要动态连接到库的-o文件之间是否有什么区别。从理论上讲,这些应该是一样的吗?

在一般情况下,不能互换使用静态库和动态库。参见:gcc 中共享库函数的静态链接

关于您的实际问题:

。。。如果指定要静态链接到库的.o文件和指定要动态链接到库中的-o文件之间有任何区别。从理论上讲,这些应该是一样的吗?

不,它们不应该相同。存在差异,最值得注意的可能是动态库有一个非空的.dynsym部分。

如果函数foo()静态链接到应用程序中,那么函数定义将位于相对于应用程序代码其余部分的固定(静态!)位置。

另一方面,如果我们将foo()动态链接到应用程序中,那么在编译时,应用程序无法知道在执行过程中在哪里可以找到foo()的定义,因为应用程序无法对库做出任何假设——无论是对库在运行时的位置,还是对其内部结构。因此,库本身提供了一个.dynsym部分,以便客户端代码能够找到foo的定义,尽管在编译时还不清楚它将在哪里

我对SCons了解不多,但据我所知,它与其他make系统相似,仍然执行相同的编译/链接步骤。链接的体系结构已经在Stack Overflow上有了很好的记录,所以我将尝试解释其中的差异。

由于静态库旨在在链接时将符号解析为可执行文件,因此它们不需要任何特殊的东西,因为解析是在编译时进行的。动态库需要特别考虑,因为它们是在运行时解析的,而链接器不知道如何使用它们。您将需要特殊的标志(例如,fPIC标志来生成可以在内存中任何地方运行的代码)。

因此,简短的回答是,是的,存在差异。据我所知,为动态链接生成的对象文件可以变成静态库(可能会有一些代码膨胀),但大多数为静态链接生成的目标文件不能用于动态链接,因为它们可能没有必要的标志。我通常(非正式地)认为它是一个静态库,就像另一个对象文件,而动态库就像一个独立的可执行文件,它只是挂接在其中(实际上更接近于共享库常用的ELF格式)。