简体   繁体   中英

Linker error compiling an executable which uses Boost.Thread linking to a static library using Boost.Thread

I have a static library called MyAwesomeLib . It is built with the CMakeLists.txt below

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})

Now I want to build MyAwesomeExecutable which needs symbols from MyAwesomeLib . Both the executable and the library uses Boost.Thread (thread_group and thread class).

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})

When I build MyAwesomeExecutable , Visual Studio 2010 build its dependency MyAwesomeLib automatically. MyAwesomeLib builds just fine. But building MyAwesomeExecutable gives the following linker errors:

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)

Static library is just a collection of object files. It can compile quite well, because it doesn't use undefined symbols. Several checks can be done to ensure that boost libraries is really linked with your library. Please, do it to provide some more information.

1.Using cmake print out values from Boost_LIBRARY_DIRS and Boost_INCLUDE_DIRS to check linked boost libraries.

2.Check link.txt file generated by cmake. This file is generated for each target like library or executable and on Linux it is placed under buildir/path/to/target/folder/CMakeFiles/targetName.dir/link.txt . link.txt contains compiler command to build and link executable. With it you can check, whether boost thread libraries are actually linked to your executable. In VS link.txt isn't generated, as said in the comment to this answer. Then you can check for linker command-line using VS itself.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM