【问题标题】:How do I link different versions of the same library in g++?如何在 g++ 中链接同一库的不同版本?
【发布时间】:2014-03-14 01:46:29
【问题描述】:

我试图弄清楚如何在 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++。所以。但是,这不是一个可行的解决方案,因为它需要我修改客户端的系统。

我想做的是让 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?我应该怎么做?

【问题讨论】:

  • 您不想在同一个进程中加载​​ 2 个版本的 libstdc++,真正的目标是确保加载的版本是较新的。
  • 我在完全相同的版本(RHEL 5,不是吗?)上遇到了同样的问题,@MadScientist 的评论对我有用。

标签: c++ linux gcc linker makefile


【解决方案1】:

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

我通过将第 3 方库与旧版本的 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)。

在我的情况下这是可能的,因为第 3 方库暴露了 C API,其接口中没有使用 C++ 标准库组件。

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

【讨论】:

  • 这是非常好的信息。附加说明:如果您正在使用 GCC 构建自己的库,则可以将 -static-libgcc -static-libstdc++ 添加到您的链接行,以让 GCC 将这些静态版本拉入您的共享库中。但是,正如 Maxim 所说,这仅在您不需要跨共享库边界传递 STL 对象时才有效。如果你这样做了,并且两个 STL 实现不兼容,那么你就是 SOL。幸运的是,GCC STL 很长一段时间没有 ABI 兼容性中断。
  • 所以 C-ABI 在两个版本的 lib 之间起到了一种屏障的作用?在保留共享库的同时是否还有解决方案?我想我很多年前就听说过这样的事情,而且我的记忆力很差,他们也使用 C 库作为边界。它也适用于 dlopen() 吗?
  • @karsten 有很多问题需要评论,您可以发表自己的问题。
猜你喜欢
  • 2018-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多