undefined ссылка на boost :: system :: system_category () при компиляции

105

Я пытаюсь скомпилировать программу на Ubuntu 11.10, которая использует библиотеки Boost. У меня установлены библиотеки Boost 1.46-dev из репозитория Ubuntu, но я получаю сообщение об ошибке при компиляции программы.

undefined reference to boost::system::system_category()

Что я делаю не так?

user1049697
источник
6
Это не ошибка компилятора, это ошибка компоновщика . Вам нужно сделать ссылку на библиотеку Boost.System.
ildjarn

Ответы:

160

Библиотека boost, которую вы используете, зависит от библиотеки boost_system. (Не все из них.)

Предполагая, что вы используете gcc, попробуйте добавить -lboost_systemв командную строку вашего компилятора, чтобы связать его с этой библиотекой.

hc_
источник
3
Для компиляции я использую Makefile g ++. Где обычно ставят такие флажки?
user1049697
2
Способы сборки командной строки компилятора / компоновщика сильно различаются от случая к случаю. Почему бы вам не вставить свой Makefile (или соответствующие его части) в свой вопрос? Таким образом, вы можете получить ответ, который работает в вашем конкретном случае.
hc_
7
Хорошо, я редактировал Makefile.am и добавил -lboost_system, так это выглядело так: sslsniff_LDFLAGS = -lssl -lboost_filesystem -lpthread -lboost_thread -llog4cpp -lboost_system. Но это не помогло ...
user1049697
1
Все еще та же ошибка? Вы autoreconfпотом бежали ? Кроме того , этот пост и это один может помочь вам с вашей конфигурацией Autotools.
hc_
2
Я заменил sslsniff_LDFLAGSс sslsniff_LDADDв Makefile.am и это не сработало. Потом я сохранил оба sslsniff_LDFLAGSи добавил sslsniff_LDADD = -lboost_system -lssl -lboost_filesystem -lpthread -lboost_thread -llog4cpp. Потом я смог скомпилировать. Спасибо вам за помощь!
user1049697
62

Связывание с библиотекой , которая определяет недостающий символ ( -lboost_system) является очевидным решением, но в данном конкретном случае Boost.System, ошибочная особенность в оригинальном дизайне делает его использовать boost::system::generic_category()и boost::system::system_category()без необходимости. Компиляция с флагом -DBOOST_SYSTEM_NO_DEPRECATEDотключает этот код и позволяет нескольким программам компилироваться без необходимости -lboost_system(эта ссылка, конечно, все еще необходима, если вы явно используете некоторые функции библиотеки).

Начиная с Boost 1.66 и этого коммита , это поведение теперь является значением по умолчанию, поэтому, надеюсь, все меньше и меньше пользователей будут нуждаться в этом ответе.

Как заметил @AndrewMarshall, альтернативой является определение, BOOST_ERROR_CODE_HEADER_ONLYкоторое включает версию кода только для заголовков. Это был обескуражен буста , как это может нарушить некоторые функциональные возможности . Однако, начиная с версии 1.69, по-видимому, по умолчанию используется только заголовок, что , предположительно, делает этот вопрос устаревшим.

Марк Глисс
источник
4
Спасибо!!! ничего не помогло, так как я использую boost 1.41 (Centos SL), единственное, что меня освободило, - это использование -DBOOST_SYSTEM_NO_DEPRECATED
Roger Rabbit
5
На самом деле то, что вам может понадобиться, это -DBOOST_ERROR_CODE_HEADER_ONLY
Эндрю Маршалл,
1
Интересно, что новое поведение Boost 1.66 с меньшим количеством ссылок на system_category () и т. Д. Может привести к появлению новых проблем со ссылками при наличии проблем с упорядочением ссылок. См github.com/PointCloudLibrary/pcl/pull/2236 , например
pixelbeat
3
Если вы используете CMake, просто добавьте add_definitions (-DBOOST_ERROR_CODE_HEADER_ONLY)
николай
1
Единственное исправление, которое у меня сработало с Boost 1.68, - это определение BOOST_ERROR_CODE_HEADER_ONLY.
sakra
17

Еще один обходной путь для тех, кому не нужен весь шебанг: используйте переключатель

-DBOOST_ERROR_CODE_HEADER_ONLY.

Если вы используете CMake, это add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY).

Вадим Берман
источник
1
Я недавно столкнулся с этой проблемой. Ничего не работает кроме этого. Интересно, обескураживает ли это повышение, как упомянуто в ответе Марка Глисса.
Джон З. Ли
1
quote "Boost.System теперь работает только с заголовком. Библиотека-заглушка все еще создается для совместимости, но связывание с ней больше не требуется."
Джон З. Ли
16

Вышеупомянутая ошибка является ошибкой компоновщика ... компоновщик - это программа, которая берет один или несколько объектов, сгенерированных компилятором, и объединяет их в одну исполняемую программу.

Вы должны добавить -lboost_systemк вам флаги компоновщика, которые указывают компоновщику, что он должен искать символы, как boost::system::system_category()в библиотеке libboost_system.so.

Если у вас есть main.cpp, либо:

g++ main.cpp -o main -lboost_system

ИЛИ

g++ -c -o main.o main.cpp
g++ main.o -lboost_system
user1055604
источник
5
пробел между -l и именем библиотеки неверен. вы должны использовать -lboost_system
portforwardpodcast
1
Я обнаружил, что centos не заботится о положении -l, но ubuntu должно быть в конце.
ask_io 03
7

При использовании CMAKE и find_package убедитесь, что это:

find_package(Boost COMPONENTS system ...)

и нет

find_package(boost COMPONENTS system ...)

Некоторые люди могли потерять из-за этого часы ...

Kriegalex
источник
6

У меня та же проблема:

g++ -mconsole -Wl,--export-all-symbols -LC:/Programme/CPP-Entwicklung/MinGW-4.5.2/lib  -LD:/bfs_ENTW_deb/lib   -static-libgcc -static-libstdc++ -LC:/Programme/CPP-Entwicklung/boost_1_47_0/stage/lib   \
 D:/bfs_ENTW_deb/obj/test/main_filesystem.obj \
 -o D:/bfs_ENTW_deb/bin/filesystem.exe -lboost_system-mgw45-mt-1_47 -lboost_filesystem-mgw45-mt-1_47

D: /bfs_ENTW_deb/obj/test/main_filesystem.obj: main_filesystem.cpp :(. Text + 0x54): неопределенная ссылка на `boost :: system :: generic_category ()

Решением было использовать отладочную версию системной библиотеки:

g++ -mconsole -Wl,--export-all-symbols -LC:/Programme/CPP-Entwicklung/MinGW-4.5.2/lib  -LD:/bfs_ENTW_deb/lib   -static-libgcc -static-libstdc++ -LC:/Programme/CPP-Entwicklung/boost_1_47_0/stage/lib   \
 D:/bfs_ENTW_deb/obj/test/main_filesystem.obj \
 -o D:/bfs_ENTW_deb/bin/filesystem.exe -lboost_system-mgw45-mt-d-1_47 -lboost_filesystem-mgw45-mt-1_47

Но почему?

Волкер
источник
1
Может быть, где-то был определен какой-то флаг отладки, поэтому у вас были другие библиотеки, встроенные в отладку, или g ++ создавал obj отладки?
noonex
4

Когда у меня возникла эта проблема, причиной был порядок библиотек. Чтобы исправить это, я поставил libboost_systemпоследним:

g++ mingw/timer1.o -o mingw/timer1.exe  -L/usr/local/boost_1_61_0/stage/lib \
    -lboost_timer-mgw53-mt-1_61 \
    -lboost_chrono-mgw53-mt-1_61 \
    -lboost_system-mgw53-mt-1_61

Это было на mingw с gcc 5.3 и boost 1.61.0 с простым примером таймера.

Мин Чжан
источник
1
Это тоже была моя проблема. Я включил его через CMake, и по какой-то причине предполагаемые зависимости и порядок были определены в скрипте FindBoost. На самом деле, моя проблема заключалась в том, что я всегда использовал разделяемые библиотеки и никогда не обращал внимания, а затем переходил к статическим библиотекам и получал ошибки сборки. Ой.
Энтони
Это исправило это и для меня ... до этого решения единственное, что работало, - это определение BOOST_ERROR_CODE_HEADER_ONLY. В Ubuntu 18.04 увеличьте 1.68 с помощью cmake. Мое исправление: target_link_libraries (исполняемый pthread ssl crypto boost_system)
Луис,
2

в моем случае добавления -lboost_systemбыло недостаточно, он все еще не мог найти его в моей пользовательской среде сборки. Мне пришлось воспользоваться советом Избавьтесь от «gcc - / usr / bin / ld: warning lib not found» и измените мою ./configureкоманду на:

./configure CXXFLAGS="-I$HOME/include" LDFLAGS="-L$HOME/lib -Wl,-rpath-link,$HOME/lib" --with-boost-libdir=$HOME/lib --prefix=$HOME

для получения дополнительных сведений см. Boost 1.51: «ошибка: не удалось связать с boost_thread!»

jcomeau_ictx
источник
1

... и если вы хотите связать свой основной статически, добавьте в свой Jamfile следующие требования:

<link>static
<library>/boost/system//boost_system

и, возможно, также:

<linkflags>-static-libgcc
<linkflags>-static-libstdc++
Formiaczek
источник