libpthread.so.0: Fehler beim Hinzufügen von Symbolen: DSO fehlt in der Befehlszeile


205

Beim Kompilieren von openvswitch-1.5.0 ist der folgende Kompilierungsfehler aufgetreten:

 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

Wenn ich versuche, die Symbole von zu sehen libpthread, sieht es gut aus.

$ 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

Könnten Sie irgendwelche Hinweise oder Hinweise geben?



link_libraries (pthread)
Alex Punnen

# readelf -s /lib/x86_64-linux-gnu/libncurses.so readelf: Fehler: '/lib/x86_64-linux-gnu/libncurses.so' konnte nicht gefunden werden. Systemfehlermeldung: Zu viele Ebenen symbolischer Links
Ashish Karpe

Mögliches Duplikat von DSO fehlt in der Kommandozeile
luator

4
Verdammt, ich habe gccnichtg++
Post Self

Antworten:


162

Sie sollten die Bibliothek in der Befehlszeile nach dem Kompilieren der Objektdateien erwähnen :

 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 -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 -lpthread 

Erläuterung: Die Verknüpfung hängt von der Reihenfolge der Module ab. Symbole werden zuerst angefordert und dann aus einer Bibliothek mit ihnen verknüpft. Sie müssen also Module angeben, die zuerst Bibliotheken und danach Bibliotheken verwenden. So was:

gcc x.o y.o z.o -la -lb -lc

Darüber hinaus sollten Sie bei einer zirkulären Abhängigkeit dieselbe Bibliothek mehrmals in der Befehlszeile angeben. Für den Fall, dass ein libbSymbol von libcund ein libcSymbol von benötigt wird libb, sollte die Befehlszeile wie folgt lauten:

gcc x.o y.o z.o -la -lb -lc -lb

23
Ich denke, Sie können -Wl,--start-group -la -lb- -lc -Wl,--end-groupfür zirkuläre Abhängigkeiten tun .
Z Boson

2
Beachten Sie, dass dies auch für Quelldateien gilt - sie sollten vor Bibliotheken aufgelistet werden. Sie können sich vorstellen, dass die resultierenden Objektdateien den Platz der Quelldateien in der Befehlszeile einnehmen, und dieselbe Reihenfolge wie oben anwenden.
Jspencer

Wo sollte man -lpthread hinzufügen, wenn man make zum Erstellen der Anwendung verwendet?
Codezombie

50

Die Fehlermeldung hängt von der Distribution / Compiler-Version ab:

Ubuntu Saucy:

/usr/bin/ld: /mnt/root/ffmpeg-2.1.1//libavformat/libavformat.a(http.o): undefined reference to symbol 'inflateInit2_'
/lib/x86_64-linux-gnu/libz.so.1: error adding symbols: DSO missing from command line

Ubuntu Raring: (informativer)

/usr/bin/ld: note: 'uncompress' is defined in DSO /lib/x86_64-linux-gnu/libz.so.1 so try adding it to the linker command line

Lösung: Während der Verknüpfungsphase fehlt möglicherweise eine Bibliothek in Ihren Kompilierungsschritten. In meinem Fall habe ich '-lz' zu Makefile / GCC-Flags hinzugefügt.

Hintergrund: DSO ist ein dynamisches freigegebenes Objekt oder eine gemeinsam genutzte Bibliothek.


1
Ich habe diese Lösung verwendet, um ein anderes Projekt zu erstellen, das den gleichen Fehler durch Hinzufügen von -lz zu LDFLAGS verursachte, und es hat perfekt funktioniert. Vielen Dank!
Mark Ellul

Der Fehler bleibt für mich weiterhin bestehen: / usr / bin / ld: gaSim.o: undefinierter Verweis auf das Symbol 'pthread_create @@ GLIBC_2.1' /lib/i386-linux-gnu/libpthread.so.0: Fehler beim Hinzufügen von Symbolen: DSO fehlt in der Kommandozeile
Aerox

Teilweise gelöst durch Hinzufügen von '-lpthread', aber jetzt zeigt es mir: gaSim.c :(. Text + 0x11d6): undefinierter Verweis auf `glewInit '
Aerox

@ Aerox: für glewInit, Sie brauchen-lGLEW
mchiasson

19

Hintergrund

Die DSO missing from command lineMeldung wird angezeigt, wenn der Linker das erforderliche Symbol bei seiner normalen Suche nicht findet, das Symbol jedoch in einer der Abhängigkeiten einer direkt angegebenen dynamischen Bibliothek verfügbar ist.

In der Vergangenheit betrachtete der Linker Symbole in Abhängigkeiten bestimmter Sprachen als verfügbar. Dies hat sich jedoch in einer späteren Version geändert, und jetzt erzwingt der Linker eine strengere Sicht auf das, was verfügbar ist. Die Nachricht soll somit bei diesem Übergang helfen.

Was ist zu tun?

Wenn Sie der Betreuer der Software sind

Sie sollten dieses Problem lösen, indem Sie sicherstellen, dass alle Bibliotheken, die zur Erfüllung der erforderlichen Symbole benötigt werden, direkt in der Linker-Befehlszeile angegeben sind. Denken Sie auch daran, dass die Reihenfolge oft wichtig ist.

Wenn Sie nur versuchen, die Software zu kompilieren

Um dieses Problem zu umgehen, können Sie mithilfe der Option wieder in die freizügigere Ansicht der verfügbaren Symbole wechseln -Wl,--copy-dt-needed-entries.

Übliche Methoden, um dies in einen Build einzufügen, sind das Exportieren von LDFLAGS vor dem Ausführen configureoder ähnliches:

export LDFLAGS="-Wl,--copy-dt-needed-entries"

Manchmal funktioniert es auch, LDFLAGS="-Wl,--copy-dt-needed-entries"direkt an zu gehen make.


gcc Version 7.4.0 (Ubuntu 7.4.0-1ubuntu1 ~ 18.04.1) hat dieses Flag nicht erkannt.
UserX

1
Es ist keine gcc-Option. Entweder fehlt Ihnen das -Wl,Bit, oder Sie haben einen Linker, der diese Optionen nicht unterstützt. Welchen Linker verwendest du? Diese Antwort setzt den klassischen binutils-Linker (ld.bfd) voraus. Der binutils gold linker (ld.gold) dokumentiert --copy-dt-needed-entriesals "Nicht unterstützt". Wenn Sie diesen (oder einen anderen Linker, der diese Option nicht unterstützt) als Standard haben, müssen Sie möglicherweise dem Abschnitt für Betreuer folgen oder zum Verknüpfen zum klassischen ld wechseln. Ich denke, Sie können dafür verwenden -fuse-ld=ld.bfd.
Textshell

14

Ich habe einen anderen Fall gefunden und deshalb bin ich der Meinung, dass Sie alle falsch liegen.

Das hatte ich:

/usr/lib64/gcc/x86_64-suse-linux/4.8/../../../../x86_64-suse-linux/bin/ld: eggtrayicon.o: undefined reference to symbol 'XFlush'
/usr/lib64/libX11.so.6: error adding symbols: DSO missing from command line

Das Problem ist, dass die Befehlszeile NICHT enthielt -lX11- obwohl libX11.so als Abhängigkeit hinzugefügt werden sollte, da die Argumente auch GTK- und GNOME-Bibliotheken enthielten .

Die einzige Erklärung für mich ist, dass diese Nachricht möglicherweise dazu gedacht war, Ihnen zu helfen , aber sie hat es nicht richtig gemacht. Dies war wahrscheinlich einfach: Die Bibliothek, die das Symbol bereitstellt, wurde nicht zur Befehlszeile hinzugefügt.

Bitte beachten Sie drei wichtige Regeln bezüglich der Verknüpfung in POSIX:

  • Dynamische Bibliotheken haben Abhängigkeiten definiert, daher sollten nur Bibliotheken aus der obersten Abhängigkeit in beliebiger Reihenfolge bereitgestellt werden (obwohl nach den statischen Bibliotheken).
  • Statische Bibliotheken haben nur undefinierte Symbole - es liegt an Ihnen, ihre Abhängigkeiten zu kennen und alle in der Befehlszeile anzugeben
  • Die Reihenfolge in statischen Bibliotheken lautet immer: Anforderer zuerst , Anbieter folgt . Andernfalls erhalten Sie eine undefinierte Symbolmeldung, genau wie wenn Sie vergessen haben, die Bibliothek zur Befehlszeile hinzuzufügen
  • Wenn Sie die Bibliothek mit angeben -l<name>, wissen Sie nie, ob lib<name>.sooder lib<name>.a. Die dynamische Bibliothek wird bevorzugt, wenn sie gefunden wird, und statische Bibliotheken können nur durch die Compileroption erzwungen werden - das ist alles. Und ob Sie wie oben beschrieben Probleme haben, hängt davon ab, ob Sie statische oder dynamische Bibliotheken hatten
  • Nun, manchmal fehlen die Abhängigkeiten in dynamischen Bibliotheken: D.

Es soll Ihnen nicht nur helfen, es wird vom Linker benötigt, um die fraglichen Namen aufzulösen. Der Fehler ist vollständig gültig. Wenn der Compiler dies zulassen würde, würden Sie nur einen Segfault für den Zugriff auf etwas erhalten, das in der binären Laufzeit nicht vorhanden ist.
Kevr

1
Außerdem ist es möglich, dass auf verschiedenen Plattformen die Quelle unterschiedlich kompiliert wird. Was auf einem System verknüpft ist, ist möglicherweise nicht auf einem anderen System verknüpft. Dies ist normalerweise nicht der Fall, aber zu 100% plausibel.
Kevr

Das Problem ist nicht, dass es nicht gültig ist, aber dass es nicht gerade hilfreich ist, die Ursache des Problems zu finden.
Ethouris

7

Ich stellte fest, dass ich den gleichen Fehler hatte. Ich habe einen Code mit Lapack und Blas kompiliert. Als ich die Reihenfolge wechselte, in der die beiden Bibliotheken aufgerufen wurden, verschwand der Fehler.

"LAPACK_LIB = -llapack -lblas" funktionierte, wobei "LAPACK_LIB = -lblas -llapack" den oben beschriebenen Fehler ergab.


9
Ich erhalte diesen Fehler in einem von cmake definierten Projekt. Gibt es also einen Fehler in Cmake, der die Linkerreihenfolge falsch macht?
Peter Karasev

Antwort auf @peterkarasev: versuchen Sie es mit find_package(Threads)undtarget_link_libraries( ... ${CMAKE_THREAD_LIBS_INIT})
activedecay

7

Ich bin auch auf das gleiche Problem gestoßen. Ich weiß nicht warum, ich füge nur eine -lpthreadOption zum Compiler hinzu und alles in Ordnung.

Alt:

$ g++ -rdynamic -m64 -fPIE -pie  -o /tmp/node/out/Release/mksnapshot ...*.o *.a -ldl -lrt

habe folgenden Fehler bekommen. Wenn ich die -lpthreadOption an den obigen Befehl anhänge , dann OK.

/usr/bin/ld: /tmp/node/out/Release/obj.host/v8_libbase/deps/v8/src/base/platform/condition-variable.o: undefined reference to symbol 'pthread_condattr_setclock@@GLIBC_2.3.3'
//lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status

Das hat bei mir funktioniert; Ich musste dem Befehl g ++ im Makefile, das die Verknüpfung herstellt, einen zweiten "redundanten" -Lpthread hinzufügen. (Es wurde bereits einmal in der LIBS-Liste im Makefile angezeigt.) Außerdem habe ich der LDFLAGS-Definition im Makefile "-L / lib / x86_64-linux-gnu" hinzugefügt.
UserX

2

Was ich gefunden habe ist, dass manchmal die Bibliothek, über die sich der Linker beschwert, nicht diejenige ist, die das Problem verursacht. Möglicherweise gibt es eine clevere Möglichkeit, herauszufinden, wo das Problem liegt, aber das mache ich:

  • Kommentieren Sie alle verknüpften Bibliotheken im Befehl link aus.
  • Bereinigen Sie alle .o's, .so's usw. (Normalerweise reicht es aus, sauber zu machen, aber Sie möchten möglicherweise einen rekursiven Find + rm oder ähnliches ausführen).
  • Kommentieren Sie die Bibliotheken im Link-Befehl einzeln aus und ordnen Sie die Reihenfolge nach Bedarf neu.

@ Peter Karasev: Ich bin auf dasselbe Problem mit einem gcc 4.8.2 cmake-Projekt unter CentOS7 gestoßen. Die Reihenfolge der Bibliotheken im Abschnitt "target_link_libraries" ist wichtig. Ich denke, cmake gibt die Liste einfach so wie sie ist an den Linker weiter, dh es wird nicht versucht, die richtige Reihenfolge zu ermitteln. Dies ist vernünftig - wenn Sie darüber nachdenken, kann cmake nicht wissen, wie die richtige Reihenfolge ist, bis die Verknüpfung erfolgreich abgeschlossen wurde.



1

Das gleiche Problem ist mir passiert, als ich distccmein C ++ - Projekt erstellt habe. Endlich habe ich es mit gelöst export CXX="distcc g++".


1

Wenn Sie cmake und pthreads verwenden, fügen Sie die folgenden Zeilen hinzu

find_package(Threads)
target_link_libraries(${CMAKE_THREAD_LIBS_INIT})

0

Das gleiche passierte mir bei der Installation des HPCC-Benchmarks (einschließlich HPL und einiger anderer Benchmarks). Ich -lmhabe die Compiler-Flags in meinem Build-Skript hinzugefügt und dann erfolgreich kompiliert.


3
Dies beantwortet weder diese spezifische Frage noch gibt es eine allgemeine Antwort für eine Familie ähnlicher Probleme. Dies ist eine stark lokalisierte Antwort auf eine andere Frage .
Hermann Döppes

0

Stellen Sie bei Verwendung g++sicher, dass Sie nicht gccstattdessen ausgeführt werden


3
Warum? Könnten Sie etwas näher darauf eingehen?
Ivan Ivković

0

Versuchen Sie, -pthreadam Ende der Bibliotheksliste im Makefile hinzuzufügen .

Es hat bei mir funktioniert.


0

Wenn Sie CMake verwenden, gibt es einige Möglichkeiten, wie Sie es lösen können:

Lösung 1: Die eleganteste

add_executable(...)
target_include_directories(...)
target_link_libraries(target_name pthread)

Lösung 2: Verwenden von CMakefind_package

find_package(Threads REQUIRED) # this will generate the flag for CMAKE_THREAD_LIBS_INIT

add_executable(...)
target_include_directories(...)
target_link_libraries(target_name ${CMAKE_THREAD_LIBS_INIT})

Lösung 3: Ändern Sie die CMake-Flags

# e.g. with C++ 17, change to other version if you need
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -pthread")
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.