将Boost与cmake相关联的问题

时间:2018-09-07 02:23:55

标签: c++ boost cmake linker

我想使用boost::logger编译并链接以下演示应用程序,但得到以下输出:

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()':
...
...

现在我的CMakeLists.txt如下:

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")

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!";

从cmake输出中可以看到,${Boost_LIBRARIES}没有返回任何内容,尽管编译器发现boost包含在非标准路径中,但我怀疑这是罪魁祸首。

1 个答案:

答案 0 :(得分:1)

您的CMakeLists存在许多问题。

链接

您尚未将可执行文件与Boost链接,因此尽管您可以从${Boost_INCLUDEDIR}的标头中访问Boost函数的声明,但仍会看到对其定义的未定义引用。因此,您需要:

target_link_libraries(logger PRIVATE ${Boost_LIBRARIES})

这将解决链接问题。

编译定义

少有问题,您对CMAKE_CXX_FLAGS的使用存在一些问题。不建议将set()用于CMAKE_CXX_FLAGS,但是正确的用法是:

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

因为set()被覆盖。但是,更现代的方法是:

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

这将确保这些定义仅用于此可执行文件。请注意,此步骤将需要相对较新的CMake版本。

包括目录

findBoost模块导出许多变量,其中之一是${Boost_INCLUDE_DIRS}。该变量表示存储boost文件的目录。 Boost还查找变量${BOOST_INCLUDEDIR},它是boost标头的顶级目录的路径。当前,您使用的是后者来表示前者,应该对其进行更正。