如何强制将静态库中的符号包含在共享库构建中?

25

我正在尝试构建一个共享对象库,该库将被使用dlopen()函数打开的程序所调用。这个库将使用由另一个静态库提供的功能。

我在链接动态库时加入了相应的标志以拉取静态库(例如,我使用-lfoo来链接libfoo.a),链接器没有报错。然而,当主程序调用dlopen()函数打开动态库时,会出现“未定义符号”的错误消息,引用静态库中的符号。

运行nm命令确实显示了问题符号在动态库中是未定义的,主程序也不包含该符号,那么如何强制链接器引入这个符号呢?这个符号本身位于未初始化数据部分(在nm输出中为符号类型“B”)。

3个回答

23

--whole-archive 链接器选项可以实现此操作。例如,您可以将其用作:

gcc -o libmyshared.so foo.o -lanothersharedlib -Wl,--whole-archive -lmystaticlib

你所遇到的情况是默认情况下,链接器会在静态存档中搜索二进制文件需要的符号,如果需要该符号,则会将包含该符号所在的整个.o文件包含进去。如果你的共享库不需要任何符号,则它们不会被包含在你的共享库中。

请记住,成为共享库的代码需要使用特殊选项进行编译,例如 -fpic,因为你在共享库中包含了一个静态库,所以该静态库需要使用相同的选项进行编译。


18

最近我也在寻找同样的解决方案。 我发现可以使用

--undefined=symbol
或者
-u symbol

解决了问题。


1
--whole-archive 选项会将存档文件中的所有符号转换为共享库中的导出符号。如果您只需要一个符号,则此选项可以减少 .so 文件的膨胀。 - MuertoExcobito

6

另一种方法是在库的初始化期间获取函数地址。这将确保您实际使用该符号。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接