1

I am compiling a simple project (shared library) using CMake, this is the content of the 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
  )

I dont receive any error when compiling, when running the program that loads this shared library I receive:

./test.so: undefined symbol: _ZN5boost6system15system_categoryEv

The program that loads this shared library just do the following:

void *m_hTest = dlopen("./test.so", RTLD_NOW);
if (m_hTest == NULL) {
return -1;
}

The shared library uses a Thread Local Storage from Boost, inside a class one of the members is:

boost::thread_specific_ptr<TLSData> threadData;

That is the only thing I am using from boost

4

1 回答 1

1

Whevener I link to boost with CMake I use FindBoost.cmake.

In your case it would be like this:

find_package(Boost COMPONENTS thread) 
target_link_libraries(${LibName} Boost::thread)

Note that linking to Boost::<target> is not quite the same as linking to libboost_<target>.a because Boost::<target> also brings in all dependencies for that target including its include directories and dependent libraries. In this case, explicitly linking to Boost::system and Boost::chrono are actually unnecessary because since Boost version 1.50.0, boost::thread will actually import system and chrono implicitly.

You don't need to add include_directories(${BOOST_PATH}) because that is handled by the find_package macro and is implicitly linked with the target_link_libraries macro.

If you are having troubles finding boost, you can set the BOOST_ROOT environment variable to wherever you installed boost. You can temporarily set(Boost_DEBUG ON) if you're still having trouble to troubleshoot where cmake is searching for the libraries and what it is trying to link.

Sometimes I have problems linking with boost::log or boost::chrono and I find that adding the following often helps:

target_link_libraries(${LibName}
                        Boost::disable_autolinking
                        Boost::dynamic_linking
                     )

These targets add compile defintions -DBOOST_ALL_NO_LIB and -DBOOST_ALL_DYN_LINK to your project.

于 2017-10-27T18:20:17.440 回答