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.