我有一个看起来像这样的项目:
executable
\---> bsp.so
|---> bsp_protobuf.a
\---> protobuf.a
有两个静态库首先构建(两个protobuf),静态链接到bsp.so共享库。然后最后bsp.so链接到可执行文件。
当我在命令行上使用gcc
链接可执行文件并链接bsp.so时,它链接正常。
但是,如果我不链接bsp.so然后它也建立良好 - 这是设计 - 因为我想使用dlopen()
来确定我是否需要这个库(我有指向对象的指针,但没有实例化的等等.. )。
我遇到的问题是,当我使用dlopen()
(在代码中)时,由于未定义的符号,它无法打开库。有问题的符号存在于静态库中。
我真正难以理解的是它为什么在命令行上运行但在使用dlopen()
和运行时不起作用。
我有3-4个其他共享库,我可以成功使用dlopen()
- 所以我知道我使用dlopen()
的一般过程是好的。
我正在使用dlerror()
来获取未定义的符号错误消息。
我查看了以下链接:
how-to-force-symbols-from-a-static-library-to-be-included-in-a-shared-library-bu
how-to-apply-fvisibility-option-to-symbols-in-static-libraries
我绑定了-Wl,--whole-archive
的想法,但这似乎吸引了太多,并且构建失败了太多警告 - 可能与谷歌protobuf的东西更多,加上我不确定这是我想要最终的方法。
我检查了我的共享库是用-fPIC
构建的,我不确定静态库是用-fPIC
构建还是需要它们?
我也看了一下:
讨论如何链接dlopen()
,但这是使用libtools - 我们没有为我们所有的目标,所以我不想使用libtools。
我真的不确定哪种方式可以进步 - 感觉这应该是一个简单的修复 - 但正如我所说,我无法理解为什么一种方法有效,另一种方法不...
更新
因此,在Sam的评论之后,我开始寻找合适的地方。事实证明,bsp.so的makefile仅静态链接两个库中的一个。有一个独立的测试人员用于连接两个库(因此测试人员工作)的共享库,我没有理由怀疑lib被破坏了...好吧,我学到了很多关于dlopen和链接等...:o
将可执行文件与共享库链接时,必须由共享库解析来自可执行文件的未解析符号引用,否则链接将失败。
链接共享库时,并不要求共享库本身的所有未解析符号必须由与其链接的任何其他共享库解析;因此,当您将共享库链接在一起时,可以从共享库本身找到未解析的符号。
将可执行文件与共享库链接成功,因为可执行文件中的所有未解析符号都由共享库解析;但由于共享库本身未解析的符号引用,可执行文件将无法加载。或者,共享库中的dlopen
()会产生相同的错误。
dlopen
手册页还描述了几个可用于控制此行为的可选标志。