c++ - Ubuntu 20.04 上 boost-thread 的 Clang 10 链接错误

标签 c++ linux boost clang lld

从使用 clang/lld 7 和 boost 1.65 的 Ubuntu 18.04 升级到使用 clang/lld 10 和 boost 1.71 的 20.04 后,我遇到了链接器错误,我不知道如何解决。 Ubuntu 20.04 上的 clang 和 boost 是否已知是不兼容的组合?使用 clang 在 Ubuntu 20.04 上进行编译的选项有哪些?

错误的最小示例是

#include <boost/thread/shared_mutex.hpp>
int main() {
  boost::shared_mutex sm;
}

注释:

  • 它与 GCC 9 和 gold 链接器配合得很好。
  • clang + gold 链接器组合失败并显示非常相同的错误消息,bfd 链接器失败并显示非常短的错误消息,我也会在下面显示输出。
  • 使用 clang/lld 9 而不是 10 时也会出现相同的错误。

我创建了一个可以在 ubuntu 20.04 系统或容器中轻松复制的最小示例,在复制过程中,我使用了 dockerhub 中的普通 ubuntu:focal 容器。

  1. 安装 clang/lld 10 和 boost 1.71
apt update && apt install clang lld libboost-thread-dev
update-alternatives --install "/usr/bin/ld" "ld" "/usr/bin/ld.lld-10" 30

现在所有要求都已安装,LLD 是默认链接器。

  • 创建最小示例并编译/链接它
  • root@d66452260792:/# cat x.cpp 
    #include <boost/thread/shared_mutex.hpp>
    int main() {
      boost::shared_mutex sm;
    }
    
    root@d66452260792:/# clang -lboost_thread x.cpp
    
  • 预期结果:
  • successful compilation
    
  • 实际结果
    • 使用 BFD 链接器 (GNU ld 2.34):
    /usr/bin/ld: /tmp/x-a145e4.o: undefined reference to symbol '_ZTVN10__cxxabiv121__vmi_class_type_infoE@@CXXABI_1.3'
    /usr/bin/ld: /lib/x86_64-linux-gnu/libstdc++.so.6: error adding symbols: DSO missing from command line
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    
    • 使用 LLD 10 作为链接器(但黄金链接器错误看起来非常相似):
    ld: error: undefined symbol: std::allocator<char>::allocator()
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::detail::generic_error_category_message[abi:cxx11](int))
    
    ld: error: undefined symbol: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::detail::generic_error_category_message[abi:cxx11](int))
    
    ld: error: undefined symbol: std::allocator<char>::~allocator()
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::detail::generic_error_category_message[abi:cxx11](int))
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::detail::generic_error_category_message[abi:cxx11](int))
    
    ld: error: undefined symbol: std::_V2::generic_category()
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::detail::std_category::equivalent(int, std::error_condition const&) const)
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::detail::std_category::equivalent(std::error_code const&, int) const)
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::detail::std_category::equivalent(std::error_code const&, int) const)
    
    ld: error: undefined symbol: typeinfo for std::_V2::error_category
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::detail::std_category::equivalent(int, std::error_condition const&) const)
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::detail::std_category::equivalent(std::error_code const&, int) const)
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(typeinfo for boost::system::detail::std_category)
    
    ld: error: undefined symbol: __dynamic_cast
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::detail::std_category::equivalent(int, std::error_condition const&) const)
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::detail::std_category::equivalent(std::error_code const&, int) const)
    
    ld: error: undefined symbol: __cxa_begin_catch
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(__clang_call_terminate)
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::system_error::what() const)
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::error_category::message(int, char*, unsigned long) const)
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(void std::_Rb_tree<boost::system::error_category const*, std::pair<boost::system::error_category const* const, std::unique_ptr<boost::system::detail::std_category, std::default_delete<boost::system::detail::std_category> > >, std::_Select1st<std::pair<boost::system::error_category const* const, std::unique_ptr<boost::system::detail::std_category, std::default_delete<boost::system::detail::std_category> > > >, boost::system::detail::cat_ptr_less, std::allocator<std::pair<boost::system::error_category const* const, std::unique_ptr<boost::system::detail::std_category, std::default_delete<boost::system::detail::std_category> > > > >::_M_construct_node<std::pair<boost::system::error_category const* const, std::unique_ptr<boost::system::detail::std_category, std::default_delete<boost::system::detail::std_category> > > >(std::_Rb_tree_node<std::pair<boost::system::error_category const* const, std::unique_ptr<boost::system::detail::std_category, std::default_delete<boost::system::detail::std_category> > > >*, std::pair<boost::system::error_category const* const, std::unique_ptr<boost::system::detail::std_category, std::default_delete<boost::system::detail::std_category> > >&&))
    
    ld: error: undefined symbol: std::terminate()
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(__clang_call_terminate)
    
    ld: error: undefined symbol: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::empty() const
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::system_error::what() const)
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::system_error::what() const)
    
    ld: error: undefined symbol: std::runtime_error::what() const
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::system_error::what() const)
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::system_error::what() const)
    
    ld: error: undefined symbol: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator=(char const*)
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::system_error::what() const)
    
    ld: error: undefined symbol: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator+=(char const*)
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::system_error::what() const)
    
    ld: error: undefined symbol: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator+=(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::system_error::what() const)
    
    ld: error: undefined symbol: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::system_error::what() const)
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::system_error::what() const)
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::error_category::message(int, char*, unsigned long) const)
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::system_error::~system_error())
    
    ld: error: undefined symbol: __cxa_end_catch
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::system_error::what() const)
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::error_category::message(int, char*, unsigned long) const)
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(void std::_Rb_tree<boost::system::error_category const*, std::pair<boost::system::error_category const* const, std::unique_ptr<boost::system::detail::std_category, std::default_delete<boost::system::detail::std_category> > >, std::_Select1st<std::pair<boost::system::error_category const* const, std::unique_ptr<boost::system::detail::std_category, std::default_delete<boost::system::detail::std_category> > > >, boost::system::detail::cat_ptr_less, std::allocator<std::pair<boost::system::error_category const* const, std::unique_ptr<boost::system::detail::std_category, std::default_delete<boost::system::detail::std_category> > > > >::_M_construct_node<std::pair<boost::system::error_category const* const, std::unique_ptr<boost::system::detail::std_category, std::default_delete<boost::system::detail::std_category> > > >(std::_Rb_tree_node<std::pair<boost::system::error_category const* const, std::unique_ptr<boost::system::detail::std_category, std::default_delete<boost::system::detail::std_category> > > >*, std::pair<boost::system::error_category const* const, std::unique_ptr<boost::system::detail::std_category, std::default_delete<boost::system::detail::std_category> > >&&))
    
    ld: error: undefined symbol: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::c_str() const
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::system_error::what() const)
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::error_category::message(int, char*, unsigned long) const)
    
    ld: error: undefined symbol: std::_V2::error_category::~error_category()
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::detail::std_category::~std_category())
    
    ld: error: undefined symbol: operator delete(void*)
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::detail::std_category::~std_category())
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::system_error::~system_error())
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::detail::to_std_category(boost::system::error_category const&))
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(__gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<boost::system::error_category const* const, std::unique_ptr<boost::system::detail::std_category, std::default_delete<boost::system::detail::std_category> > > > >::deallocate(std::_Rb_tree_node<std::pair<boost::system::error_category const* const, std::unique_ptr<boost::system::detail::std_category, std::default_delete<boost::system::detail::std_category> > > >*, unsigned long))
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::exception_detail::error_info_injector<boost::thread_resource_error>::~error_info_injector())
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::thread_resource_error::~thread_resource_error())
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::thread_exception::~thread_exception())
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::thread_resource_error> >::~clone_impl())
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::thread_resource_error> >::clone() const)
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::wrapexcept<boost::thread_resource_error>::~wrapexcept())
    
    ld: error: undefined symbol: std::runtime_error::~runtime_error()
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::system_error::~system_error())
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::system_error::system_error(boost::system::system_error const&))
    
    ld: error: undefined symbol: __cxa_guard_acquire
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::detail::to_std_category(boost::system::error_category const&))
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::detail::to_std_category(boost::system::error_category const&))
    >>> referenced by x.cpp
    >>>               /tmp/x-dd4c59.o:(boost::system::detail::to_std_category(boost::system::error_category const&))
    
    ld: error: too many errors emitted, stopping now (use -error-limit=0 to see all errors)
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    

    最佳答案

    首先,与库链接时顺序很重要。始终将库放在命令行上最后

    其次,boost_thread 依赖于 boost_system 库(应列在 boost_thread 之前)。

    第三,clang前端程序用于链接C程序,而不是C++。对于 C++,请使用 clang++

    要在支持的系统上使用 POSIX 线程功能,构建时还需要使用 -pthread 标志。

    所以把它们放在一起:

    $ clang++ -pthread x.cpp -lboost_system -lboost_thread
    

    关于c++ - Ubuntu 20.04 上 boost-thread 的 Clang 10 链接错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66988335/

    相关文章:

    python - Vagrant w/windows 作为主机,由于 crlf,文件不在 vm 上运行

    c++ - Boost库文件生成

    c++ - 制作rcssbase时增加错误

    python - 使用 Boost/Python 的 undefined symbol

    c++ - 反转字符串的递归方法

    c++ - 在 linux 上运行的 c++ 程序中为类编写测试用例

    c++ - 如何使用类似 Type() 的语法对 Type* 指针进行值初始化?

    c++ - 如何在 c++ 中获取 windows-phone8 中的硬件信息?

    c - 如何从c中的文件中获取元数据

    linux - 如何在 Linux 中拦截文件更新?