如何在共享库中嵌入静态库 (Linux)?

How to embed a static library in a shared library (Linux)?

我有一个没有源代码的静态库,需要从 LuaJIT FFI 动态调用它的符号。

因为它是静态的,我不能动态加载它,所以我试图将它嵌入到共享库中,然后在运行时间加载共享库。

问题是静态库的导出符号出现在共享库的符号 table 中,但未定义。

nm libUSBDevices.a

显示了很多行,其中我感兴趣的符号:

00001d80 T _ZN9USBDevice16FlightControllerC1EPKc
00001e30 T _ZN9USBDevice16FlightControllerD1Ev
00000140 T _ZN9USBDevice7AxisFctC1Ev
00000180 T _ZN9USBDevice7AxisFctclEv

然后我使用这两个 g++ 命令编译了共享库:

g++ -m32 -c -Wall -Werror -fpic USBDevicesLoader.cpp -llibUSBDevices.a

输出 USBDevicesLoader.o(USBDevicesLoader.cpp 包含一些调用静态库内部符号的导出函数,这些函数正确存在于 .so 中)

g++ -m32 -shared -o libUSBDevicesLoader.so USBDevicesLoader.o

这会输出共享库,但是在 运行 时加载时,它会显示:

[...] symbol lookup error: /home/me/USBDevices-loader/libUSBDevicesLoader.so: undefined symbol: _ZN9USBDevice16FlightControllerC1EPKc

当我在共享库上 运行 nm 时,它显示符号未定义:

U _ZN9USBDevice16FlightControllerC1EPKc
U _ZN9USBDevice7AxisFctclEv

我建议问题出在编译命令的某处,我还尝试直接从 .a 构建共享库而不先编译 cpp(只需将第二个命令中的 USBDevicesLoader.o 替换为 . a, 跳过第一个命令)但是问题还是一样

那么,有没有办法将静态库(没有源代码)的所有符号嵌入到动态库中,然后可以在 运行 时加载和使用?谢谢

您可以使用 --whole-archive 选项实现此目的 here and in the docs:

--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.

举个例子:

g++ -shared -o libnew.so -Wl,--whole-archive libmylib_static.a -Wl,--no-whole-archive

然后您可以像往常一样 link 访问共享 libnew.so 库。