如何将存档的所有对象包含在共享对象中?

Posted

技术标签:

【中文标题】如何将存档的所有对象包含在共享对象中?【英文标题】:How to include all objects of an archive in a shared object? 【发布时间】:2010-05-04 09:00:18 【问题描述】:

在编译我们的项目时,我们创建了几个存档(静态库),比如liby.alibz.a,每个都包含一个定义函数y_function()z_function() 的目标文件。然后,这些档案被加入到一个共享对象中,比如libyz.so,这是我们的主要可分发目标之一。

g++  -fPIC  -c -o y.o y.cpp
ar cr liby.a y.o
g++  -fPIC  -c -o z.o z.cpp
ar cr libz.a z.o
g++ -shared -L. -ly -lz -o libyz.so

在示例程序中使用此共享对象时,例如 x.c,由于未定义对函数 y_function()z_function() 的引用,链接失败。

g++ x.o -L. -lyz -o xyz

但是,当我将最终的可执行文件直接与档案(静态库)链接时,它可以工作。

g++ x.o -L. -ly -lz -o xyz

我的猜测是存档中包含的目标文件没有链接到共享库中,因为它们没有在其中使用。如何强制包含?

编辑:

可以使用 --whole-archive ld 选项强制包含。但是如果导致编译错误:

g++ -shared '-Wl,--whole-archive' -L. -ly -lz -o libyz.so
/usr/lib/libc_nonshared.a(elf-init.oS): In function `__libc_csu_init':
(.text+0x1d): undefined reference to `__init_array_end'
/usr/bin/ld: /usr/lib/libc_nonshared.a(elf-init.oS): relocation R_X86_64_PC32 against undefined hidden symbol `__init_array_end' can not be used when making a shared object
/usr/bin/ld: final link failed: Bad value

知道这是从哪里来的吗?

【问题讨论】:

【参考方案1】:

你可以试试 (ld(2)):

   --whole-archive
       For each archive mentioned on the command line after the --whole-archive option, include every object file in the
       archive in the link, rather than searching the archive for the required object files.  This is normally used to turn
       an archive file into a shared library, forcing every object to be included in the resulting shared library.  This
       option may be used more than once.

(gcc -Wl,--whole-archive)

另外,您应该将-Wl,--no-whole-archive 放在库列表的末尾。 (正如 Dmitry Yudakov 在下面的评论中所说)

【讨论】:

谢谢,这看起来像我要找的东西,但它会产生一个链接错误,我不知道它来自哪里。我在问题中添加了详细信息。 man ld 中有此选项的重要说明:不要忘记在您的档案列表之后使用 -Wl,-no-whole-archive,因为 gcc 会将自己的档案列表添加到您的链接,您可能不希望此标志也影响这些链接

以上是关于如何将存档的所有对象包含在共享对象中?的主要内容,如果未能解决你的问题,请参考以下文章

如何在共享对象构建中包含子目录

如何找出从共享对象导出的所有符号?

如何更改共享脚本中的变量,而不影响共享该脚本的所有其他游戏对象?

从多个线程同步对共享对象的方法调用

仅获取共享特定属性值的 Core Data 对象

创建对象----原型模式