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

Did*_*set 15 linux linker gcc archive

当编译我们的项目,我们创建几个档案(静态库),说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
Run Code Online (Sandbox Code Playgroud)

当使用该共享对象到示例程序,比方说x.c,链接失败,因为到功能的未定义的引用y_function()z_function().

g++ x.o -L. -lyz -o xyz
Run Code Online (Sandbox Code Playgroud)

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

g++ x.o -L. -ly -lz -o xyz
Run Code Online (Sandbox Code Playgroud)

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

编辑:

可以使用--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
Run Code Online (Sandbox Code Playgroud)

知道这是从哪里来的吗?

elm*_*rco 21

你可以尝试(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.
Run Code Online (Sandbox Code Playgroud)

(gcc -Wl, - 整个档案)

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

  • 这个选项在`man ld`中有一个importnat注释:不要忘记在你的档案列表之后使用-Wl,-no-whole-archive,因为gcc会将自己的档案列表添加到你的链接中,你可能不想要这个标志也会影响那些 (5认同)