简体   繁体   中英

problems linking boost with cmake

I would like to compile & link the following demo application using boost::logger but I get the following output:

d$ rm -rf *; cmake ..;make
-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Boost version: 1.67.0
-- Boost_LIBRARIES:
-- 
-- BOOST_INCLUDEDIR:
-- /path/to/env/include
-- Configuring done
-- Generating done
-- Build files have been written to: /path/to/src/tmp/logger/build
Scanning dependencies of target logger
[ 50%] Building CXX object CMakeFiles/logger.dir/logger.cpp.o
[100%] Linking CXX executable logger
CMakeFiles/logger.dir/logger.cpp.o: In function `init()':
/path/to/src/tmp/logger/logger.cpp:21: undefined reference to `boost::log::v2_mt_posix::core::get()'
/path/to/src/tmp/logger/logger.cpp:24: undefined reference to `boost::log::v2_mt_posix::core::set_filter(boost::log::v2_mt_posix::filter const&)'
CMakeFiles/logger.dir/logger.cpp.o: In function `boost::log::v2_mt_posix::attribute_name::attribute_name(char const*)':
/path/to/env/include/boost/log/attributes/attribute_name.hpp:80: undefined reference to `boost::log::v2_mt_posix::attribute_name::get_id_from_string(char const*)'
CMakeFiles/logger.dir/logger.cpp.o: In function `boost::log::v2_mt_posix::aux::light_rw_mutex::light_rw_mutex()':
/path/to/env/include/boost/log/detail/light_rw_mutex.hpp:103: undefined reference to `pthread_rwlock_init'
CMakeFiles/logger.dir/logger.cpp.o: In function `boost::log::v2_mt_posix::aux::light_rw_mutex::~light_rw_mutex()':
/path/to/env/include/boost/log/detail/light_rw_mutex.hpp:107: undefined reference to `pthread_rwlock_destroy'
CMakeFiles/logger.dir/logger.cpp.o: In function `boost::log::v2_mt_posix::aux::light_rw_mutex::lock_shared()':
/path/to/env/include/boost/log/detail/light_rw_mutex.hpp:111: undefined reference to `pthread_rwlock_rdlock'
CMakeFiles/logger.dir/logger.cpp.o: In function `boost::log::v2_mt_posix::aux::light_rw_mutex::unlock_shared()':
/path/to/env/include/boost/log/detail/light_rw_mutex.hpp:115: undefined reference to `pthread_rwlock_unlock'
CMakeFiles/logger.dir/logger.cpp.o: In function `boost::log::v2_mt_posix::aux::once_block_sentry::~once_block_sentry()':
...
...

now my CMakeLists.txt looks like:

cmake_minimum_required(VERSION 2.6)
project(LOGGER)

set(BOOST_INCLUDEDIR "/path/to/env/include")
set(BOOST_ROOT "/path/to/env/include")
set(Boost_NO_SYSTEM_PATHS on CACHE BOOL "Do not search system for Boost")


find_package(Boost REQUIRED)

message(STATUS Boost_LIBRARIES:)
message (STATUS ${Boost_LIBRARIES})
message(STATUS BOOST_INCLUDEDIR:)
message(STATUS ${BOOST_INCLUDEDIR})

ADD_EXECUTABLE(logger logger.cpp)
target_include_directories(logger PUBLIC ${BOOST_INCLUDEDIR})

set (CMAKE_CXX_FLAGS "-g -Wall -DBOOST_LOG_DYN_LINK")

and logger.cpp :

#include <iostream>
#include <boost/fusion/iterator/equal_to.hpp>
#include <boost/log/core.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/utility/setup/file.hpp>

namespace logging = boost::log;
namespace src = boost::log::sources;
namespace sinks = boost::log::sinks;
namespace keywords = boost::log::keywords;
namespace expr = boost::log::expressions;


void init()
{
    logging::add_file_log("sample.log");

    logging::core::get()->set_filter
    (
        logging::trivial::severity >= logging::trivial::info
    );
}

int main(void) {
    init();

    std::cout <<"Hello World!";

As you can see in the cmake output, ${Boost_LIBRARIES} did not return anything, I suspect this to be the culprit even though, the compiler found the boost includes at the non-standard path.

There are a number of issues with your CMakeLists.

Linking

You haven't linked your executable against Boost, so although you will have access to the declarations of Boost functions from the headers found at ${Boost_INCLUDEDIR} , you'll see undefined references to their definitions. Hence, you need to:

target_link_libraries(logger PRIVATE ${Boost_LIBRARIES})

This will resolve the linking issue.

Compile Definitions

Less problematically, your usage of CMAKE_CXX_FLAGS has some issues. Using set() for CMAKE_CXX_FLAGS is deprecated, but the correct usage is:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} <value>")

Because set() overwrites. However, the more modern way to do this would be:

target_compile_options(logger PRIVATE -g -Wall)
target_compile_definitions(logger PRIVATE BOOST_LOG_DYN_LINK=true)

This will ensure that these definitions are used only for this exectuable. Note that this step will require a relatively recent version of CMake.

Include Directories

The findBoost module exports a number of variables, one of which is ${Boost_INCLUDE_DIRS} . This variable represents the directories in which boost files are stored. Boost also looks for a variable, ${BOOST_INCLUDEDIR} , which is the path to the top-level directory of the boost headers. Currently, you're using the latter to represent the former, which should be corrected.

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