【问题标题】:Getting undefined reference to std::thread::_M_start_thread获取对 std::thread::_M_start_thread 的未定义引用
【发布时间】:2016-11-08 16:21:12
【问题描述】:

我正在构建一个使用我从源代码构建的第 3 方库 (Box2D-MT) 的应用程序。链接时,我得到这个未定义的引用错误:

b2Threading.cpp:(.text._ZNSt6threadC2IM12b2ThreadPoolFviEJPS1_iEEEOT_DpOT0_[_ZNSt6threadC5IM12b2ThreadPoolFviEJPS1_iEEEOT_DpOT0_]+0xa4): 
undefined reference to 'std::thread::_M_start_thread(std::shared_ptr<std::thread::_Impl_base>, void (*)())'

我正在使用 g++ 构建并链接

-lBox2D -lpthread -lrt -ldl -lstdc++

另外,我正在编译

-std=c++11

查看 libstdc++.a 我可以看到类似的这个符号存在(它是“T”):

nm -C /usr/lib/gcc/x86_64-linux-gnu/4.9.2/libstdc++.a | grep _M_start_thread
0000000000000000 T std::thread::_M_start_thread(std::shared_ptr<std::thread::_Impl_base>)

但是这个重载不需要第二个参数。

我已经在整个互联网上搜索了类似的东西,但之前似乎没有人遇到过这个问题(在任何情况下)。

关于我为什么会收到此错误以及如何解决它的任何提示?

【问题讨论】:

  • 使用-pthread 编译器标志而不是-lpthread。用它来编译和链接。
  • @πάνταῥεῖ 现在试过了,我得到了完全相同的错误
  • 你的完整链接命令是什么?
  • @n.m. g++ -L./3rdparty/easyunit/ -o "foo" objects.o -leasyunit -lGLEW -lglfw -lGL -lX11 -lXxf86vm -lpng -lBox2D -lrt -lpthread -ldl
  • 我以不同的顺序更改了库,但得到了相同的结果

标签: c++ multithreading g++ ld undefined-reference


【解决方案1】:

看起来像标头/库版本不匹配。这就是我所拥有的:

$ nm -C /pkgs/gcc/4.9.2/lib/libstdc++.a | grep std::thread::_M_start_thread
00000000 T std::thread::_M_start_thread(std::shared_ptr<std::thread::_Impl_base>)

$ nm -C /pkgs/gcc/5.2.0/lib/libstdc++.a | grep std::thread::_M_start_thread
00000000 T std::thread::_M_start_thread(std::shared_ptr<std::thread::_Impl_base>)
00000000 T std::thread::_M_start_thread(std::shared_ptr<std::thread::_Impl_base>, void (*)())

$ fgrep -r M_start_thread /usr/intel/pkgs/gcc/4.9.2/include/
/pkgs/gcc/4.9.2/include/c++/4.9.2/thread:        _M_start_thread(_M_make_routine(std::__bind_simple(
/pkgs/gcc/4.9.2/include/c++/4.9.2/thread:    _M_start_thread(__shared_base_type);

$ fgrep -r M_start_thread /usr/intel/pkgs/gcc/5.2.0/include/
/pkgs/gcc/5.2.0/include/c++/5.2.0/thread:        _M_start_thread(_M_make_routine(std::__bind_simple(
/pkgs/gcc/5.2.0/include/c++/5.2.0/thread:        _M_start_thread(_M_make_routine(std::__bind_simple(
/pkgs/gcc/5.2.0/include/c++/5.2.0/thread:    _M_start_thread(__shared_base_type, void (*)());
/pkgs/gcc/5.2.0/include/c++/5.2.0/thread:    _M_start_thread(__shared_base_type);

【讨论】:

  • 好的,可能是这样。我想当我构建 Box2D 时,它使用的头文件/库与构建链接到它的应用程序时不同。我如何知道它使用了哪些,以及如何控制它?这可能特定于它使用的构建系统(cmake),但也许有一些更通用的解决方案(比如从系统中删除除一个版本的头文件/库之外的所有版本?)
  • 我检查了系统,我只有 4.9.2 包含文件和 4.8 和 4.9 库。两个库都不包含所需的重载。如果它不在库中,标题怎么可能包含对它的引用?
相关资源