Michael Große
Michael Große

Reputation: 1896

linker error while linking boost log tutorial (undefined references)

I have installed boost on Fedora 20 via yum and am trying some simple examples. However I have trouble to compile the first example from the logging tutorial.

Compiling with g++ -c boosttest.cc works fine, but I get lot's of errors when I try to link it with

g++ boosttest.o -o boosttest -lboost_log -lpthread

the full error-log:

boosttest.o: In function `main':
boosttest.cc:(.text+0x44): undefined reference to `boost::log::v2s_mt_posix::trivial::logger::get()'
boosttest.cc:(.text+0x9a): undefined reference to `boost::log::v2s_mt_posix::trivial::logger::get()'
boosttest.cc:(.text+0x167): undefined reference to `boost::log::v2s_mt_posix::trivial::logger::get()'
boosttest.cc:(.text+0x1bd): undefined reference to `boost::log::v2s_mt_posix::trivial::logger::get()'
boosttest.cc:(.text+0x28a): undefined reference to `boost::log::v2s_mt_posix::trivial::logger::get()'
boosttest.o:boosttest.cc:(.text+0x2e0): more undefined references to `boost::log::v2s_mt_posix::trivial::logger::get()' follow
boosttest.o: In function `boost::log::v2s_mt_posix::record::reset()':
boosttest.cc:(.text._ZN5boost3log12v2s_mt_posix6record5resetEv[_ZN5boost3log12v2s_mt_posix6record5resetEv]+0x18): undefined reference to `boost::log::v2s_mt_posix::record_view::public_data::destroy(boost::log::v2s_mt_posix::record_view::public_data const*)'
boosttest.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>, void, void, void, void, void, void, void, void, void> >::open_record<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<boost::log::v2s_mt_posix::keywords::tag::severity, boost::log::v2s_mt_posix::trivial::severity_level const> const&)':
boosttest.cc:(.text._ZN5boost3log12v2s_mt_posix7sources22basic_composite_loggerIcNS2_18severity_logger_mtINS1_7trivial14severity_levelEEENS2_18multi_thread_modelINS1_3aux14light_rw_mutexEEENS2_8featuresINS2_8severityIS6_EEvvvvvvvvvEEE11open_recordINS_9parameter3aux15tagged_argumentINS1_8keywords3tag8severityEKS6_EEEENS1_6recordERKT_[_ZN5boost3log12v2s_mt_posix7sources22basic_composite_loggerIcNS2_18severity_logger_mtINS1_7trivial14severity_levelEEENS2_18multi_thread_modelINS1_3aux14light_rw_mutexEEENS2_8featuresINS2_8severityIS6_EEvvvvvvvvvEEE11open_recordINS_9parameter3aux15tagged_argumentINS1_8keywords3tag8severityEKS6_EEEENS1_6recordERKT_]+0x1e): undefined reference to `boost::log::v2s_mt_posix::core::get_logging_enabled() const'
boosttest.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()':
boosttest.cc:(.text._ZN5boost3log12v2s_mt_posix3aux11record_pumpINS1_7sources18severity_logger_mtINS1_7trivial14severity_levelEEEED2Ev[_ZN5boost3log12v2s_mt_posix3aux11record_pumpINS1_7sources18severity_logger_mtINS1_7trivial14severity_levelEEEED5Ev]+0x2c): undefined reference to `boost::log::v2s_mt_posix::aux::unhandled_exception_count()'
boosttest.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&)':
boosttest.cc:(.text._ZN5boost3log12v2s_mt_posix3aux11record_pumpINS1_7sources18severity_logger_mtINS1_7trivial14severity_levelEEEEC2ERS8_RNS1_6recordE[_ZN5boost3log12v2s_mt_posix3aux11record_pumpINS1_7sources18severity_logger_mtINS1_7trivial14severity_levelEEEEC5ERS8_RNS1_6recordE]+0x1d): undefined reference to `boost::log::v2s_mt_posix::aux::stream_provider<char>::allocate_compound(boost::log::v2s_mt_posix::record&)'
boosttest.cc:(.text._ZN5boost3log12v2s_mt_posix3aux11record_pumpINS1_7sources18severity_logger_mtINS1_7trivial14severity_levelEEEEC2ERS8_RNS1_6recordE[_ZN5boost3log12v2s_mt_posix3aux11record_pumpINS1_7sources18severity_logger_mtINS1_7trivial14severity_levelEEEEC5ERS8_RNS1_6recordE]+0x28): undefined reference to `boost::log::v2s_mt_posix::aux::unhandled_exception_count()'
boosttest.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()':
boosttest.cc:(.text._ZN5boost3log12v2s_mt_posix3aux11record_pumpINS1_7sources18severity_logger_mtINS1_7trivial14severity_levelEEEE12auto_releaseD2Ev[_ZN5boost3log12v2s_mt_posix3aux11record_pumpINS1_7sources18severity_logger_mtINS1_7trivial14severity_levelEEEE12auto_releaseD5Ev]+0xf): 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*)'
boosttest.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)':
boosttest.cc:(.text._ZN5boost3log12v2s_mt_posix7sources3aux14severity_levelINS1_7trivial14severity_levelEE9set_valueES6_[_ZN5boost3log12v2s_mt_posix7sources3aux14severity_levelINS1_7trivial14severity_levelEE9set_valueES6_]+0x7): undefined reference to `boost::log::v2s_mt_posix::sources::aux::get_severity_level()'
boosttest.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<boost::log::v2s_mt_posix::keywords::tag::severity, boost::log::v2s_mt_posix::trivial::severity_level const> >(boost::parameter::aux::tagged_argument<boost::log::v2s_mt_posix::keywords::tag::severity, boost::log::v2s_mt_posix::trivial::severity_level const> const&)':
boosttest.cc:(.text._ZN5boost3log12v2s_mt_posix7sources12basic_loggerIcNS2_18severity_logger_mtINS1_7trivial14severity_levelEEENS2_18multi_thread_modelINS1_3aux14light_rw_mutexEEEE20open_record_unlockedINS_9parameter3aux15tagged_argumentINS1_8keywords3tag8severityEKS6_EEEENS1_6recordERKT_[_ZN5boost3log12v2s_mt_posix7sources12basic_loggerIcNS2_18severity_logger_mtINS1_7trivial14severity_levelEEENS2_18multi_thread_modelINS1_3aux14light_rw_mutexEEEE20open_record_unlockedINS_9parameter3aux15tagged_argumentINS1_8keywords3tag8severityEKS6_EEEENS1_6recordERKT_]+0x2a): undefined reference to `boost::log::v2s_mt_posix::core::open_record(boost::log::v2s_mt_posix::attribute_set const&)'
boosttest.o: In function `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> >::push_record_unlocked(boost::rv<boost::log::v2s_mt_posix::record>&)':
boosttest.cc:(.text._ZN5boost3log12v2s_mt_posix7sources12basic_loggerIcNS2_18severity_logger_mtINS1_7trivial14severity_levelEEENS2_18multi_thread_modelINS1_3aux14light_rw_mutexEEEE20push_record_unlockedERNS_2rvINS1_6recordEEE[_ZN5boost3log12v2s_mt_posix7sources12basic_loggerIcNS2_18severity_logger_mtINS1_7trivial14severity_levelEEENS2_18multi_thread_modelINS1_3aux14light_rw_mutexEEEE20push_record_unlockedERNS_2rvINS1_6recordEEE]+0x36): 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

What am I missing? What am I doing wrong?

EDIT 1: The order of -lboost_log -lpthread makes no difference in the output. There is also a very similar question, but the solution does not work for me. The following also fails with the same errors:

g++ -DBOOST_LOG_DYN_LINK boosttest.o -o boosttest -lboost_log -lpthread

Upvotes: 68

Views: 50738

Answers (15)

Patrizio Bertoni
Patrizio Bertoni

Reputation: 2732

In addition to the other responses, I'd point out that some modern systems (e.g. boost 1.83 on Ubuntu 24.04) may suggest you to use

find_package (Boost CONFIG)

Instead of

find_package (Boost COMPONENTS log ... log_setup REQUIRED)

Because the latter would print out

CMake Warning (dev) at CMakeLists.txt:29 (find_package): Policy CMP0167 is not set: The FindBoost module is removed. Run "cmake --help-policy CMP0167" for policy details. Use the cmake_policy command to set the policy and suppress this warning. This warning is for project developers. Use -Wno-dev to suppress it.

However, despite it was building my project before logging insertion, I had to add also the latter.

Upvotes: 0

Francesco Garbin
Francesco Garbin

Reputation: 61

Given some trivial logging code in some main.cpp such as:

#include <iostream>
#define BOOST_LOG_DYN_LINK 1 #defined before log headers
#include <boost/log/trivial.hpp>

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

You can compile with:

g++ main.cpp -lboost_log -lboost_system -lboost_thread -lpthread -o main

Make sure to #define BOOST_LOG_DYN_LINK before including boost/log headers.

Upvotes: 1

67hz
67hz

Reputation: 431

You can avoid flags if you only need a static compilation. In that case just include the log and log_setup components in CMake.

set(Boost_USE_STATIC_LIBS ON)

find_package(Boost 1.67.0 COMPONENTS log log_setup REQUIRED)
if(Boost_FOUND)
    target_link_libraries(YourExecutable ${Boost_LIBRARIES})
endif()

Upvotes: 3

GPrathap
GPrathap

Reputation: 7820

I also had this error, if you are using CMake you may able to resolve this issue in the following way,

  1. Finding related packages: log log_setup

    find_package(Boost COMPONENTS program_options log log_setup REQUIRED)

2.Append log and log_setup into other libs:

  set(PROJECT_LIB ${PROJECT_LIB} ${Boost_LOG_LIBRARY} ${Boost_LOG_SETUP_LIBRARY})
  1. Link those libraries into your program,

    target_link_libraries(${PROJECT_NAME} -Wl,--start-group ${PROJECT_LIB} -Wl,--end-group)

  2. Add DBOOST_LOG_DYN_LINK into CMAKE_CXX_FLAGS flags

    set(CMAKE_CXX_FLAGS "-Wall -Wextra -fPIC -fopenmp -DBOOST_LOG_DYN_LINK")

Upvotes: 10

stdcerr
stdcerr

Reputation: 15668

I'm using cmake and get the same error on make, I inserted set (CMAKE_CXX_FLAGS "-g -Wall -DBOOST_LOG_DYN_LINK") into my CMakeLists.txt to make it look like:

cmake_minimum_required(VERSION 2.6)
project(LOGGER)

set(BOOST_INCLUDEDIR "/path/to/env/include")
set(BOOST_ROOT "/path/to/env/include")

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")

which creates this output:

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

Mind that Boost_LIBRARIES stays empty for some reason... :o

Upvotes: 3

antoxar
antoxar

Reputation: 51

If u want to link boost logging statically u need to be accurate with _WIN32_WINNT and BOOST_LOG_NO_THREADS settings during boost compilation and setting of project u gonna use logging with.

The following snippet in boost\1.67.0\include\boost\log\detail\config.hpp explains how namespace for logging got chosen.

If u not sure how boost got compiled, try to open library in hex editor and find stream provider.

std@@@attributes@v2s_mt_nt6@log@1@_N@Z.??0stream_compound@?$stream_provider

Snippet bellow describes shows what linker is asking for.

// Setup namespace name
#if !defined(BOOST_LOG_DOXYGEN_PASS)
#   if defined(BOOST_LOG_DLL)
#       if defined(BOOST_LOG_NO_THREADS)
#           define BOOST_LOG_VERSION_NAMESPACE v2_st
#       else
#           if defined(BOOST_THREAD_PLATFORM_PTHREAD)
#               define BOOST_LOG_VERSION_NAMESPACE v2_mt_posix
#           elif defined(BOOST_THREAD_PLATFORM_WIN32)
#               if BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6
#                   define BOOST_LOG_VERSION_NAMESPACE v2_mt_nt6
#               else
#                   define BOOST_LOG_VERSION_NAMESPACE v2_mt_nt5
#               endif
#           else
#               define BOOST_LOG_VERSION_NAMESPACE v2_mt
#           endif
#       endif // defined(BOOST_LOG_NO_THREADS)
#   else
#       if defined(BOOST_LOG_NO_THREADS)
#           define BOOST_LOG_VERSION_NAMESPACE v2s_st
#       else
#           if defined(BOOST_THREAD_PLATFORM_PTHREAD)
#               define BOOST_LOG_VERSION_NAMESPACE v2s_mt_posix
#           elif defined(BOOST_THREAD_PLATFORM_WIN32)
#               if BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6
#                   define BOOST_LOG_VERSION_NAMESPACE v2s_mt_nt6
#               else
#                   define BOOST_LOG_VERSION_NAMESPACE v2s_mt_nt5
#               endif
#           else
#               define BOOST_LOG_VERSION_NAMESPACE v2s_mt
#           endif
#       endif // defined(BOOST_LOG_NO_THREADS)
#   endif // defined(BOOST_LOG_DLL)

Upvotes: 0

lazzlo
lazzlo

Reputation: 35

If you want link boost.log statically then maybe you need do this (libraries in this order)

g++ main.cpp -static -lboost_log -lboost_system -lboost_thread -lpthread -o main

Upvotes: 3

palik
palik

Reputation: 2873

-lboost_log_setup solved the issue for me.

I borrowed it from spdlog bench Makefile

g++ -std=c++11 -Wall -pedantic -g -O0 -DBOOST_LOG_DYN_LINK  -c boost-bench-mt.cpp
g++ boost-bench-mt.o  -lpthread -lboost_log -lboost_log_setup  -lboost_system -lboost_thread -o boost-bench-mt

Upvotes: 5

user2394303
user2394303

Reputation:

actually, only g++ -DBOOST_ALL_DYN_LINK -lpthread -lboost_log-mt logging_test.cpp works for me. DBOOST_LOG_DYN_LINK or -lboost_log got the same error.

Upvotes: 2

Loach Fish
Loach Fish

Reputation: 11

Someone addvise to add the cflag BOOST_LOG_DYN_LINK. I think it is not all the truth.

To use the libboost_log, you should to know the cxxflag of the library when it build. Maybe the flag BOOST_LOG_DYN_LINK is not added into the build.

You should take care of the file boost/log/detail/config.hpp about the BOOST_LOG_VERSION_NAMESPACE.

Anyway you should keep the same boost_log_version_namespace with the libboost_log that linked.

To check the boost_log_version_namespace can use the command: nm -C libboost_log | grep push_record_move

push_record_move is one function of boost_log, it will output,like this, boost::log::v2s_mt_posix::core::push_record_move(boost::log::v2s_mt_posix::record&)

v2s_mt_posix is the boost_log_version_namespace.

Upvotes: -1

user4062498
user4062498

Reputation: 71

I had the same annoying problem. The macro should be defined while compiling, not linking:

g++ -std=c++11 -DBOOST_LOG_DYN_LINK -c boosttest.cc

In the linker command, make sure the order is as follows:

g++ boosttest.o -lboost_log -lpthread -o boosttest

Upvotes: 7

silgon
silgon

Reputation: 7221

You just need to add the BOOST_LOG_DYN_LINK definition. So, in one-liner command like so:

g++ -DBOOST_LOG_DYN_LINK logging_test.cpp -lboost_log -lpthread

With that command it should be running now.

Upvotes: 2

Tony BenBrahim
Tony BenBrahim

Reputation: 7300

Look at Mark Lakata's answer in Boost logger linking issue

My problem, and probably Michael's problem, is indeed the presence of both .dylib and .a in /usr/local/lib. Since I do not plan to ever link boost dynamically, running sudo rm -f /usr/local/lib/libboost_*.dylib solved the problem and let me link statically. The program I am working on is for redistribution, and I want to distribute one executable without dependencies, so other solutions on this page were not workable. If that is not acceptable, you could also specify the full path to the lib, like -l/usr/include/lib/libboost_log.a, but that results in system dependent makefiles.

Upvotes: 3

Adrian Heine
Adrian Heine

Reputation: 4141

Just add a line

#define BOOST_LOG_DYN_LINK 1

as the first line of boosttest.cc.

Alternatively, you can add -DBOOST_LOG_DYN_LINK to you compilation step (not the linking step, as you posted in the question):

g++ -std=c++11 -Wall -pedantic -g -O0 -DBOOST_LOG_DYN_LINK  -c boosttest.cc
g++  boosttest.o -lpthread -lboost_log -o boosttest

Upvotes: 95

doptimusprime
doptimusprime

Reputation: 9411

It simply means that boost-log library is not linked properly. Also, order in GCC does matter. Refer to this question.

  1. First ensure that the library is properly built and it has all the symbols.
  2. Try to change the order. It might help you.

Upvotes: 0

Related Questions