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

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

我尝试使用 linker 中的静态选项静态 link 一些构建的库。我正在使用 SCons compile/link 库。我的印象是静态构建发生在 link 时间,因此你 linking 什么并不重要。我遇到了一堆错误,想知道注定要静态 linked 到库的 .o 文件和注定要动态 linked 到库的 .o 文件之间是否有任何区别图书馆。从理论上讲,这些应该相同吗?

我对 SCons 了解不多,但据我所知,它与其他 make 系统相似,并且仍然执行相同的 compiling/linking 步骤。链接的架构已经是well documented on Stack Overflow,所以我会尝试解释不同之处。

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

所以简短的回答是,是的,存在差异。据我所知,为动态链接生成的目标文件可以转换为静态库(具有共享库常用的某些 possible code bloat), but most object files made for static linking can't be used for dynamic linking since they probably don't have the necessary flags. I usually think of it (informally) as a static library being like another object file, while a dynamic library is like a standalone executable that is just hooked into (which is actually closer to the ELF 格式)。

在一般情况下,您不能交替使用静态库和动态库。参见:Static link of shared library function in gcc

关于您的实际问题:

... if there is any difference between .o files that were destined to be statically linked to the libraries and .o files that were destined to be dynamically linked to the libraries. Theoretically, should these be the same?

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

如果函数 foo() 被静态 link 编辑到应用程序中,那么函数定义将处于 固定 (静态!)相对于其余应用程序代码的位置。

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