【问题标题】:problems linking boost with cmake将 boost 与 cmake 联系起来的问题
【发布时间】:2018-09-07 02:23:55
【问题描述】:

我想使用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 包含在非标准路径中。

【问题讨论】:

  • 您在查找 Boost 时忘记添加 log 组件:find_package(Boost COMPONENTS log REQUIRED)。之后,Boost_LIBRARIES 应该不再为空,您需要将可执行文件与其链接。此外,BOOST_ROOT 变量应该包含 Boost 的安装目录,而不是它的包含目录“/path/to/env/include”。

标签: c++ boost cmake linker


【解决方案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 头文件的顶级目录的路径。目前,您使用后者来表示前者,应该更正。

【讨论】:

  • 哈,现在找不到标题了。我得到:fatal error: boost/fusion/iterator/equal_to.hpp: No such file or directory 使用“现代”方式和cmake version 3.5.2
  • “/path/to/env/include”看起来像/path/to/boost/吗?可能只尝试 fusion/iterator/equal_to.hpp,因为“增强”部分可能已经被预先设置。我尝试在最后编译它,但由于安装差异较大,因此具有挑战性。
  • @DrWatson 不,就像/path/to/env/include/boost/
  • 是的,这就是我的意思——它以 boost 结尾。所以如果你#include ,它会搜索/path/to/env/include/boost/boost/a/thing,我认为这是一个太多的提升。
  • 我不知道,现在我得到fatal error: fusion/iterator/equal_to.hpp: No such file or directory - 这么说,我认为它仍然需要提升,因为$BOOST_INCLUDEDIR 没有它 - 嗯,无论如何,不​​是它...... .这两种方式都不起作用
猜你喜欢
  • 1970-01-01
  • 2012-07-13
  • 2011-01-25
  • 1970-01-01
  • 2018-06-21
  • 1970-01-01
  • 2019-06-20
  • 2012-07-29
  • 1970-01-01
相关资源
最近更新 更多