Podczas kompilowania openvswitch-1.5.0 napotkałem następujący błąd kompilacji:
gcc -Wstrict-prototypes -Wall -Wno-sign-compare -Wpointer-arith
-Wdeclaration-after-statement -Wformat-security -Wswitch-enum -Wunused-parameter -Wstrict-aliasing -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -Wno-override-init -g -O2 -export-dynamic ***-lpthread*** -o utilities/ovs-dpctl utilities/ovs-dpctl.o lib/libopenvswitch.a
/home/jyyoo/src/dpdk/build/lib/librte_eal.a
/home/jyyoo/src/dpdk/build/lib/libethdev.a
/home/jyyoo/src/dpdk/build/lib/librte_cmdline.a
/home/jyyoo/src/dpdk/build/lib/librte_hash.a
/home/jyyoo/src/dpdk/build/lib/librte_lpm.a
/home/jyyoo/src/dpdk/build/lib/librte_mbuf.a
/home/jyyoo/src/dpdk/build/lib/librte_ring.a
/home/jyyoo/src/dpdk/build/lib/librte_mempool.a
/home/jyyoo/src/dpdk/build/lib/librte_malloc.a -lrt -lm
/usr/bin/ld: /home/jyyoo/src/dpdk/build/lib/librte_eal.a(eal.o): undefined reference
to symbol 'pthread_create@@GLIBC_2.2.5'
/lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from
command line
Jeśli spróbuję zobaczyć symbole libpthread
, wygląda dobrze.
$ readelf -s /lib/x86_64-linux-gnu/libpthread.so.0 | grep pthread_create
199: 0000000000008220 2814 FUNC GLOBAL DEFAULT 13 pthread_create@@GLIBC_2.2.5
173: 0000000000008220 2814 FUNC LOCAL DEFAULT 13 __pthread_create_2_1
462: 0000000000008220 2814 FUNC GLOBAL DEFAULT 13 pthread_create@@GLIBC_2.2
Czy możesz podać jakieś wskazówki lub wskazówki?
gcc
nieg++
Odpowiedzi:
Należy wspomnieć biblioteki w wierszu poleceń po pliki wynikowe są kompilowane:
Objaśnienie: łączenie zależy od kolejności modułów. Symbole są najpierw wymagane, a następnie łączone z biblioteki, która je ma. Musisz więc określić moduły, które najpierw używają bibliotek, a biblioteki po nich. Lubię to:
Ponadto w przypadku zależności cyklicznej należy kilkakrotnie podać tę samą bibliotekę w wierszu poleceń. Dlatego w przypadku, gdy
libb
potrzebny jest symbol zlibc
ilibc
potrzebny jest symbol zlibb
, wierszem poleceń powinno być:źródło
-Wl,--start-group -la -lb- -lc -Wl,--end-group
dla zależności cyklicznych.Komunikat o błędzie zależy od wersji dystrybucji / kompilatora:
Ubuntu Saucy:
Ubuntu Raring: (więcej informacji)
Rozwiązanie: Być może brakuje biblioteki na etapach kompilacji podczas etapu łączenia. W moim przypadku dodałem „-lz” do flag makefile / GCC.
Tło: DSO to dynamiczny obiekt współdzielony lub biblioteka współdzielona.
źródło
glewInit
potrzebujesz-lGLEW
tło
The
DSO missing from command line
Wiadomość zostanie wyświetlona, gdy łącznik nie znajdzie wymaganej symbol ze to normalne, ale symbol wyszukiwania jest dostępny w jednym z zależnościami o bezpośrednio określonej biblioteki dynamicznej.W przeszłości linker uważał za dostępne symbole w zależnościach określonych języków. Ale to zmieniło się w niektórych późniejszych wersjach, a teraz linker wymusza ściślejsze spojrzenie na to, co jest dostępne. Wiadomość ma zatem pomóc w tym przejściu.
Co robić?
Jeśli jesteś opiekunem oprogramowania
Powinieneś rozwiązać ten problem, upewniając się, że wszystkie biblioteki potrzebne do spełnienia potrzebnych symboli są określone bezpośrednio w wierszu poleceń konsolidatora. Pamiętaj też, że kolejność ma często znaczenie.
Jeśli tylko próbujesz skompilować oprogramowanie
Aby obejść ten problem, można powrócić do bardziej liberalnego widoku dostępnych symboli za pomocą opcji
-Wl,--copy-dt-needed-entries
.Typowe sposoby wprowadzania tego do kompilacji to eksportowanie LDFLAGS przed uruchomieniem
configure
lub podobnym:Czasami przejście
LDFLAGS="-Wl,--copy-dt-needed-entries"
bezpośrednio domake
może również działać.źródło
-Wl,
bitu, albo masz linker, który nie obsługuje tych opcji. Jakiego linkera używasz? Ta odpowiedź zakłada klasyczny linker binutils (ld.bfd). Binutils gold linker (ld.gold) dokumentuje--copy-dt-needed-entries
jako „Nieobsługiwany”. Więc jeśli masz ten (lub inny linker, który nie obsługuje tej opcji) jako domyślny, być może będziesz musiał postępować zgodnie z sekcją dla opiekunów lub przejść do klasycznego ld do łączenia. Myślę, że możesz-fuse-ld=ld.bfd
do tego użyć .Znalazłem inny przypadek i dlatego myślę, że wszyscy się mylicie.
Oto co miałem:
Problem polega na tym, że wiersz poleceń NIE zawierał
-lX11
- chociaż libX11.so należy dodać jako zależność, ponieważ w argumentach były również biblioteki GTK i GNOME.Tak więc jedynym wyjaśnieniem dla mnie jest to, że ta wiadomość mogła mieć na celu pomóc , ale nie zrobiła tego poprawnie. Prawdopodobnie było to proste: biblioteka, która zawiera ten symbol, nie została dodana do wiersza poleceń.
Zwróć uwagę na trzy ważne zasady dotyczące łączenia w POSIX:
-l<name>
, nigdy nie wiesz, czy zajmielib<name>.so
lublib<name>.a
. Biblioteka dynamiczna jest preferowana, jeśli zostanie znaleziona, a biblioteki statyczne można wymusić tylko za pomocą opcji kompilatora - to wszystko. I czy masz jakieś problemy jak wyżej, zależy to od tego, czy posiadałeś biblioteki statyczne czy dynamiczneźródło
Odkryłem, że mam ten sam błąd. Kompilowałem kod zarówno z lapack, jak i blas. Gdy zmieniłem kolejność wywoływania dwóch bibliotek, błąd zniknął.
„LAPACK_LIB = -llapack -lblas” zadziałało, gdy „LAPACK_LIB = -lblas -llapack” dał błąd opisany powyżej.
źródło
find_package(Threads)
itarget_link_libraries( ... ${CMAKE_THREAD_LIBS_INIT})
Zetknąłem się również z tym samym problemem. Nie wiem dlaczego, po prostu dodałem
-lpthread
opcję do kompilatora i wszystko w porządku.Stary:
dostałem następujący błąd. Jeśli dołączę
-lpthread
opcję do powyższego polecenia, to OK.źródło
Odkryłem, że czasami biblioteka, na którą narzeka linker, nie jest przyczyną problemu. Być może istnieje sprytny sposób, aby dowiedzieć się, gdzie jest problem, ale to właśnie robię:
@peter karasev: Natknąłem się na ten sam problem z projektem cmake gcc 4.8.2 na CentOS7. Ważna jest kolejność bibliotek w sekcji „target_link_libraries”. Wydaje mi się, że cmake po prostu przekazuje listę linkerowi w niezmienionej postaci, tzn. Nie próbuje ustalić prawidłowej kolejności. Jest to uzasadnione - jeśli pomyślisz o tym, cmake nie może wiedzieć, jaka jest poprawna kolejność, dopóki połączenie nie zostanie pomyślnie zakończone.
źródło
Dodaj:
CFLAGS="-lrt"
iLDFLAGS="-lrt"
źródło
Ten sam problem przydarzył mi się, gdy wykonałem
distcc
projekt w C ++; W końcu to rozwiązałemexport CXX="distcc g++"
.źródło
jeśli używasz cmake i używanych pthreads, spróbuj dodać następujące linie
źródło
To samo przydarzyło mi się, gdy instalowałem test porównawczy HPCC (obejmuje HPL i kilka innych testów porównawczych). Dodałem
-lm
do flag kompilatora w skrypcie kompilacji, a następnie pomyślnie skompilowałem.źródło
Jeśli używasz
g++
, upewnij się, żegcc
zamiast tego nie działaszźródło
Spróbuj dodać
-pthread
na końcu listy bibliotek w Makefile .To zadziałało dla mnie.
źródło
Jeśli używasz CMake, istnieje kilka sposobów na jego rozwiązanie:
Rozwiązanie 1: Najbardziej elegancki
Rozwiązanie 2: Korzystanie z CMake
find_package
Rozwiązanie 3: Zmień flagi CMake
źródło