linker error while linking boost log tutorial (und

2019-01-07 17:52发布

问题:

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

回答1:

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


回答2:

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


回答3:

-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


回答4:

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.



回答5:

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:
-- /work/cloudparc/env/include
-- Configuring done
-- Generating done

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



回答6:

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.



回答7:

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.



回答8:

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


回答9:

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.


回答10:

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.