centos上编译报错,部分信息如下:

/usr/local/lib/libprotobuf.so.9: undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::find_first_of(char, unsigned long) const@GLIBCXX_3.4.21'
/usr/local/lib/libboost_regex.so.1.68.0: undefined reference to `std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::_M_create(unsigned long&, unsigned long)@GLIBCXX_3.4.21'
/home/jwy/pytorch/torch/lib/libtorch.so: undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()@GLIBCXX_3.4.21'
/usr/local/lib/libboost_regex.so.1.68.0: undefined reference to `std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::_M_assign(std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocat        or<wchar_t> > const&)@GLIBCXX_3.4.21'
…… ……

注意到主要出现的信息是关于

undefined reference to `std::__cxx11::basic_string  

原因

  gcc5以及以后的版本,将std::string和std::list重写,std::list变为std::__cxx11::list<int>,std::string在c++03库是std::basic_string<char>,而在c++11中变为了std::__cxx11::basic_string<char>。而为了在编译的时候兼容旧版本(链接阶段),可在编译的时候启动_GLIBCXX_USE_CXX11_ABI 宏指定具体链接的库。

  注意:不要将c++11和c++03的库混用。

GCC官方解释

If you get linker errors about undefined references to symbols that involve types in the std::__cxx11 namespace or the tag [abi:cxx11] then it probably indicates that you are trying to link together object files that were compiled with different values for the _GLIBCXX_USE_CXX11_ABI macro. This commonly happens when linking to a third-party library that was compiled with an older version of GCC. If the third-party library cannot be rebuilt with the new ABI then you will need to recompile your code with the old ABI.

Not all uses of the new ABI will cause changes in symbol names, for example a class with a std::string member variable will have the same mangled name whether compiled with the old or new ABI. In order to detect such problems the new types and functions are annotated with the abi_tag attribute, allowing the compiler to warn about potential ABI incompatibilities in code using them. Those warnings can be enabled with the -Wabi-tag option.

  如出现std::__cxx11命名空间或abi:cxx11中未定义符号的链接错误,很可能是因为链接了使用不同的_GLIBCXX_USE_CXX11_ABI宏编译的目标,在链接旧版gcc编译的第三方库中经常出现。如第三方库无法使用新的ABI编译,则需使用旧版ABI重新编译本地代码。 

  使用新版ABI不一定都会出现符号的重命名,如std::string在新旧版中名字相同。可通过在编译的时候使用-Wabi-tag选项提醒ABI是否一致。

宏定义的使用

-D_GLIBCXX_USE_CXX11_ABI=0 // 链接到旧版本,未启用c++11特性,std::string是std::basic_string<char>,如将c++11下的string当作参数传入非c++11库,就会出现error: cannot convert 'const std::__cxx11::basic_string<char>' to 'const char*',或者未定义的方法引用(undefined reference)
-D_GLIBCXX_USE_CXX11_ABI=1 // 链接到新版本
#define _GLIBCXX_USE_CXX11_ABI 0
#define _GLIBCXX_USE_CXX11_ABI 1

参考链接:

https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html

 

posted on 2019-11-13 09:41  luku  阅读(28338)  评论(0编辑  收藏  举报