【问题标题】:Linker error compiling an executable which uses Boost.Thread linking to a static library using Boost.Thread链接器错误编译使用 Boost.Thread 的可执行文件链接到使用 Boost.Thread 的静态库
【发布时间】:2026-01-09 02:40:01
【问题描述】:

我有一个名为MyAwesomeLib 的静态库。它是用下面的 CMakeLists.txt 构建的

PROJECT(MyAwesomeLib)

find_package(OpenCV)
find_package(VTK REQUIRED)
find_package(OpenGL)
find_package(GLUT)

set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
FIND_PACKAGE(Boost COMPONENTS thread)

if(NOT Boost_FOUND)
message(SEND_ERROR "Cannot find Boost Thread")
endif(NOT Boost_FOUND)

link_directories (${Boost_LIBRARY_DIRS})
include_directories(${Boost_INCLUDE_DIR} ${GLUT_INCLUDE_DIR})

INCLUDE(${VTK_USE_FILE})

file(GLOB SRCS "*.cpp" "*.c")
file(GLOB HDRS "*.h")
add_library(MyAwesomeLib STATIC ${SRCS} ${HDRS})
target_link_libraries(MyAwesomeLib ${OpenCV_LIBS} ${Boost_LIBRARIES} ${GLUT_LIBRARY} ${OPENGL_LIBRARY})

现在我想构建MyAwesomeExecutable,它需要来自MyAwesomeLib 的符号。可执行文件和库都使用 Boost.Thread(thread_group 和线程类)。

PROJECT(MyAwesomeExecutable)

FIND_PACKAGE(OpenCV REQUIRED)
FIND_PACKAGE(VTK REQUIRED)

set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
FIND_PACKAGE(Boost COMPONENTS thread)

if(NOT Boost_FOUND)
message(SEND_ERROR "Cannot find Boost Thread")
endif(NOT Boost_FOUND)

link_directories (${Boost_LIBRARY_DIRS})
include_directories(${Boost_INCLUDE_DIR} ${GLUT_INCLUDE_DIR})

INCLUDE(${VTK_USE_FILE})

FILE(GLOB SRCS "*.cpp" "*.c")
FILE(GLOB HDRS "*.h")

ADD_EXECUTABLE(MyAwesomeExecutable ${SRCS} ${HDRS})
TARGET_LINK_LIBRARIES(MyAwesomeExecutable MyAwesomeLib ${Boost_LIBRARIES} ${GLUT_LIBRARY} ${OPENGL_LIBRARY} ${OpenCV_LIBS})

当我构建 MyAwesomeExecutable 时,Visual Studio 2010 会自动构建它的依赖关系 MyAwesomeLibMyAwesomeLib 构建得很好。但是构建MyAwesomeExecutable 会出现以下链接器错误:

2>MyAwesomeExecutable.obj : error LNK2019: unresolved external symbol "public: void __cdecl boost::thread::join(void)" (?join@thread@boost@@QEAAXXZ) referenced in function "public: void __cdecl boost::thread_group::join_all(void)" (?join_all@thread_group@boost@@QEAAXXZ)
2>MyAwesomeLib.lib(Face.obj) : error LNK2001: unresolved external symbol "public: void __cdecl boost::thread::join(void)" (?join@thread@boost@@QEAAXXZ)
2>MyAwesomeExecutable.obj : error LNK2019: unresolved external symbol "public: __cdecl boost::thread::~thread(void)" (??1thread@boost@@QEAA@XZ) referenced in function "public: void * __cdecl boost::thread::`scalar deleting destructor'(unsigned int)" (??_Gthread@boost@@QEAAPEAXI@Z)
2>MyAwesomeLib.lib(Face.obj) : error LNK2001: unresolved external symbol "public: __cdecl boost::thread::~thread(void)" (??1thread@boost@@QEAA@XZ)
2>MyAwesomeExecutable.obj : error LNK2019: unresolved external symbol "private: void __cdecl boost::thread::start_thread(void)" (?start_thread@thread@boost@@AEAAXXZ) referenced in function "public: __cdecl boost::thread::thread<class boost::_bi::bind_t<void,void (__cdecl*)(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >),class boost::_bi::list1<class boost::_bi::value<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > > > >(class boost::_bi::bind_t<void,void (__cdecl*)(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >),class boost::_bi::list1<class boost::_bi::value<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > > >,struct boost::thread::dummy *)" (??$?0V?$bind_t@XP6AXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@ZV?$list1@V?$value@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@_bi@boost@@@_bi@boost@@@_bi@boost@@@thread@boost@@QEAA@V?$bind_t@XP6AXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@ZV?$list1@V?$value@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@_bi@boost@@@_bi@boost@@@_bi@1@PEAUdummy@01@@Z)
2>MyAwesomeLib.lib(Face.obj) : error LNK2001: unresolved external symbol "private: void __cdecl boost::thread::start_thread(void)" (?start_thread@thread@boost@@AEAAXXZ)

【问题讨论】:

  • 你使用Boost的自动链接吗?禁用它时我有更多的运气: add_definitions( -DBOOST_ALL_NO_LIB ) 并明确指定动态链接: add_definitions( -DBOOST_ALL_DYN_LINK )

标签: c++ visual-studio-2010 boost cmake


【解决方案1】:

静态库只是目标文件的集合。它可以很好地编译,因为它不使用未定义的符号。可以进行多项检查以确保 boost 库确实与您的库链接。请这样做以提供更多信息。

1.使用cmake打印出Boost_LIBRARY_DIRSBoost_INCLUDE_DIRS的值来检查链接的boost库。

2.检查cmake生成的link.txt文件。该文件是为每个目标(如库或可执行文件)生成的,在 Linux 上,它位于buildir/path/to/target/folder/CMakeFiles/targetName.dir/link.txt 下。 link.txt 包含用于构建和链接可执行文件的编译器命令。有了它,您可以检查 boost 线程库是否实际链接到您的可执行文件。如对此答案的评论所述,VS link.txt 未生成。然后您可以使用 VS 本身检查链接器命令行。

【讨论】:

  • 使用 Visual Studio 10 构建时,不会生成 link.txt。 MinGW 会发生这种情况。也许编辑你的答案,让他检查 Visual Studio 中的链接器命令行?
  • @Andre:从来没有在 VS 下使用过 CMake,所以不知道没有 link.txt。感谢您的关注。