使用具有不同编译器版本的boost库

时间:2014-03-26 16:19:26

标签: c++ gcc boost compiler-errors

我使用gcc版本4.6.3(在3.2.0-29-通用#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)

2 个答案:

答案 0 :(得分:5)

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

最好的办法是将整个系统保留在最新支持的gcc版本上。如果您的用户确实需要不同的编译器,那么您可以提供库的不同版本 - 每个版本对应您想要支持的编译器。

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

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

答案 1 :(得分:3)

Boost充满了基于编译器对不同功能的可用性或支持的条件编译块。查看他们的macro list。不同的编译器(或版本)对不同的标准功能(或扩展)具有不同级别的支持。 Boost库是一组混合代码,可以根据最小公分母(当它没有&#34;伤害&#34;代码),特定于编译器的变通方法,以及有条件地使用功能时支持,可以提供明显的好处。

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

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

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