gcc 使用静态libstdc++依赖构建ELF共享库

a64a0gku  于 2023-06-30  发布在  其他
关注(0)|答案(1)|浏览(237)

目前我正在尝试实现一个ELF共享库,使用-static-libstdc++-static-libgcc选项构建。这个共享库必须用C11构建,它有一些遗留代码,此外,它有一个非常具体的设计。
如果一些应用程序链接这个共享库,它们的C
实用程序一定不能互相干扰。例如,与std::cout相关的std::ios_base::Init::Init()_ZNSt8ios_base4InitC1Ev)等待出现在两个独立的实现中,一个是针对该特定共享库的静态实现,另一个是针对应用程序及其其他共享库的共享实现。然而,LD_DEBUG=all的使用表明,这个特定的共享库的C实用程序符号,如std::ios_base::Init::Init(),绑定到libstdc++中定义的符号,我试图避免...
这样的逻辑是否可以实现,或者至少可以以某种方式解决?在任何情况下,我都需要单独的C
实用程序。先谢谢你了!

syqv5f0l

syqv5f0l1#

目前我正在尝试实现一个ELF共享库,使用-static-libstdc++-static-libgcc选项构建。
最好的办法是不要这样做--“正常”地链接你的库(所以它依赖于libstdc++.so.6libgcc_s.so.1),这样你的大部分问题都会消失。(参见http://xyproblem.info-- * 为什么 * 要静态链接libstdc++?)
但是,LD_DEBUG=all的使用表明,这个特定共享库的C++实用程序符号(如std::ios_base::Init::Init())绑定到libstdc++中定义的符号
当您有两个libstdc++副本时,这句话就毫无意义了--一个在您的库中,另一个在“库外”(可能是libstdc++.so.6)。
你的意思是,你的库中对std::ios_base::Init::Init()的引用被绑定到libstdc++.so.6内部的定义。
你可以通过隐藏库中的所有符号来避免这种情况,并且使用链接器脚本只暴露“官方”接口。参见this answer
注意事项:

  • 控制C++共享库的ABI比控制纯C共享库要困难得多
  • 如果你把libstdc++“隐藏”在你的共享库中,并通过接口传递C++对象(例如a std::stringstd::map),您可以预期各种~不可能调试的问题,由于ABI之间的“隐藏”libstdc++.a和外部libstdc++.so.6不兼容。

相关问题