Home > Software engineering >  Conan CMake C : Linking against Boost.Log static library fails
Conan CMake C : Linking against Boost.Log static library fails

Time:01-31

I am trying to set up a basic Boost.Logging demo project, with Conan and CMake.

I'm using Conan 1.53.0 and CMake 3.22.1, with gcc-11.3.0, on Ubuntu 22.04.1.

First, I use Conan to bring in Boost 1.81, thus my conanfile.txt:

[requires]
boost/1.81.0

[options]
boost:shared=False

[generators]
CMakeDeps
CMakeToolchain

I am using the Conan "toolchain" developer flow, as recommended by the docs. That is why I'm using CMakeToolchain, and that requires CMakeDeps.

For my CMakeLists.txt I have the following:

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)

Note that I have selected static libs, which matches with the [options] / boost:shared=False selection in conanfile.txt.

Finally, my actual code, log_demo.cpp, is trivial:

#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;
}

I invoke Conan to get Boost with:

$ 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

...

This generated, amongst other files, conan_toolchain.cmake in this build directory.

Now I can invoke CMake to configure the build:

$ 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

And where things go wrong is with linking against 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

This linker error - undefined reference to 'boost::log::v2s_mt_posix::trivial::logger::get()' - occurs for a lot of people, it seems. There are many suggested workarounds and hacks, but none of my attempts to find one that works have been successful. Apparently this error relates to an attempt to link against the static libraries of Boost, which is actually what I want.

I tried the -v option for CMake, to see what the linker command is:

$ 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 
...

I see no mention of any Boost libraries on that c command line - that seems wrong to me. Why isn't there a -lboost_log and -lboost_log_setup present?

This must be the fourth time in ten years I've tried to set up Boost.Log, each time it's different (due to Conan changes, or CMake changes), so I'm hoping I'm missing something really obvious here...

CodePudding user response:

You question is well detailed in terms of steps and logs, thank you for providing such good information.

Your error comes from a configuration mismatch. Your Conan profile shows build_type=Release, but your CMake command uses Debug, you need to use the very same configuration for both. So, if you want to update it on Conan command, you need to pass conan install .. -s build_type=Debug.

Here I'm using Release, but the idea is the same, using your files we will have:

$ 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

Note those package IDs used by me are the same from your log, which means, we are using the very same configuration of packages.

CodePudding user response:

As uilianries explained, you are using default profile file which sets build type to Release. To easily change its build type you can use following command:

$ conan profile update settings.build_type=Debug default
  • Related