【问题标题】:Boost.Log with CMake causing undefined reference error带有 CMake 的 Boost.Log 导致未定义的引用错误
【发布时间】:2013-07-24 12:34:01
【问题描述】:

我正在尝试在我正在处理的项目中使用新的 Boost.Log 库。该项目是用 CMake 构建的。我收到链接错误,声称链接器遇到了对 Boost.Log 的未定义引用

Linking CXX executable main
CMakeFiles/main.dir/main.cpp.o: In function `main':
main.cpp:(.text+0x30): undefined reference to `boost::log::v2s_mt_posix::trivial::logger::get()'

我有一个简单的 hello world 测试,但由于这些错误而失败。如果我链接 Boost.Log 库,什么会导致它生成未定义的引用错误?

main.cpp:

#include <boost/log/trivial.hpp>
int main(int argc, char* const argv[]) {
  BOOST_LOG_TRIVIAL(info) << "Hello World";
}

CMakeLists.txt:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
FIND_PACKAGE(Boost 1.54 COMPONENTS log REQUIRED)
FIND_PACKAGE(Threads)
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR})
ADD_EXECUTABLE(main main.cpp)
TARGET_LINK_LIBRARIES(main ${Boost_LOG_LIBRARY} ${CMAKE_THREAD_LIBS_INIT})

编辑:cmake 和 make 的详细输出

cmake:

-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:476 ] _boost_TEST_VERSIONS = 1.56.0;1.56;1.55.0;1.55;1.54.0;1.54
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:478 ] Boost_USE_MULTITHREADED = TRUE
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:480 ] Boost_USE_STATIC_LIBS = 
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:482 ] Boost_USE_STATIC_RUNTIME = 
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:484 ] Boost_ADDITIONAL_VERSIONS = 
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:486 ] Boost_NO_SYSTEM_PATHS = 
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:538 ] Declared as CMake or Environmental Variables:
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:540 ]   BOOST_ROOT = 
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:542 ]   BOOST_INCLUDEDIR = 
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:544 ]   BOOST_LIBRARYDIR = 
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:546 ] _boost_TEST_VERSIONS = 1.56.0;1.56;1.55.0;1.55;1.54.0;1.54
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:639 ] location of version.hpp: /usr/include/boost/version.hpp
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:663 ] version.hpp reveals boost 1.54.0
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:739 ] guessed _boost_COMPILER = -gcc48
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:749 ] _boost_MULTITHREADED = -mt
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:792 ] _boost_RELEASE_ABI_TAG = -
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:794 ] _boost_DEBUG_ABI_TAG = -d
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:842 ] _boost_LIBRARY_SEARCH_DIRS = /usr/lib64;NO_DEFAULT_PATH
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:930 ] Searching for LOG_LIBRARY_RELEASE: boost_log-gcc48-mt-1_54;boost_log-gcc48-mt;boost_log-mt-1_54;boost_log-mt;boost_log
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:966 ] Searching for LOG_LIBRARY_DEBUG: boost_log-gcc48-mt-d-1_54;boost_log-gcc48-mt-d;boost_log-mt-d-1_54;boost_log-mt-d;boost_log-mt;boost_log
-- [ /usr/share/cmake-2.8/Modules/FindBoost.cmake:1017 ] Boost_FOUND = 1
-- Boost version: 1.54.0
-- Found the following Boost libraries:
--   log
-- Configuring done
-- Generating done
-- Build files have been written to: /home/durrw/boost-log-test/build

制作:

/usr/bin/cmake -H/home/durrw/boost-log-test -B/home/durrw/boost-log-test/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /home/durrw/boost-log-test/build/CMakeFiles /home/durrw/boost-log-test/build/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory `/home/durrw/boost-log-test/build'
make -f CMakeFiles/main.dir/build.make CMakeFiles/main.dir/depend
make[2]: Entering directory `/home/durrw/boost-log-test/build'
cd /home/durrw/boost-log-test/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/durrw/boost-log-test /home/durrw/boost-log-test /home/durrw/boost-log-test/build /home/durrw/boost-log-test/build /home/durrw/boost-log-test/build/CMakeFiles/main.dir/DependInfo.cmake --color=
make[2]: Leaving directory `/home/durrw/boost-log-test/build'
make -f CMakeFiles/main.dir/build.make CMakeFiles/main.dir/build
make[2]: Entering directory `/home/durrw/boost-log-test/build'
Linking CXX executable main
/usr/bin/cmake -E cmake_link_script CMakeFiles/main.dir/link.txt --verbose=1
/usr/bin/c++       CMakeFiles/main.dir/main.cpp.o  -o main -rdynamic -lboost_log -lpthread 
CMakeFiles/main.dir/main.cpp.o: In function `main':
main.cpp:(.text+0x39): undefined reference to `boost::log::v2s_mt_posix::trivial::logger::get()'

【问题讨论】:

  • 如果您运行cmake . -DBoost_DEBUG=1make VERBOSE=1,您将获得更多关于CMake 正在做什么以及实际链接器命令是什么的信息。随意将这些输出添加到您的问题中以获得更多帮助。
  • 调试输出很有用,但似乎仍然没有帮助,因为它链接到 boost_log

标签: c++ boost cmake boost-log


【解决方案1】:

看起来它归结为链接到 Boost.Log 的共享版本。

docs for Boost.Log 中有一些关于该问题的详细信息,您的错误消息提到了命名空间 boost::log::v2s_mt_posix,并且从文档中,这意味着链接器希望链接到静态版本的 Boost.Log。

如果您想链接到共享版本,似乎您需要定义BOOST_LOG_DYN_LINKBOOST_ALL_DYN_LINK,即在您的 CMakeLists.txt 中添加:

ADD_DEFINITIONS(-DBOOST_LOG_DYN_LINK)

如果要链接到静态版本的 Boost.Log,则需要在调用 FIND_PACKAGE(Boost ...) 之前添加一个 CMake 变量

SET(Boost_USE_STATIC_LIBS ON)
FIND_PACKAGE(Boost 1.54 COMPONENTS log REQUIRED)

有关影响 CMake 如何找到 Boost 的更多变量,请参阅FindBoost 的文档。

【讨论】:

  • 需要将ADD_DEFINITIONS(-DBOOST_LOG_DYN_LINK) 添加到我的 CMakeLists.txt 文件中。此外,我是 CMake 的新手,没有意识到事情并没有转移到子文件夹中的 CMakeLists.txt 文件中。以为我可以将它添加到根文件夹中的 CMakeLists.txt 文件中,并将其应用于所有子文件夹。然而,我发现这不是 CMake 的工作方式。
【解决方案2】:

对于 CMake 3.15(和一些早期版本),以下似乎足以使用 CMake 构建 Boost.Log 而不会出现原始链接器错误:

cmake_minimum_required(VERSION 3.15)
project(boost_log_tutorial)

SET(Boost_USE_STATIC_LIBS ON)           # link statically
#ADD_DEFINITIONS(-DBOOST_LOG_DYN_LINK)  # or, link dynamically

find_package(Boost 1.69.0 COMPONENTS log REQUIRED)

add_executable(boost_log_tutorial main.cpp)
target_link_libraries(boost_log_tutorial Boost::log_setup Boost::log)

关键的事情似乎是针对Boost:log_setupBoost::log 进行链接,并使用SET(Boost_USE_STATIC_LIBS ON)ADD_DEFINITIONS(-DBOOST_LOG_DYN_LINK) 指定静态或动态链接。

【讨论】:

    【解决方案3】:

    这是 Boost_INCLUDE_DIRS 而不是 Boost_INCLUDE_DIR。

    您可以尝试启用 Boost_USE_STATIC_LIBS

    【讨论】:

    • 根据docs for FindBoost,看起来这两个变量现在都有效。另外,如果这是错误的,会不会导致编译器错误而不是链接器错误?
    • Boost_INCLUDE_DIR 支持是在 CMake 2.8.11 中添加的,除非您强制执行 CMake 版本检查,否则确实无法使用。
    • 啊-好的。尽管如此,C++ #include 调用还是会出现编译器问题,如果这是错误的,不是吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-08
    • 1970-01-01
    • 2016-02-24
    • 1970-01-01
    • 1970-01-01
    • 2012-09-20
    • 2016-06-10
    相关资源
    最近更新 更多