Ошибка компоновщика при связывании учебника будильника (undefined ссылки)
Я установил boost на Fedora 20 через yum и пробую некоторые простые примеры. Однако мне сложно скомпилировать первый пример из учебного журнала.
Компиляция с g++ -c boosttest.cc
отлично работает, но я получаю много ошибок, когда пытаюсь связать ее с
g++ boosttest.o -o boosttest -lboost_log -lpthread
полный журнал ошибок:
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
Что мне не хватает? Что я делаю неправильно?
EDIT 1: Порядок -lboost_log -lpthread
не влияет на вывод. Существует также очень похожий вопрос, но решение для меня не работает. Следующее также терпит неудачу с теми же ошибками:
g++ -DBOOST_LOG_DYN_LINK boosttest.o -o boosttest -lboost_log -lpthread
Ответы
Ответ 1
Просто добавьте строку
#define BOOST_LOG_DYN_LINK 1
как первая строка boosttest.cc
.
В качестве альтернативы вы можете добавить -DBOOST_LOG_DYN_LINK
к вашему этапу компиляции (а не к шагу привязки, как вы разместили в вопросе):
g++ -std=c++11 -Wall -pedantic -g -O0 -DBOOST_LOG_DYN_LINK -c boosttest.cc
g++ boosttest.o -lpthread -lboost_log -o boosttest
Ответ 2
У меня была такая же неприятная проблема.
Макрос должен быть определен при компиляции, а не в ссылке:
g++ -std=c++11 -DBOOST_LOG_DYN_LINK -c boosttest.cc
В команде компоновщика убедитесь, что порядок выглядит следующим образом:
g++ boosttest.o -lboost_log -lpthread -o boosttest
Ответ 3
-lboost_log_setup
решил проблему для меня.
Я взял его из 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
Посмотрите на ответ Марка Лаката в Устранить проблему связывания журналов
Моя проблема и, вероятно, проблема Михаэля, действительно есть как .dylib, так и .a в /usr/local/lib. Поскольку я не планирую динамически связывать динамику, запуск sudo rm -f /usr/local/lib/libboost_*.dylib
решает проблему и позволяет мне связывать статически. Программа, над которой я работаю, предназначена для перераспределения, и я хочу распространять один исполняемый файл без зависимостей, поэтому другие решения на этой странице не были работоспособны.
Если это неприемлемо, вы также можете указать полный путь к lib, например -l/usr/include/lib/libboost_log.a, но это приводит к зависящим от системы make файлам.
Ответ 5
Вам просто нужно добавить определение BOOST_LOG_DYN_LINK
. Итак, в команде с одним слоем:
g++ -DBOOST_LOG_DYN_LINK logging_test.cpp -lboost_log -lpthread
С помощью этой команды он должен быть запущен.
Ответ 6
Я использую cmake
и получаю ту же ошибку на make
, я вставил set (CMAKE_CXX_FLAGS "-g -Wall -DBOOST_LOG_DYN_LINK")
в мой CMakeLists.txt
чтобы он выглядел так:
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")
который создает этот вывод:
-- 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
Имейте в виду, что Boost_LIBRARIES
по какой-то причине остается пустым...: o
Ответ 7
Кто-то добавляет, чтобы добавить cflag BOOST_LOG_DYN_LINK. Я думаю, что это не вся правда.
Чтобы использовать libboost_log, вы должны знать cxxflag библиотеки при ее создании. Возможно, флаг BOOST_LOG_DYN_LINK не добавлен в сборку.
Вы должны позаботиться о файле
boost/log/detail/config.hpp о BOOST_LOG_VERSION_NAMESPACE.
В любом случае вы должны сохранить такое же boost_log_version_namespace с связанным с ним libboost_log.
Для проверки области boost_log_version_namespace можно использовать команду:
nm -C libboost_log | grep push_record_move
push_record_move - это одна из функций boost_log, она будет выводиться, например,
повышение:: войти:: v2s_mt_posix:: основной:: push_record_move (повышение:: войти:: v2s_mt_posix:: запись &)
v2s_mt_posix - это пространство boost_log_version_namespace.
Ответ 8
Если вам нужна ссылка boost.log статически, возможно, вам нужно сделать это (библиотеки в этом порядке)
g++ main.cpp -static -lboost_log -lboost_system -lboost_thread -lpthread -o main
Ответ 9
Это просто означает, что библиотека boost-log не связана должным образом. Кроме того, заказ в GCC имеет значение. Обратитесь к этому question.
- Сначала убедитесь, что библиотека правильно построена и у нее есть все символы.
- Попробуйте изменить порядок. Это может помочь вам.
Ответ 10
на самом деле, только g++ -DBOOST_ALL_DYN_LINK -lpthread -lboost_log-mt logging_test.cpp
работает для меня. DBOOST_LOG_DYN_LINK
или -lboost_log
получили ту же ошибку.
Ответ 11
Если вы хотите статически связать лог-буст, вам нужно быть точным с настройками _WIN32_WINNT и BOOST_LOG_NO_THREADS во время компиляции буста и настройки проекта, с которыми вы будете использовать логирование.
Следующий фрагмент в boost\1.67.0\include\boost\log\detail\config.hpp объясняет, как было выбрано пространство имен для ведения журнала.
Если вы не уверены, как boost скомпилирован, попробуйте открыть библиотеку в hex-редакторе и найти поставщика потоков.
std @@@attribute @v2s_mt_nt6 @log @1 @_N @Z.?? 0stream_compound @? $ stream_provider
Ниже приведен фрагмент описания того, что запрашивает компоновщик.
// 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)
Ответ 12
У меня также была эта ошибка, если вы используете CMake, вы можете решить эту проблему следующим образом,
-
Поиск связанных пакетов: log log_setup
find_package(Boost COMPONENTS program_options log log_setup REQUIRED)
2. Добавьте log и log_setup в другие библиотеки:
set(PROJECT_LIB ${PROJECT_LIB} ${Boost_LOG_LIBRARY} ${Boost_LOG_SETUP_LIBRARY})
-
Свяжите эти библиотеки в свою программу,
target_link_libraries(${PROJECT_NAME} -Wl,--start-group ${PROJECT_LIB} -Wl,--end-group)
-
Добавьте DBOOST_LOG_DYN_LINK в флаги CMAKE_CXX_FLAGS
set(CMAKE_CXX_FLAGS "-Wall -Wextra -fPIC -fopenmp -DBOOST_LOG_DYN_LINK")