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

我试图弄清楚如何在SLES10机器上加载两个不同版本的libstdc .so . 我的客户端有一个进程Foo,它是用GCC 4.1.2构建的,因此使用了6.0.8版本的libstdc .so . 我们还在构建名为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 .so . 但是,这不是一个vialbe解决方案,因为它要求我修改客户端的系统 .

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

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

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

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

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

回答(1)

2 years ago

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

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

ld --relocatable -o lib3rd-party-prelinked.so lib3rd-party.so /usr/lib64/libstdc++.a.6

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

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

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