我有一个库 foo,我为其生成了一个静态对象 (libfoo.a)。
我有第二个库 bar,我为其生成了一个共享对象 (libbar.so),它从 libfoo.a 中获取一些符号。
我有第三个库 baz,我正在尝试将其链接到 bar。调用链接器时,我收到有关 bar 中缺少符号的错误(对应于 foo 中的符号)。 nm 告诉我这些符号存在于 libfoo.a 中,但不存在于 libbar.so 中;但是,libbar.so 中有一些来自 libfoo.a 的符号。
为什么没有复制所有符号?
最佳答案
.a
库不是“静态对象”。 .a
文件是一个存档,理论上与 tar
类似,但格式不同,由 ar
命令生成。文件中的每个对象都是独特且独特的。通常这些对象是 .o
文件,它们是已编译的、未链接的对象。这些 .o
文件之一中的所有符号都将在链接期间包含在另一个文件中 (ld
)。但链接期间并非需要存档中的所有对象,其他对象文件中的符号不会在链接文件中看到。
例如,在libdialog.a
中,有mouse.o
和columns.o
对象文件。您的程序使用列,但不使用鼠标功能。因此,您的程序包含 columns.o
中的所有符号,但不包含 mouse.o
中的任何符号。
对于“共享对象”(.so
),它是单个对象,因此链接到它将包括对象中需要或不需要的所有符号。在上面的示例中,如果我们链接到 libdialog.so
,那么程序将包含来自 columns.o
和 mouse.o
的符号即使不使用基于鼠标的代码。
生成共享对象 (.so
) 时,使用存档 (.a
) 时适用相同的链接规则。因此 .so
文件将仅包含所使用的存档中 .o
文件中的符号。
关于gcc - 将符号从静态对象复制到共享对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9408626/