niezdefiniowane odniesienie do boost :: system :: system_category () podczas kompilacji

105

Próbuję skompilować program na Ubuntu 11.10, który używa bibliotek Boost. Mam zainstalowane biblioteki 1.46-dev Boost z repozytorium Ubuntu, ale podczas kompilacji programu pojawia się błąd.

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

Co takiego robię źle?

user1049697
źródło
6
To nie jest błąd kompilatora, to błąd konsolidatora . Musisz połączyć się z biblioteką Boost.System.
ildjarn

Odpowiedzi:

160

Biblioteka boost, której używasz, zależy od biblioteki boost_system. (Nie wszyscy to robią.)

Zakładając, że używasz gcc, spróbuj dodać -lboost_systemdo wiersza poleceń kompilatora, aby połączyć się z tą biblioteką.

hc_
źródło
3
Do kompilacji używam pliku Makefile g ++. Gdzie zwykle umieszcza się takie flagi?
user1049697
2
Sposób montowania wiersza poleceń kompilatora / konsolidatora różni się znacznie w zależności od przypadku. Dlaczego nie wkleisz swojego Makefile (lub odpowiednich jego części) do pytania? W ten sposób możesz uzyskać odpowiedź, która działa w Twoim konkretnym przypadku.
hc_
7
Ok, ja edytowany Makefile.am i dodał -lboost_system, więc wyglądało to tak: sslsniff_LDFLAGS = -lssl -lboost_filesystem -lpthread -lboost_thread -llog4cpp -lboost_system. To jednak nie pomogło ...
user1049697
1
Wciąż ten sam błąd? Biegałeś autoreconfpóźniej? Również ten post i ten mogą pomóc w konfiguracji narzędzi automatycznych.
hc_
2
Wymieniłem sslsniff_LDFLAGSz sslsniff_LDADDw Makefile.am i to nie pomogło. Potem zachowałem oba sslsniff_LDFLAGSi dodałem sslsniff_LDADD = -lboost_system -lssl -lboost_filesystem -lpthread -lboost_thread -llog4cpp. Wtedy udało mi się skompilować. Dziękuję za pomoc!
user1049697
62

Powiązanie z biblioteką, która definiuje brakujący symbol ( -lboost_system) jest oczywistym rozwiązaniem, ale w konkretnym przypadku Boost.System, błąd w oryginalnym projekcie sprawia, że ​​jest on użyteczny boost::system::generic_category()i boost::system::system_category()niepotrzebny. Kompilowanie z flagą -DBOOST_SYSTEM_NO_DEPRECATEDwyłącza ten kod i pozwala wielu programom kompilować się bez wymagania -lboost_system(to łącze jest oczywiście nadal potrzebne, jeśli jawnie używasz niektórych funkcji biblioteki).

Począwszy od Boost 1.66 i tego zatwierdzenia , to zachowanie jest teraz domyślne, więc miejmy nadzieję, że coraz mniej użytkowników powinno potrzebować tej odpowiedzi.

Jak zauważył @AndrewMarshall, alternatywą jest zdefiniowanie, BOOST_ERROR_CODE_HEADER_ONLYktóre włącza wersję kodu zawierającą tylko nagłówki. Było to zniechęcone przez Boost, ponieważ może to zepsuć niektóre funkcje. Jednak od wersji 1.69 wydaje się, że tylko nagłówek stał się domyślny , rzekomo czyniąc to pytanie przestarzałym.

Marc Glisse
źródło
4
dzięki!!! nic nie pomogło, odkąd używam boost 1.41 (Centos SL), jedyną rzeczą, która mnie uwolniła, jest użycie -DBOOST_SYSTEM_NO_DEPRECATED
Roger Rabbit
5
Właściwie to, czego możesz chcieć, to -DBOOST_ERROR_CODE_HEADER_ONLY
Andrew Marshall
1
Co ciekawe, nowe zachowanie Boost 1.66 polegające na mniejszej liczbie odwołań do system_category () itp. Może powodować nowe problemy z łączami w przypadku problemów z ich kolejnością. Zobacz github.com/PointCloudLibrary/pcl/pull/2236 na przykład
pixelbeat
3
Jeśli używasz CMake, po prostu dodaj „add_definitions (-DBOOST_ERROR_CODE_HEADER_ONLY)”
nickolay.
1
Jedyną poprawką, która działała dla mnie z Boost 1.68, było zdefiniowanie BOOST_ERROR_CODE_HEADER_ONLY.
sakra
17

Kolejne obejście dla tych, którzy nie potrzebują całego shebangu: użyj przełącznika

-DBOOST_ERROR_CODE_HEADER_ONLY.

Jeśli używasz CMake, to jest add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY).

Vadim Berman
źródło
1
Niedawno natknąłem się na ten problem. Nic nie działa poza tym. Zastanawiam się, czy nadal nie zniechęca tego doładowanie, jak wspomniano w odpowiedzi Marca Glisse'a.
John Z. Li
1
quote "Boost.System obsługuje teraz tylko nagłówki. Biblioteka pośrednicząca jest nadal tworzona w celu zapewnienia zgodności, ale łączenie z nią nie jest już konieczne."
John Z. Li
16

Powyższy błąd to błąd konsolidatora ... konsolidator to program, który pobiera jeden lub więcej obiektów wygenerowanych przez kompilator i łączy je w jeden program wykonywalny.

Musisz dodać -lboost_systemdo siebie flagi konsolidatora, które wskazują konsolidatorowi, że musi szukać symboli takich jak boost::system::system_category()w bibliotece libboost_system.so.

Jeśli masz plik main.cpp:

g++ main.cpp -o main -lboost_system

LUB

g++ -c -o main.o main.cpp
g++ main.o -lboost_system
user1055604
źródło
5
spacja między -l a nazwą biblioteki jest niepoprawna. powinieneś użyć
-lboost_system
1
Okazało się, że centos nie przejmował się pozycją -l, ale ubuntu tak, musi być na końcu.
ask_io
7

Używając CMAKE i find_package, upewnij się, że jest to:

find_package(Boost COMPONENTS system ...)

i nie

find_package(boost COMPONENTS system ...)

Niektórzy mogli stracić na to godziny ...

Kriegalex
źródło
6

Mam ten sam problem:

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): niezdefiniowane odniesienie do `boost :: system :: generic_category ()

Rozwiązaniem było użycie wersji debugowania biblioteki systemowej:

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

Ale dlaczego?

volker
źródło
1
Czy to możliwe, że gdzieś została zdefiniowana jakaś flaga debugowania, więc masz inne biblioteki wbudowane w debug lub g ++ produkuje debug obj?
noonex
4

Kiedy miałem ten problem, przyczyną było uporządkowanie bibliotek. Aby to naprawić, wstawiłem libboost_systemostatnią:

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

Było to na mingw z gcc 5.3 i boost 1.61.0 z prostym przykładem timera.

Min Zhang
źródło
1
To też był mój problem. Umieściłem go za pomocą CMake i, z jakiegokolwiek powodu, założone zależności i kolejność zostały opracowane w skrypcie FindBoost. Naprawdę jednak mój problem polegał na tym, że zawsze korzystałem z bibliotek współdzielonych i nigdy nie zwracałem uwagi, a następnie przechodziłem do bibliotek statycznych i otrzymywałem błędy kompilacji. Ups.
Anthony
Naprawiło to również dla mnie ... przed tym rozwiązaniem jedyną rzeczą, która działała, było zdefiniowanie BOOST_ERROR_CODE_HEADER_ONLY. W Ubuntu 18.04 zwiększ 1,68 za pomocą cmake. Moja poprawka: target_link_libraries (plik wykonywalny pthread ssl crypto boost_system)
Luis
2

w moim przypadku dodanie -lboost_systemnie wystarczyło, nadal nie mógł go znaleźć w moim niestandardowym środowisku kompilacji. Musiałem skorzystać z porady w Pozbądź się "gcc - / usr / bin / ld: warning lib not found" i zmień moje ./configurepolecenie na:

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

Aby uzyskać więcej informacji, zobacz Boost 1.51: "błąd: nie można połączyć z boost_thread!"

jcomeau_ictx
źródło
1

... a na wypadek, gdybyś chciał statycznie połączyć swój główny plik, w swoim Jamfile dodaj następujące wymagania do wymagań:

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

a może także:

<linkflags>-static-libgcc
<linkflags>-static-libstdc++
formiaczek
źródło