[英]Conan + CMake + C++ : Linking against Boost.Log static library fails
我正在嘗試使用 Conan 和 CMake 建立一個基本的 Boost.Logging 演示項目。
我在 Ubuntu 22.04.1 上使用柯南 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
我正在使用柯南“工具鏈”開發人員流程,正如文檔所推薦的那樣。 這就是我使用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)
請注意,我選擇了 static 庫,它與 conanfile.txt 中的[options]
/ boost:shared=False
選擇conanfile.txt
。
最后,我的實際代碼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;
}
我調用柯南來獲得提升:
$ 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
go 錯誤的地方在於鏈接 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
這個 linker 錯誤 - undefined reference to 'boost::log::v2s_mt_posix::trivial::logger::get()'
- 似乎對很多人來說都是如此。 有許多建議的變通方法和技巧,但我試圖找到一種可行的方法,但都沒有成功。 顯然,此錯誤與嘗試鏈接 Boost 的static庫有關,這實際上是我想要的。
我嘗試了 CMake 的-v
選項,以查看 linker 命令是什么:
$ 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
請注意,我使用的那些 package ID 與您的日志中的相同,這意味着,我們使用的是完全相同的包配置。
正如 uilianries 所解釋的那樣,您正在使用將構建類型設置為 Release 的默認配置文件。 要輕松更改其構建類型,您可以使用以下命令:
$ conan profile update settings.build_type=Debug default
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.