【问题标题】:Using boost library with different compiler version使用具有不同编译器版本的 boost 库
【发布时间】:2014-03-26 16:19:26
【问题描述】:

我使用 gcc 版本 4.6.3(在 3.2.0-29-generic #46-Ubuntu 中)编译了 boost 1.54。 然后,我使用这个 boost 库开发了我的库。由于我不想每次更改库时都重新编译 boost,因此我将已编译的 boost 静态库添加到我的 git repo 中。

现在,我正在尝试在具有不同版本编译器的不同机器上编译我的库(尝试使用 gcc 4.4 和 gcc 4.7)。我的库编译得很好,但是在链接时它会打印以下错误。

`.text._ZN5boost16exception_detail10bad_alloc_D2Ev' referenced in section `.text._ZN5boost16exception_detail10bad_alloc_D1Ev[boost::exception_detail::bad_alloc_::~bad_alloc_()]' of ../external/lib/linux/64/libboost_thread.a(thread.o): defined in discarded section `.text._ZN5boost16exception_detail10bad_alloc_D2Ev[_ZN5boost16exception_detail10bad_alloc_D5Ev]' of ../external/lib/linux/64/libboost_thread.a(thread.o)
`.text._ZN5boost16exception_detail14bad_exception_D2Ev' referenced in section `.text._ZN5boost16exception_detail14bad_exception_D1Ev[boost::exception_detail::bad_exception_::~bad_exception_()]' of ../external/lib/linux/64/libboost_thread.a(thread.o): defined in discarded section `.text._ZN5boost16exception_detail14bad_exception_D2Ev[_ZN5boost16exception_detail14bad_exception_D5Ev]' of ../external/lib/linux/64/libboost_thread.a(thread.o)
`.text._ZN5boost16exception_detail19error_info_injectorINS_21thread_resource_errorEED2Ev' referenced in section `.text._ZN5boost16exception_detail19error_info_injectorINS_21thread_resource_errorEED1Ev[boost::exception_detail::error_info_injector<boost::thread_resource_error>::~error_info_injector()]' of ../external/lib/linux/64/libboost_thread.a(thread.o): defined in discarded section `.text._ZN5boost16exception_detail19error_info_injectorINS_21thread_resource_errorEED2Ev[_ZN5boost16exception_detail19error_info_injectorINS_21thread_resource_errorEED5Ev]' of ../external/lib/linux/64/libboost_thread.a(thread.o)
`.text._ZN5boost16exception_detail19error_info_injectorINS_10lock_errorEED2Ev' referenced in section `.text._ZN5boost16exception_detail19error_info_injectorINS_10lock_errorEED1Ev[boost::exception_detail::error_info_injector<boost::lock_error>::~error_info_injector()]' of ../external/lib/linux/64/libboost_thread.a(thread.o): defined in discarded section `.text._ZN5boost16exception_detail19error_info_injectorINS_10lock_errorEED2Ev[_ZN5boost16exception_detail19error_info_injectorINS_10lock_errorEED5Ev]' of ../external/lib/linux/64/libboost_thread.a(thread.o)
`.text._ZN5boost16exception_detail19error_info_injectorINS_15condition_errorEED2Ev' referenced in section `.text._ZN5boost16exception_detail19error_info_injectorINS_15condition_errorEED1Ev[boost::exception_detail::error_info_injector<boost::condition_error>::~error_info_injector()]' of ../external/lib/linux/64/libboost_thread.a(thread.o): defined in discarded section `.text._ZN5boost16exception_detail19error_info_injectorINS_15condition_errorEED2Ev[_ZN5boost16exception_detail19error_info_injectorINS_15condition_errorEED5Ev]' of ../external/lib/linux/64/libboost_thread.a(thread.o)
collect2: ld returned 1 exit status
make[2]: *** [libHazelcastClientShared_64.so] Error 1
make[1]: *** [CMakeFiles/HazelcastClientShared_64.dir/all] Error 2
make: *** [all] Error 2

PS:我也尝试使用具有相同编译器版本的不同机器进行编译。 (gcc 版本 4.6.3 和 Centos 6.4)

【问题讨论】:

    标签: c++ gcc boost compiler-errors


    【解决方案1】:

    c++ ABI 不能保证在不同编译器版本之间保持一致。这会影响 c++ 名称修改,并可能导致您看到的链接器错误。您必须对所有库使用相同版本的 gcc。

    最好的办法是让您的整个系统使用最新支持的 gcc 版本。如果您的用户确实需要不同的编译器,那么您可以提供不同版本的库 - 为您想要支持的每个编译器提供一个版本。

    不能保证与使用不同编译器编译的库进行链接。这对于静态和共享/动态 c++ 库都是如此。

    还可以看看: 看看Unusual C++ linker error - 'Defined in discarded section' 似乎该问题的公认答案也是使用相同版本的 GCC 编译所有库。

    【讨论】:

    • 那我还有一个问题。忘记提升。假设我用 gcc 4.7 编译了我的库。然后我将它作为静态库分发。那么我的图书馆的用户是否必须用 gcc 4.7 编译他/她自己的图书馆?如果有人需要两个使用不同 gcc 版本编译的不同库会怎样?
    • 我已编辑我的答案以解决您的评论/问题
    【解决方案2】:

    Boost 充满了基于编译器对不同功能的可用性或支持的条件编译块。见他们的macro list。不同的编译器(或版本)对不同的标准特性(或扩展)具有不同的支持级别。 Boost 库是针对最小公分母定制的代码组合(当它不会“伤害”代码时)、特定于编译器的变通方法以及有条件地使用功能,在支持时可以提供明显的好处。

    我非常倾向于认为这是导致问题的原因。当您第一次编译为特定编译器和平台的代码时,某些开关会打开,而其他开关会根据该平台支持的内容而关闭,从而生成仅适用于该平台的二进制库。然后,当您尝试在另一个平台上编译代码时,在 boost 标头中打开/关闭了不同的开关,导致链接时不兼容。

    长话短说,你不能做你想做的事,至少,不是没有相当多的工作。一种解决方案是确定在功能最差的平台上打开或关闭了哪些 boost 宏(从我链接到的列表中),然后在代码中手动定义这些宏以在所有平台上强制执行相同的编译。但这可能是劳动密集型的。

    Boost 具有非常好的和广泛的分布(二进制文件也是如此)。所以,我不会太担心能够在不同平台上安装 boost 二进制文件。

    【讨论】:

      猜你喜欢
      • 2010-09-24
      • 2019-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-25
      • 2017-04-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多