c++ - Conan + CMake + C++ : Linking against Boost. 记录静态库失败

标签 c++ boost cmake conan boost-log

我正在尝试使用 Conan 和 CMake 建立一个基本的 Boost.Logging 演示项目。

我在 Ubuntu 22.04.1 上使用 Conan 1.53.0 和 CMake 3.22.1 以及 gcc-11.3.0。

首先,我使用 Conan 引入 Boost 1.81,因此我的 conanfile.txt:

[requires]
boost/1.81.0

[options]
boost:shared=False

[generators]
CMakeDeps
CMakeToolchain

我正在使用柯南“工具链”开发人员流程,如 docs 所推荐。 。这就是我使用 CMakeToolchain 的原因,并且需要 CMakeDeps

对于我的 CMakeLists.txt 我有以下内容:

cmake_minimum_required(VERSION 3.22)
project(log_demo)

set(CMAKE_CXX_STANDARD 17)

set(Boost_USE_STATIC_LIBS ON)
find_package(Boost 1.81.0 COMPONENTS log_setup log REQUIRED)

add_executable(log_demo log_demo.cpp)
target_link_libraries(log_demo PRIVATE Boost::log_setup Boost::log)

请注意,我选择了静态库,它与 conanfile.txt 中的 [options]/boost:shared=False 选择相匹配.

最后,我的实际代码 log_demo.cpp 很简单:

#include <boost/log/core.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/expressions.hpp>

int main()
{
    BOOST_LOG_TRIVIAL(debug) << "This is debug";
    return 0;
}

我调用柯南来获得Boost:

$ mkdir build && cd build
$ conan install ..
Configuration:
[settings]
arch=x86_64
arch_build=x86_64
build_type=Release
compiler=gcc
compiler.libcxx=libstdc++11
compiler.version=11
os=Linux
os_build=Linux
[options]
[build_requires]
[env]

conanfile.txt: Installing package
Requirements
    boost/1.81.0 from 'conancenter' - Cache
    bzip2/1.0.8 from 'conancenter' - Cache
    libbacktrace/cci.20210118 from 'conancenter' - Cache
    zlib/1.2.13 from 'conancenter' - Cache
Packages
    boost/1.81.0:dc8aedd23a0f0a773a5fcdcfe1ae3e89c4205978 - Cache
    bzip2/1.0.8:c32092bf4d4bb47cf962af898e02823f499b017e - Cache
    libbacktrace/cci.20210118:dfbe50feef7f3c6223a476cd5aeadb687084a646 - Cache
    zlib/1.2.13:dfbe50feef7f3c6223a476cd5aeadb687084a646 - Cache

...

这会在此 build 目录中生成 conan_toolchain.cmake 以及其他文件。

现在我可以调用 CMake 来配置构建:

$ cmake -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Debug ..
-- Using Conan toolchain: /home/david/cpp/log_demo/build/conan_toolchain.cmake
-- The C compiler identification is GNU 11.3.0
-- The CXX compiler identification is GNU 11.3.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Conan: Component target declared 'Boost::diagnostic_definitions'
-- Conan: Component target declared 'Boost::disable_autolinking'
-- Conan: Component target declared 'Boost::dynamic_linking'
-- Conan: Component target declared 'Boost::headers'
-- Conan: Component target declared 'Boost::boost'
-- Conan: Component target declared 'boost::_libboost'
-- Conan: Component target declared 'Boost::atomic'
-- Conan: Component target declared 'Boost::container'
-- Conan: Component target declared 'Boost::context'
-- Conan: Component target declared 'Boost::date_time'
-- Conan: Component target declared 'Boost::exception'
-- Conan: Component target declared 'Boost::math'
-- Conan: Component target declared 'Boost::math_c99'
-- Conan: Component target declared 'Boost::math_c99f'
-- Conan: Component target declared 'Boost::math_c99l'
-- Conan: Component target declared 'Boost::math_tr1'
-- Conan: Component target declared 'Boost::math_tr1f'
-- Conan: Component target declared 'Boost::math_tr1l'
-- Conan: Component target declared 'Boost::program_options'
-- Conan: Component target declared 'Boost::regex'
-- Conan: Component target declared 'Boost::serialization'
-- Conan: Component target declared 'Boost::stacktrace'
-- Conan: Component target declared 'Boost::stacktrace_addr2line'
-- Conan: Component target declared 'Boost::stacktrace_backtrace'
-- Conan: Component target declared 'Boost::stacktrace_basic'
-- Conan: Component target declared 'Boost::stacktrace_noop'
-- Conan: Component target declared 'Boost::system'
-- Conan: Component target declared 'Boost::test'
-- Conan: Component target declared 'Boost::test_exec_monitor'
-- Conan: Component target declared 'Boost::url'
-- Conan: Component target declared 'Boost::wserialization'
-- Conan: Component target declared 'Boost::chrono'
-- Conan: Component target declared 'Boost::coroutine'
-- Conan: Component target declared 'Boost::filesystem'
-- Conan: Component target declared 'Boost::json'
-- Conan: Component target declared 'Boost::nowide'
-- Conan: Component target declared 'Boost::prg_exec_monitor'
-- Conan: Component target declared 'Boost::random'
-- Conan: Component target declared 'Boost::thread'
-- Conan: Component target declared 'Boost::timer'
-- Conan: Component target declared 'Boost::type_erasure'
-- Conan: Component target declared 'Boost::unit_test_framework'
-- Conan: Component target declared 'Boost::wave'
-- Conan: Component target declared 'Boost::contract'
-- Conan: Component target declared 'Boost::fiber'
-- Conan: Component target declared 'Boost::fiber_numa'
-- Conan: Component target declared 'Boost::graph'
-- Conan: Component target declared 'Boost::iostreams'
-- Conan: Component target declared 'Boost::locale'
-- Conan: Component target declared 'Boost::log'
-- Conan: Component target declared 'Boost::log_setup'
-- Conan: Target declared 'boost::boost'
-- Conan: Target declared 'BZip2::BZip2'
-- Conan: Including build module from '/home/david/.conan/data/bzip2/1.0.8/_/_/package/c32092bf4d4bb47cf962af898e02823f499b017e/lib/cmake/conan-official-bzip2-variables.cmake'
-- Conan: Target declared 'ZLIB::ZLIB'
-- Conan: Target declared 'libbacktrace::libbacktrace'
-- Configuring done
-- Generating done
-- Build files have been written to: /home/david/cpp/log_demo/build

问题出在与 Boost.Log 的链接上:

$ cmake --build .
[ 50%] Building CXX object CMakeFiles/log_demo.dir/log_demo.cpp.o
[100%] Linking CXX executable log_demo
/usr/bin/ld: CMakeFiles/log_demo.dir/log_demo.cpp.o: in function `main':
/home/david/cpp/log_demo/log_demo.cpp:7: undefined reference to `boost::log::v2s_mt_posix::trivial::logger::get()'
/usr/bin/ld: /home/david/cpp/log_demo/log_demo.cpp:7: undefined reference to `boost::log::v2s_mt_posix::trivial::logger::get()'
/usr/bin/ld: CMakeFiles/log_demo.dir/log_demo.cpp.o: in function `boost::log::v2s_mt_posix::record::reset()':
/usr/include/boost/log/core/record.hpp:157: undefined reference to `boost::log::v2s_mt_posix::record_view::public_data::destroy(boost::log::v2s_mt_posix::record_view::public_data const*)'
/usr/bin/ld: CMakeFiles/log_demo.dir/log_demo.cpp.o: in function `boost::log::v2s_mt_posix::record boost::log::v2s_mt_posix::sources::basic_composite_logger<char, boost::log::v2s_mt_posix::sources::severity_logger_mt<boost::log::v2s_mt_posix::trivial::severity_level>, boost::log::v2s_mt_posix::sources::multi_thread_model<boost::log::v2s_mt_posix::aux::light_rw_mutex>, boost::log::v2s_mt_posix::sources::features<boost::log::v2s_mt_posix::sources::severity<boost::log::v2s_mt_posix::trivial::severity_level> > >::open_record<boost::parameter::aux::tagged_argument_list_of_1<boost::parameter::aux::tagged_argument<boost::log::v2s_mt_posix::keywords::tag::severity, boost::log::v2s_mt_posix::trivial::severity_level const> > >(boost::parameter::aux::tagged_argument_list_of_1<boost::parameter::aux::tagged_argument<boost::log::v2s_mt_posix::keywords::tag::severity, boost::log::v2s_mt_posix::trivial::severity_level const> > const&)':
/usr/include/boost/log/sources/basic_logger.hpp:463: undefined reference to `boost::log::v2s_mt_posix::core::get_logging_enabled() const'
/usr/bin/ld: CMakeFiles/log_demo.dir/log_demo.cpp.o: in function `boost::log::v2s_mt_posix::aux::record_pump<boost::log::v2s_mt_posix::sources::severity_logger_mt<boost::log::v2s_mt_posix::trivial::severity_level> >::record_pump(boost::log::v2s_mt_posix::sources::severity_logger_mt<boost::log::v2s_mt_posix::trivial::severity_level>&, boost::log::v2s_mt_posix::record&)':
/usr/include/boost/log/sources/record_ostream.hpp:508: undefined reference to `boost::log::v2s_mt_posix::aux::stream_provider<char>::allocate_compound(boost::log::v2s_mt_posix::record&)'
/usr/bin/ld: CMakeFiles/log_demo.dir/log_demo.cpp.o: in function `boost::log::v2s_mt_posix::aux::record_pump<boost::log::v2s_mt_posix::sources::severity_logger_mt<boost::log::v2s_mt_posix::trivial::severity_level> >::auto_release::~auto_release()':
/usr/include/boost/log/sources/record_ostream.hpp:493: undefined reference to `boost::log::v2s_mt_posix::aux::stream_provider<char>::release_compound(boost::log::v2s_mt_posix::aux::stream_provider<char>::stream_compound*)'
/usr/bin/ld: CMakeFiles/log_demo.dir/log_demo.cpp.o: in function `boost::log::v2s_mt_posix::sources::aux::severity_level<boost::log::v2s_mt_posix::trivial::severity_level>::set_value(boost::log::v2s_mt_posix::trivial::severity_level)':
/usr/include/boost/log/sources/severity_feature.hpp:137: undefined reference to `boost::log::v2s_mt_posix::sources::aux::get_severity_level()'
/usr/bin/ld: CMakeFiles/log_demo.dir/log_demo.cpp.o: in function `boost::log::v2s_mt_posix::record boost::log::v2s_mt_posix::sources::basic_logger<char, boost::log::v2s_mt_posix::sources::severity_logger_mt<boost::log::v2s_mt_posix::trivial::severity_level>, boost::log::v2s_mt_posix::sources::multi_thread_model<boost::log::v2s_mt_posix::aux::light_rw_mutex> >::open_record_unlocked<boost::parameter::aux::tagged_argument_list_of_1<boost::parameter::aux::tagged_argument<boost::log::v2s_mt_posix::keywords::tag::severity, boost::log::v2s_mt_posix::trivial::severity_level const> > >(boost::parameter::aux::tagged_argument_list_of_1<boost::parameter::aux::tagged_argument<boost::log::v2s_mt_posix::keywords::tag::severity, boost::log::v2s_mt_posix::trivial::severity_level const> > const&)':
/usr/include/boost/log/sources/basic_logger.hpp:263: undefined reference to `boost::log::v2s_mt_posix::core::open_record(boost::log::v2s_mt_posix::attribute_set const&)'
/usr/bin/ld: CMakeFiles/log_demo.dir/log_demo.cpp.o: in function `boost::log::v2s_mt_posix::core::push_record(boost::log::v2s_mt_posix::record&&)':
/usr/include/boost/log/core/core.hpp:308: undefined reference to `boost::log::v2s_mt_posix::core::push_record_move(boost::log::v2s_mt_posix::record&)'
collect2: error: ld returned 1 exit status
gmake[2]: *** [CMakeFiles/log_demo.dir/build.make:97: log_demo] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/log_demo.dir/all] Error 2
gmake: *** [Makefile:91: all] Error 2

这个链接器错误 - 对 'boost::log::v2s_mt_posix::trivial::logger::get()' 的 undefined reference - 似乎很多人都会发生。有许多建议的解决方法和技巧,但我寻找有效方法的尝试都没有成功。显然,这个错误与尝试链接 Boost 的静态库有关,这实际上正是我想要的。

我尝试了 CMake 的 -v 选项,以查看链接器命令是什么:

$ cmake --build . -v
...
[ 50%] Linking CXX executable log_demo
/usr/bin/cmake -E cmake_link_script CMakeFiles/log_demo.dir/link.txt --verbose=1
/usr/bin/c++ -m64 -g -m64 CMakeFiles/log_demo.dir/log_demo.cpp.o -o log_demo 
...

我在 c++ 命令行上没有看到任何 Boost 库的提及 - 这对我来说似乎是错误的。为什么没有 -lboost_log-lboost_log_setup 存在?

这一定是我十年来第四次尝试设置 Boost.Log,每次都不同(由于 Conan 更改或 CMake 更改),所以我希望我错过了一些非常明显的东西这里...

最佳答案

您的问题在步骤和日志方面非常详细,感谢您提供如此好的信息。

您的错误来自配置不匹配。您的 Conan 配置文件显示 build_type=Release,但您的 CMake 命令使用 Debug,您需要对两者使用完全相同的配置。因此,如果您想在 Conan 命令上更新它,您需要传递 conan install .. -s build_type=Debug

这里我使用Release,但想法是相同的,使用您的文件我们将拥有:

$ conan install .. && cmake -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release .. && cmake --build .
Configuration:
[settings]
arch=x86_64
arch_build=x86_64
build_type=Release
compiler=gcc
compiler.libcxx=libstdc++11
compiler.version=11
os=Linux
os_build=Linux
[options]
[build_requires]
[env]

conanfile.txt: Installing package
Requirements
    boost/1.81.0 from 'conancenter' - Cache
    bzip2/1.0.8 from 'conancenter' - Cache
    libbacktrace/cci.20210118 from 'conancenter' - Cache
    zlib/1.2.13 from 'conancenter' - Cache
Packages
    boost/1.81.0:dc8aedd23a0f0a773a5fcdcfe1ae3e89c4205978 - Cache
    bzip2/1.0.8:c32092bf4d4bb47cf962af898e02823f499b017e - Cache
    libbacktrace/cci.20210118:dfbe50feef7f3c6223a476cd5aeadb687084a646 - Cache
    zlib/1.2.13:dfbe50feef7f3c6223a476cd5aeadb687084a646 - Cache

Installing (downloading, building) binaries...
bzip2/1.0.8: Already installed!
libbacktrace/cci.20210118: Already installed!
zlib/1.2.13: Already installed!
boost/1.81.0: Already installed!
conanfile.txt: Generator txt created conanbuildinfo.txt
conanfile.txt: WARN: Using the new toolchains and generators without specifying a build profile (e.g: -pr:b=default) is discouraged and might cause failures and unexpected behavior
conanfile.txt: Generator 'CMakeDeps' calling 'generate()'
conanfile.txt: WARN: Using the new toolchains and generators without specifying a build profile (e.g: -pr:b=default) is discouraged and might cause failures and unexpected behavior
conanfile.txt: Generator 'CMakeToolchain' calling 'generate()'
conanfile.txt: Preset 'release' added to CMakePresets.json. Invoke it manually using 'cmake --preset release'
conanfile.txt: If your CMake version is not compatible with CMakePresets (<3.19) call cmake like: 'cmake <path> -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=/home/conan/project/build_linux/conan_toolchain.cmake -DCMAKE_POLICY_DEFAULT_CMP0091=NEW -DCMAKE_BUILD_TYPE=Release'
conanfile.txt: Aggregating env generators
conanfile.txt: Generated conaninfo.txt
conanfile.txt: Generated graphinfo
-- Using Conan toolchain: /home/conan/project/build_linux/conan_toolchain.cmake
-- The CXX compiler identification is GNU 11.1.0
-- Check for working CXX compiler: /usr/local/bin/c++
-- Check for working CXX compiler: /usr/local/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Conan: Component target declared 'Boost::diagnostic_definitions'
-- Conan: Component target declared 'Boost::disable_autolinking'
-- Conan: Component target declared 'Boost::dynamic_linking'
-- Conan: Component target declared 'Boost::headers'
-- Conan: Component target declared 'Boost::boost'
-- Conan: Component target declared 'boost::_libboost'
-- Conan: Component target declared 'Boost::atomic'
-- Conan: Component target declared 'Boost::container'
-- Conan: Component target declared 'Boost::context'
-- Conan: Component target declared 'Boost::date_time'
-- Conan: Component target declared 'Boost::exception'
-- Conan: Component target declared 'Boost::math'
-- Conan: Component target declared 'Boost::math_c99'
-- Conan: Component target declared 'Boost::math_c99f'
-- Conan: Component target declared 'Boost::math_c99l'
-- Conan: Component target declared 'Boost::math_tr1'
-- Conan: Component target declared 'Boost::math_tr1f'
-- Conan: Component target declared 'Boost::math_tr1l'
-- Conan: Component target declared 'Boost::program_options'
-- Conan: Component target declared 'Boost::regex'
-- Conan: Component target declared 'Boost::serialization'
-- Conan: Component target declared 'Boost::stacktrace'
-- Conan: Component target declared 'Boost::stacktrace_addr2line'
-- Conan: Component target declared 'Boost::stacktrace_backtrace'
-- Conan: Component target declared 'Boost::stacktrace_basic'
-- Conan: Component target declared 'Boost::stacktrace_noop'
-- Conan: Component target declared 'Boost::system'
-- Conan: Component target declared 'Boost::test'
-- Conan: Component target declared 'Boost::test_exec_monitor'
-- Conan: Component target declared 'Boost::url'
-- Conan: Component target declared 'Boost::wserialization'
-- Conan: Component target declared 'Boost::chrono'
-- Conan: Component target declared 'Boost::coroutine'
-- Conan: Component target declared 'Boost::filesystem'
-- Conan: Component target declared 'Boost::json'
-- Conan: Component target declared 'Boost::nowide'
-- Conan: Component target declared 'Boost::prg_exec_monitor'
-- Conan: Component target declared 'Boost::random'
-- Conan: Component target declared 'Boost::thread'
-- Conan: Component target declared 'Boost::timer'
-- Conan: Component target declared 'Boost::type_erasure'
-- Conan: Component target declared 'Boost::unit_test_framework'
-- Conan: Component target declared 'Boost::wave'
-- Conan: Component target declared 'Boost::contract'
-- Conan: Component target declared 'Boost::fiber'
-- Conan: Component target declared 'Boost::fiber_numa'
-- Conan: Component target declared 'Boost::graph'
-- Conan: Component target declared 'Boost::iostreams'
-- Conan: Component target declared 'Boost::locale'
-- Conan: Component target declared 'Boost::log'
-- Conan: Component target declared 'Boost::log_setup'
-- Conan: Target declared 'boost::boost'
-- Conan: Target declared 'BZip2::BZip2'
-- Conan: Including build module from '/home/conan/.conan/data/bzip2/1.0.8/_/_/package/c32092bf4d4bb47cf962af898e02823f499b017e/lib/cmake/conan-official-bzip2-variables.cmake'
-- Conan: Target declared 'ZLIB::ZLIB'
-- Conan: Target declared 'libbacktrace::libbacktrace'
-- Configuring done
-- Generating done
-- Build files have been written to: /home/conan/project/build_linux
Scanning dependencies of target log_demo
[ 50%] Building CXX object CMakeFiles/log_demo.dir/log_demo.cpp.o
[100%] Linking CXX executable log_demo
[100%] Built target log_demo
$ ./log_demo 
[2023-01-31 08:42:44.851824] [0x0000004001b498c0] [debug]   This is debug

请注意,我使用的包 ID 与您的日志中的相同,这意味着我们使用的是完全相同的包配置。

关于c++ - Conan + CMake + C++ : Linking against Boost. 记录静态库失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75292878/

相关文章:

c++ - 如何强制 cmake 在没有完整路径的情况下使用 cl.exe?

c++ - (target_)link_libraries 和 (target_)include_directories 之间的区别

c++ - 未找到重载函数

c++ - 不旋转包装矩形?

c++ - 无法在 boost spirit 中指定 skipper (编译器错误)

c++ - 为什么这段使用 `::boost::bind` 的代码会出现编译错误?

c++ - 模板类的成员函数指针

C++ LNK2001 : unresolved external symbol problem

c++ - 如何学习编写地道的 C++ 代码

c++ - CMake 链接错误(collect2 : ld returned 1 exit status)