我正在尝试构建一个共享对象库,该库将由程序使用dlopen()打开。该库将使用由静态的单独库提供的功能。
我在链接行中包含了相应的标志,以便在链接动态库时引入静态库(例如,我有-lfoo for libfoo.a),并且链接器不会抱怨。但是,当主程序在动态库上调用dlopen()时,调用将失败,并带有一个引用静态库中符号的“未定义符号”消息。
运行nm确实表明有问题的符号在动态库中未定义,并且主程序不包含它,那么如何强制链接器将此符号拉入?符号本身位于未初始化的数据部分(nm输出中的符号类型“B”)。
答案 0 :(得分:17)
--whole-archive
链接器选项应该这样做。你可以用它作为例如。
gcc -o libmyshared.so foo.o -lanothersharedlib -Wl,--whole-archive -lmystaticlib
您所遇到的是,默认情况下,链接器将在您生成的二进制文件所需的静态存档中搜索符号,如果需要,则它将包含符号所在的整个.o。如果您的共享库不需要任何符号,它们将不会包含在您的共享库中。
请记住,成为共享库的代码需要使用特殊选项进行编译,例如-fpic
,因为您在共享库中包含静态库,需要使用相同的库编译静态库选项。
答案 1 :(得分:12)
最近我正在寻找相同的解决方案。 我发现使用
--undefined=symbol
或
-u symbol
解决了这个问题。
答案 2 :(得分:5)
另一个hack是在库的初始化期间在某处获取函数的地址。这将确保您实际使用该符号。