проблемы, связывающие повышение с cmake - PullRequest
0 голосов
/ 07 сентября 2018

Я хотел бы скомпилировать и связать следующее демонстрационное приложение, используя 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} ничего не возвратил, я подозреваю, что это виновник, хотя компилятор обнаружил, что повышение включает нестандартный путь.

1 Ответ

0 голосов
/ 07 сентября 2018

Существует ряд проблем с вашими CMakeLists.

Linking

Вы не связали свой исполняемый файл с Boost, поэтому, хотя у вас будет доступ к объявлениям функций Boost из заголовков, найденных в ${Boost_INCLUDEDIR}, вы увидите неопределенные ссылки на их определения. Следовательно, вам необходимо:

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_INCLUDEDIR}, которая является путем к каталогу верхнего уровня заголовков повышения. В настоящее время вы используете последнее для представления первого, которое следует исправить.

...