référence non définie à boost :: system :: system_category () lors de la compilation

105

J'essaye de compiler un programme sur Ubuntu 11.10 qui utilise les bibliothèques Boost. Les bibliothèques Boost 1.46-dev du référentiel Ubuntu sont installées, mais j'obtiens une erreur lors de la compilation du programme.

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

Qu'est-ce que je fais de mal?

user1049697
la source
6
Ce n'est pas une erreur du compilateur, c'est une erreur de l' éditeur de liens . Vous devez créer un lien vers la bibliothèque Boost.System.
ildjarn

Réponses:

160

La bibliothèque boost que vous utilisez dépend de la bibliothèque boost_system. (Tous ne le font pas.)

En supposant que vous utilisez gcc, essayez d'ajouter -lboost_systemà la ligne de commande de votre compilateur afin d'établir un lien avec cette bibliothèque.

hc_
la source
3
J'utilise un Makefile g ++ pour la compilation. Où place-t-on habituellement de tels drapeaux?
user1049697
2
L'assemblage de la ligne de commande du compilateur / éditeur de liens varie considérablement d'un cas à l'autre. Pourquoi ne collez-vous pas votre Makefile (ou les parties pertinentes de celui-ci) dans votre question? De cette façon, vous pourriez obtenir une réponse qui fonctionne dans votre cas spécifique.
hc_
7
Ok, je Makefile.am et édité ajouté -lboost_system, il ressemblait à ceci: sslsniff_LDFLAGS = -lssl -lboost_filesystem -lpthread -lboost_thread -llog4cpp -lboost_system. Cela n'a pas aidé cependant ...
user1049697
1
Toujours la même erreur? Avez-vous couru autoreconfaprès? En outre, cet article et celui-ci pourraient vous aider dans la configuration de vos autotools.
hc_
2
J'ai remplacé sslsniff_LDFLAGSpar sslsniff_LDADDMakefile.am et cela n'a PAS fonctionné. Ensuite, j'ai gardé les deux sslsniff_LDFLAGSet ajouté sslsniff_LDADD = -lboost_system -lssl -lboost_filesystem -lpthread -lboost_thread -llog4cpp. Ensuite, j'ai pu compiler. Merci pour l'aide!
user1049697
62

La liaison avec une bibliothèque qui définit le symbole manquant ( -lboost_system) est la solution évidente, mais dans le cas particulier de Boost.System, une anomalie dans la conception originale le rend utile boost::system::generic_category()et boost::system::system_category()inutile. Compiler avec l'indicateur -DBOOST_SYSTEM_NO_DEPRECATEDdésactive ce code et permet à un certain nombre de programmes de se compiler sans exiger -lboost_system(ce lien est bien sûr toujours nécessaire si vous utilisez explicitement certaines des fonctionnalités de la bibliothèque).

À partir de Boost 1.66 et de ce commit , ce comportement est maintenant la valeur par défaut, donc j'espère que de moins en moins d'utilisateurs devraient avoir besoin de cette réponse.

Comme l'a remarqué @AndrewMarshall, une alternative consiste à définir BOOST_ERROR_CODE_HEADER_ONLYce qui active une version du code en en-tête uniquement. Cela a été découragé par Boost car cela peut casser certaines fonctionnalités. Cependant, depuis 1.69, l'en-tête seul semble être devenu la valeur par défaut , ce qui rend cette question obsolète.

Marc Glisse
la source
4
Merci!!! rien n'a aidé puisque j'utilise boost 1.41 (Centos SL), la seule chose qui m'a libéré, c'est d'utiliser le -DBOOST_SYSTEM_NO_DEPRECATED
Roger Rabbit
5
En fait, ce que vous voudrez peut-être, c'est -DBOOST_ERROR_CODE_HEADER_ONLY
Andrew Marshall
1
Fait intéressant, le nouveau comportement de Boost 1.66 consistant à avoir moins de références à system_category () etc. peut introduire de nouveaux problèmes de lien en présence de problèmes d'ordre de lien. Voir github.com/PointCloudLibrary/pcl/pull/2236 par exemple
pixelbeat
3
Si vous utilisez CMake, ajoutez simplement 'add_definitions (-DBOOST_ERROR_CODE_HEADER_ONLY)'
nickolay
1
Le seul correctif qui a fonctionné pour moi avec Boost 1.68 était de définir BOOST_ERROR_CODE_HEADER_ONLY.
sakra
17

Une autre solution de contournement pour ceux qui n'ont pas besoin de tout le shebang: utilisez le commutateur

-DBOOST_ERROR_CODE_HEADER_ONLY.

Si vous utilisez CMake, c'est add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY).

Vadim Berman
la source
1
J'ai récemment rencontré ce problème. Rien ne fonctionne sauf celui-ci. Je me demande si cela est encore découragé par le boost comme mentionné dans la réponse de Marc Glisse.
John Z. Li
1
quote "Boost.System est maintenant uniquement en-tête. Une bibliothèque de stub est toujours construite pour la compatibilité, mais la liaison vers elle n'est plus nécessaire."
John Z. Li
16

L'erreur ci-dessus est une erreur de l'éditeur de liens ... l'éditeur de liens est un programme qui prend un ou plusieurs objets générés par un compilateur et les combine en un seul programme exécutable.

Vous devez ajouter des -lboost_systemindicateurs de l'éditeur de liens qui indiquent à l'éditeur de liens qu'il doit rechercher des symboles comme boost::system::system_category()dans la bibliothèque libboost_system.so.

Si vous avez main.cpp, soit:

g++ main.cpp -o main -lboost_system

OU

g++ -c -o main.o main.cpp
g++ main.o -lboost_system
user1055604
la source
5
l'espace entre -l et le nom de la bibliothèque est incorrect. vous devriez utiliser -lboost_system
portforwardpodcast
1
J'ai trouvé que centos ne se souciait pas de la position de -l mais ubuntu l'a fait, doit être à la fin.
ask_io
7

Lorsque vous utilisez CMAKE et find_package, assurez-vous que c'est:

find_package(Boost COMPONENTS system ...)

et pas

find_package(boost COMPONENTS system ...)

Certaines personnes ont peut-être perdu des heures pour ça ...

Kriegalex
la source
6

J'ai le même problème:

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): référence non définie à `boost :: system :: generic_category ()

La solution était d'utiliser la version debug de la bibliothèque système:

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

Mais pourquoi?

volker
la source
1
Est-ce que quelque part a été défini un indicateur de débogage, donc vous aviez d'autres bibliothèques intégrées au débogage ou g ++ produisait un obj de débogage?
noonex
4

Quand j'ai eu ce problème, la cause était la commande des bibliothèques. Pour y remédier, j'ai mis en libboost_systemdernier:

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

C'était sur mingw avec gcc 5.3 et boost 1.61.0 avec un simple exemple de minuterie.

Min Zhang
la source
1
C'était aussi mon problème. Je l'ai inclus via CMake et, pour une raison quelconque, les dépendances et l'ordre supposés ont été élaborés dans le script FindBoost. Vraiment, cependant, mon problème était toujours d'utiliser des bibliothèques partagées et de ne jamais prêter attention, puis de passer aux bibliothèques statiques et d'obtenir des erreurs de construction. Oups.
Anthony
Cela m'a aussi corrigé ... avant cette solution, la seule chose qui fonctionnait était de définir BOOST_ERROR_CODE_HEADER_ONLY. Sur Ubuntu 18.04, augmentez 1.68, avec cmake. Mon correctif: target_link_libraries (exécutable pthread ssl crypto boost_system)
Luis
2

dans mon cas, l'ajout -lboost_systemn'était pas suffisant, il ne pouvait toujours pas le trouver dans mon environnement de construction personnalisé. J'ai dû utiliser les conseils de Débarrassez-vous de "gcc - / usr / bin / ld: warning lib not found" et changez ma ./configurecommande en:

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

pour plus de détails, voir Boost 1.51: "erreur: impossible de se lier à boost_thread!"

jcomeau_ictx
la source
1

... et au cas où vous voudriez lier votre main de manière statique, dans votre Jamfile ajoutez ce qui suit aux exigences:

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

et peut-être aussi:

<linkflags>-static-libgcc
<linkflags>-static-libstdc++
formiaczek
la source