Я компилирую простой проект (разделяемая библиотека) с использованием 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;
}
Общая библиотека использует Thread Local Storage из Boost, внутри класса один из членов которого:
boost::thread_specific_ptr<TLSData> threadData;
Это единственное, что я использую от Boost
Whevener я связываю, чтобы повысить с CMake, который я использую FindBoost.cmake.
В вашем случае это будет так:
find_package(Boost COMPONENTS thread)
target_link_libraries(${LibName} Boost::thread)
Обратите внимание, что ссылка на Boost::<target>
не совсем то же самое, что ссылка на libboost_<target>.a
так как Boost::<target>
также вводит все зависимости для этой цели, включая каталоги включения и зависимые библиотеки. В этом случае явно ссылка на Boost::system
а также Boost::chrono
на самом деле не нужны, потому что, начиная с Boost версии 1.50.0, boost::thread
будет на самом деле импортировать систему и хроно неявно.
Вам не нужно добавлять include_directories(${BOOST_PATH})
потому что это обрабатывается find_package
макрос и неявно связан с target_link_libraries
макро.
Если у вас возникли проблемы с поиском буста, вы можете установить BOOST_ROOT
переменная окружения, где вы установили boost. Вы можете временно set(Boost_DEBUG ON)
если вам все еще не удается выяснить, где cmake ищет библиотеки и что пытается связать.
Иногда у меня возникают проблемы с установкой связи с boost::log
или же boost::chrono
и я считаю, что добавление следующего часто помогает:
target_link_libraries(${LibName}
Boost::disable_autolinking
Boost::dynamic_linking
)
Эти цели добавляют определения компиляции -DBOOST_ALL_NO_LIB
а также -DBOOST_ALL_DYN_LINK
к вашему проекту.
Других решений пока нет …