2012-02-06 67 views
5

这里是情况,我有一个使用最新GCC(4.3.3)的C++代码库,但我需要链接到使用GCC 3.2构建的较旧库。 3。没有新版本的库可用,我不能没有它,它是封闭的源,所以它不能被重建。混合使用C++ ABI以针对传统库进行构建

这似乎是一个问题,因为GCC 4.3.3和3.2.3之间存在ABI不兼容问题,所以我试图看看我的选项是用来解决这个问题的。

一些额外的细节:

  • 我可以重现我的代码库与-fabi版本= 1的一切才能得到正确的ABI的版本,但是我依赖于一些较新的功能从的libstdC++版本6
  • 代码库之外的所有C++库依赖都是开源的,所以我可以根据需要重建它们,除了这个库之外。
  • 许多C库依赖关系无法重建或难以重建。
  • 老库似乎是依赖于一些的libstdC++版本5层的功能

到目前为止我试过:

  • 重建所有的C++代码和依赖库与-fabi版本= 1和链接针对libstdC++版本6.这会导致C++标准库符号中的一些未定义符号错误失败。
  • 与上述相同,但在共享库中另外链接了libstdC++ 5,它解决了链接器问题,但似乎导致在遗留库内运行时混合两个版本,并导致崩溃。

我看到这个页面:http://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html这似乎表明可以在应用程序中混合使用C++ ABI版本来满足库之间不同的依赖关系。但是,在这里似乎并没有很好的工作,除非我错过了一些东西。

任何想法?

+0

如果您将旧的libstdC++静态链接到共享库,链接器选项'-Bsymbolic'和'--exclude-libs'应该会有所帮助。 – 2012-05-03 20:10:55

回答

3

好吧,你的解决方法是:

  • 写了一个“C”接口,旧的C++库,编译3.2.3所以它会工作。
  • 现在,您可以在新编译器中使用C接口。

你可以在C库上编写一些C++“包装器”代码,所以你将它用作C++,但是这个代码将被构建在新的编译器中。

+1

当然,这样做的缺点是增加了一堆胶水代码,但具有与任何一对C编译器/版本一起工作的优势。 – kibibu 2012-02-06 15:36:52

+0

这似乎是一个合理的方法。如果我创建一个共享库,它仍然会依赖于较旧的libstdC++共享库。我会不会有同样的问题?或者我应该静态链接旧版本? – 2012-02-06 16:17:14

+0

在做了一些更深入的挖掘之后,似乎正确的做法是将来自旧版GCC的libstdC++静态链接到此共享库中。然而,仅仅与此相关联,我怀疑,这还不够,因为你将会像以前一样有效地解决图书馆边界上共享符号的问题。我认为你可以通过在应用程序中使用dlopen并使用RTLD_NOW |来消除这种情况RTLD_DEEPBIND | RTLD_LOCAL。 – 2012-02-07 20:23:11