如何在g ++中链接同一个库的不同版本?

jma*_*ein 5 c++ linux linker gcc makefile

我正在试图弄清楚如何加载两个不同版本的libstdc ++.所以在SLES10机器上.我的客户端有一个进程Foo,它是用GCC 4.1.2构建的,因此使用了6.0.8版本的libstdc ++.所以.我们还在构建名为libBar.so的共享库.该库将在运行时由Foo动态加载.libBar.so使用GCC 4.3.6和libstdc ++版本6.0.10编译.

目前,当我尝试让Foo加载libBar.so时,我收到以下错误.

错误:无法加载共享对象'/usr/lib64/libBar.so':/ usr/lib64/libstdc + +.so.6:找不到版本`GLIBCXX_3.4.9'(/usr/lib64/libBar.so要求)

目前,我可以让它工作的唯一方法是更改​​我的库加载顺序(通过ld.so.conf),以便Foo和libbar.so都加载相同的(6.0.10)libstdc ++.所以.但是,这不是一个vialbe解决方案,因为它要求我修改客户端的系统.

我想要做的是让Foo加载它的libstdc ++版本.所以libBar.so链接到它自己的libstdc ++版本.所以,但我无法弄清楚如何编写我的Makefile来实现这一点.到目前为止,这是我在Makefile.am中的LIBADD行...

libBar_la_LIBADD = ../../vendor/SLES10/lib/libstdc++.so.6.0.10

我认为这将是libstdc ++的特定版本.所以.但是,当我对完全编译和链接的libBar.so运行ldd时,这是我看到的行...

libstdc ++.so.6 => /usr/lib64/libstdc++.so.6(0x00002aaaaeac5000)

为什么它没有专门链接到libstdc ++.so.6.0.10?我应该做什么呢?

Max*_*kin 8

我在使用过时版本的第三方库时遇到了类似的问题libstdc++.

我通过将第三方库静态链接到旧版本来解决它libstdc++.最终结果是另一个没有未解析libstdc++符号的共享库.命令行是这样的:

ld --relocatable -o lib3rd-party-prelinked.so lib3rd-party.so /usr/lib64/libstdc++.a.6
Run Code Online (Sandbox Code Playgroud)

然后我用lib3rd-party-prelinked.so而不是lib3rd-party.so.(查找--relocatable中man ld).

在我的情况下,由于第三方库暴露了C API,因此在其接口中没有使用C++标准库组件.

如果您的第三方库在其接口中公开C++标准库类,这些类的ABI在这些libstdc++版本之间是不同的,那么这是不可行的.例如,您的应用程序将std::list<>新ABI 传递给第三方库,该库需要std::list<>使用旧的ABI版本.即使它链接,也会在运行时导致未定义的行为.

  • 这是非常好的信息.另外需要注意的一点是:如果您使用GCC构建自己的库,可以将`-static-libgcc -static-libstdc ++`添加到链接行,以便将GCC的静态版本引入您的共享库.但是,正如Maxim所说,只有在不需要跨共享库边界传递STL对象时,这才有效.如果你这样做,并且两个STL实现不兼容,那你就是SOL.幸运的是,GCC STL在很长一段时间内没有ABI兼容性中断. (4认同)