使用 boost 时出现运行时错误 - 未定义的符号:_ZN5boost6system15system_categoryEv
Runtime error using boost - undefined symbol: _ZN5boost6system15system_categoryEv
我正在使用CMake编译一个简单的项目(共享库),这是CMakeLists.txt
的内容
set (CMAKE_BUILD_TYPE Release)
set (LibName test)
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(test CXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${warnings}")
add_definitions(${GCC_NARROWING})
add_definitions(${GCC_RESOLVEALL})
add_definitions(-DTESTFRAMEWORK_GOOGLE)
add_definitions(-DVARIADIC_MAX=10)
add_definitions(-DENCODING=8)
#include_directories(${GTEST_PATH}/include)
include_directories(${BOOST_PATH}) #${BOOST_PATH} is defined by parent CMakeList
include_directories(${GTEST_PATH}/include ../../ThirdParty/rapidjson_master/include)
set (SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/Test.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Test.h
)
message(${LibName})
add_library(${LibName} SHARED ${SOURCES})
target_link_libraries(${LibName}
${OUTDIR}/libboost_system.a
${OUTDIR}/libboost_thread.a
${OUTDIR}/libboost_chrono.a
)
编译时我没有收到任何错误,当 运行 我收到加载此共享库的程序时:
./test.so: 未定义符号: _ZN5boost6system15system_categoryEv
加载此共享库的程序只需执行以下操作:
void *m_hTest = dlopen("./test.so", RTLD_NOW);
if (m_hTest == NULL) {
return -1;
}
共享库使用来自 Boost 的线程本地存储,在 class 其中一个成员是:
boost::thread_specific_ptr<TLSData> threadData;
这是我唯一使用的 boost
当我 link 使用 CMake 来提升时,我使用 FindBoost.cmake。
你的情况是这样的:
find_package(Boost COMPONENTS thread)
target_link_libraries(${LibName} Boost::thread)
请注意,linking 到 Boost::<target>
与 linking 到 libboost_<target>.a
并不完全相同,因为 Boost::<target>
还为此引入了所有依赖项目标包括其包含目录和依赖库。在这种情况下,显式 linking 到 Boost::system
和 Boost::chrono
实际上是不必要的,因为自 Boost 版本 1.50.0 以来,boost::thread
实际上将隐式导入 system 和 chrono。
您不需要添加 include_directories(${BOOST_PATH})
,因为它由 find_package
宏处理并且隐含地 link 与 target_link_libraries
宏一起编辑。
如果您找不到 boost,可以将 BOOST_ROOT
环境变量设置为安装 boost 的位置。如果您仍然无法解决 cmake 在何处搜索库以及它正在尝试 link 的问题,您可以暂时 set(Boost_DEBUG ON)
。
有时我在 link 使用 boost::log
或 boost::chrono
时遇到问题,我发现添加以下内容通常会有所帮助:
target_link_libraries(${LibName}
Boost::disable_autolinking
Boost::dynamic_linking
)
这些目标将编译定义 -DBOOST_ALL_NO_LIB
和 -DBOOST_ALL_DYN_LINK
添加到您的项目。
我正在使用CMake编译一个简单的项目(共享库),这是CMakeLists.txt
的内容set (CMAKE_BUILD_TYPE Release)
set (LibName test)
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(test CXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${warnings}")
add_definitions(${GCC_NARROWING})
add_definitions(${GCC_RESOLVEALL})
add_definitions(-DTESTFRAMEWORK_GOOGLE)
add_definitions(-DVARIADIC_MAX=10)
add_definitions(-DENCODING=8)
#include_directories(${GTEST_PATH}/include)
include_directories(${BOOST_PATH}) #${BOOST_PATH} is defined by parent CMakeList
include_directories(${GTEST_PATH}/include ../../ThirdParty/rapidjson_master/include)
set (SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/Test.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Test.h
)
message(${LibName})
add_library(${LibName} SHARED ${SOURCES})
target_link_libraries(${LibName}
${OUTDIR}/libboost_system.a
${OUTDIR}/libboost_thread.a
${OUTDIR}/libboost_chrono.a
)
编译时我没有收到任何错误,当 运行 我收到加载此共享库的程序时:
./test.so: 未定义符号: _ZN5boost6system15system_categoryEv
加载此共享库的程序只需执行以下操作:
void *m_hTest = dlopen("./test.so", RTLD_NOW);
if (m_hTest == NULL) {
return -1;
}
共享库使用来自 Boost 的线程本地存储,在 class 其中一个成员是:
boost::thread_specific_ptr<TLSData> threadData;
这是我唯一使用的 boost
当我 link 使用 CMake 来提升时,我使用 FindBoost.cmake。
你的情况是这样的:
find_package(Boost COMPONENTS thread)
target_link_libraries(${LibName} Boost::thread)
请注意,linking 到 Boost::<target>
与 linking 到 libboost_<target>.a
并不完全相同,因为 Boost::<target>
还为此引入了所有依赖项目标包括其包含目录和依赖库。在这种情况下,显式 linking 到 Boost::system
和 Boost::chrono
实际上是不必要的,因为自 Boost 版本 1.50.0 以来,boost::thread
实际上将隐式导入 system 和 chrono。
您不需要添加 include_directories(${BOOST_PATH})
,因为它由 find_package
宏处理并且隐含地 link 与 target_link_libraries
宏一起编辑。
如果您找不到 boost,可以将 BOOST_ROOT
环境变量设置为安装 boost 的位置。如果您仍然无法解决 cmake 在何处搜索库以及它正在尝试 link 的问题,您可以暂时 set(Boost_DEBUG ON)
。
有时我在 link 使用 boost::log
或 boost::chrono
时遇到问题,我发现添加以下内容通常会有所帮助:
target_link_libraries(${LibName}
Boost::disable_autolinking
Boost::dynamic_linking
)
这些目标将编译定义 -DBOOST_ALL_NO_LIB
和 -DBOOST_ALL_DYN_LINK
添加到您的项目。