libpthread.so.0: errore durante l'aggiunta dei simboli: DSO mancante dalla riga di comando


205

Durante la compilazione di openvswitch-1.5.0, ho riscontrato il seguente errore di compilazione:

 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

Se provo a vedere i simboli di libpthread, sembra a posto.

$ 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

Potresti dare qualche suggerimento o suggerimento?



link_libraries (pthread)
Alex Punnen,

# readelf -s /lib/x86_64-linux-gnu/libncurses.so readelf: Errore: Impossibile trovare '/lib/x86_64-linux-gnu/libncurses.so'. Messaggio di errore di sistema: troppi livelli di collegamenti simbolici
Ashish Karpe,

Possibile duplicato di DSO mancante dalla riga di comando
luator

4
Dannazione, ho fatto gccnong++
Messaggio Auto

Risposte:


164

Dovresti menzionare la libreria sulla riga di comando dopo che i file oggetto sono stati compilati:

 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 

Spiegazione: il collegamento dipende dall'ordine dei moduli. I simboli vengono prima richiesti e quindi collegati da una libreria che li ha. Quindi devi specificare i moduli che utilizzano prima le librerie e le librerie dopo di esse. Come questo:

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

Inoltre, in caso di dipendenza circolare, è necessario specificare più volte la stessa libreria sulla riga di comando. Quindi, nel caso in cui abbia libbbisogno di un simbolo libce di un libcsimbolo da libb, la riga di comando dovrebbe essere:

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

24
Penso che tu possa fare -Wl,--start-group -la -lb- -lc -Wl,--end-groupper le dipendenze circolari.
Bosone Z,

2
Nota che questo vale anche per i file sorgente: dovrebbero essere elencati prima delle librerie. Puoi pensare ai file oggetto risultanti che prendono il posto dei file sorgente nella riga di comando e applicare lo stesso ordine di cui sopra.
jspencer,

Dove si dovrebbe aggiungere -lpthread quando si usa make per compilare l'applicazione?
codezombie

50

Il messaggio di errore dipende dalla versione di distribuzione / compilatore:

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: (più informativo)

/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

Soluzione: è possibile che manchi una libreria nelle fasi della compilazione, durante la fase di collegamento. Nel mio caso, ho aggiunto '-lz' ai flag makefile / GCC.

Sfondo: DSO è un oggetto condiviso dinamico o una libreria condivisa.


1
Ho usato questa soluzione costruendo un altro progetto che stava dando lo stesso errore aggiungendo -lz a LDFLAGS e ha funzionato perfettamente. Grazie!
Mark Ellul,

L'errore rimane ancora per me: / usr / bin / ld: gaSim.o: riferimento indefinito al simbolo 'pthread_create @@ GLIBC_2.1' /lib/i386-linux-gnu/libpthread.so.0: errore nell'aggiunta di simboli: DSO mancante dalla riga di comando
Aerox il

In parte risolto aggiungendo '-lpthread', ma ora mi mostra: gaSim.c :(. Testo + 0x11d6): riferimento indefinito a `glewInit '
Aerox,

@Aerox: per glewInit, è necessario-lGLEW
mchiasson il

19

sfondo

Il DSO missing from command linemessaggio verrà visualizzato quando il linker non trova il simbolo richiesto con la sua ricerca normale ma il simbolo è disponibile in una delle dipendenze di una libreria dinamica specificata direttamente.

In passato il linker considerava disponibili i simboli nelle dipendenze delle lingue specificate. Ma ciò è cambiato in alcune versioni successive e ora il linker applica una visione più rigorosa di ciò che è disponibile. Il messaggio quindi ha lo scopo di aiutare con quella transizione.

Cosa fare?

Se sei il manutentore del software

Dovresti risolvere questo problema assicurandoti che tutte le librerie necessarie per soddisfare i simboli necessari siano specificate direttamente sulla riga di comando del linker. Inoltre, tieni presente che l'ordine è spesso importante.

Se stai solo cercando di compilare il software

Come soluzione alternativa è possibile tornare alla vista più permissiva di quali simboli sono disponibili utilizzando l'opzione -Wl,--copy-dt-needed-entries.

Modi comuni per iniettare questo in una build sono esportare LDFLAGS prima di eseguirli configureo simili in questo modo:

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

A volte il passaggio LDFLAGS="-Wl,--copy-dt-needed-entries"diretto a makepotrebbe anche funzionare.


gcc versione 7.4.0 (Ubuntu 7.4.0-1ubuntu1 ~ 18.04.1) non ha riconosciuto questo flag.
UtenteX

1
Non è un'opzione gcc, quindi o ti manca il -Wl,bit o hai un linker che non supporta queste opzioni. Quale linker stai usando? Questa risposta presuppone il classico linker binutils (ld.bfd). Il binutils gold linker (ld.gold) documenta --copy-dt-needed-entriescome "Non supportato". Quindi se hai quel (o qualsiasi altro linker che non supporta questa opzione) come impostazione predefinita potresti dover seguire la sezione per i manutentori o passare al classico ld per il collegamento. Penso che tu possa usare -fuse-ld=ld.bfdper quello.
texthell

14

Ho trovato un altro caso e quindi penso che tu abbia torto.

Questo è quello che ho avuto:

/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

Il problema è che la riga di comando DID NON contiene -lX11- sebbene libX11.so debba essere aggiunto come dipendenza perché negli argomenti c'erano anche librerie GTK e GNOME.

Quindi, l'unica spiegazione per me è che questo messaggio potrebbe essere stato pensato per aiutarti , ma non lo ha fatto correttamente. Probabilmente era semplice: la libreria che fornisce il simbolo non è stata aggiunta alla riga di comando.

Si prega di notare tre importanti regole relative al collegamento in POSIX:

  • Le librerie dinamiche hanno dipendenze definite, quindi solo le librerie dalla dipendenza superiore dovrebbero essere fornite in qualunque ordine (anche se dopo le librerie statiche)
  • Le librerie statiche hanno simboli non definiti: spetta a te conoscere le loro dipendenze e fornirle tutte nella riga di comando
  • L'ordine nelle librerie statiche è sempre: richiedente prima , il provider segue . Altrimenti riceverai un messaggio di simbolo indefinito, proprio come quando hai dimenticato di aggiungere la libreria alla riga di comando
  • Quando si specifica la libreria con -l<name>, non si sa mai se ci vorrà lib<name>.soo lib<name>.a. La libreria dinamica è preferita, se trovata, e solo le librerie statiche possono essere applicate dall'opzione del compilatore - tutto qui. E se hai problemi come sopra, dipende dal fatto che tu abbia librerie statiche o dinamiche
  • Bene, a volte le dipendenze possono mancare nelle librerie dinamiche: D

Non ha solo lo scopo di aiutarti, è richiesto dal linker per risolvere i nomi in questione. L'errore è completamente valido. Se il compilatore decidesse di lasciarlo passare, otterresti semplicemente un segfault per accedere a qualcosa che non è presente nel runtime binario.
Kevin

1
Per aggiungere, è possibile che su piattaforme diverse, la fonte sia compilata diversamente; ciò che è collegato a un sistema potrebbe non essere collegato a un altro. Questo di solito non è il caso, ma è plausibile al 100%.
Kevin

Il problema non è che non è valido, ma che non è esattamente utile per trovare la causa del problema.
Ethouris,

7

Ho scoperto di avere lo stesso errore. Stavo compilando un codice sia con Lapack che Blas. Quando ho cambiato l'ordine in cui le due librerie sono state chiamate, l'errore è scomparso.

"LAPACK_LIB = -llapack -lblas" ha funzionato dove "LAPACK_LIB = -lblas -llapack" ha dato l'errore sopra descritto.


9
Ottengo questo errore in un progetto definito da cmake ... quindi c'è un bug in Cmake che mette in errore l'ordine dei linker?
peter karasev,

rispondendo a @peterkarasev: prova a usare find_package(Threads)etarget_link_libraries( ... ${CMAKE_THREAD_LIBS_INIT})
activedecay il

7

Ho riscontrato anche lo stesso problema. Non so perché, aggiungo solo l' -lpthreadopzione al compilatore e tutto ok.

Vecchio:

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

ottenuto il seguente errore. Se aggiungo l' -lpthreadopzione al comando sopra, allora 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

Questo ha funzionato per me; Ho dovuto aggiungere un secondo "ridondante" -lpthread al comando g ++ nel makefile che fa il collegamento. (È già apparso una volta nell'elenco LIBS nel makefile.) Ho anche aggiunto "-L / lib / x86_64-linux-gnu" alla definizione LDFLAGS nel makefile.
UtenteX

2

Quello che ho scoperto è che a volte la libreria di cui si lamenta il linker non è quella che causa il problema. Forse c'è un modo intelligente per capire dove si trova il problema, ma questo è quello che faccio:

  • Commenta tutte le librerie collegate nel comando link.
  • Pulisci tutti i .o, i .so ecc. (Di solito è sufficiente ripulire, ma potresti voler eseguire una ricerca ricorsiva + rm o qualcosa di simile).
  • Scomponi le librerie nel comando di collegamento una alla volta e riorganizza l'ordine come necessario.

@peter karasev: ho riscontrato lo stesso problema con un progetto cmake gcc 4.8.2 su CentOS7. L'ordine delle librerie nella sezione "target_link_libraries" è importante. Immagino che cmake passi semplicemente la lista sul linker così com'è, cioè non cerca di elaborare l'ordine corretto. Questo è ragionevole: se ci pensi, cmake non può sapere quale sia l'ordine corretto fino a quando il collegamento non viene completato con successo.



1

Lo stesso problema si è verificato quando utilizzo il distccmio progetto c ++; Alla fine l'ho risolto con export CXX="distcc g++".


1

se stai usando cmake e hai usato pthreads, prova ad aggiungere le seguenti righe

find_package(Threads)
target_link_libraries(${CMAKE_THREAD_LIBS_INIT})

0

La stessa cosa mi è successa mentre stavo installando il benchmark HPCC (include HPL e alcuni altri benchmark). Ho aggiunto -lmai flag del compilatore nel mio script di compilazione e poi compilato correttamente.


3
Ciò non risponde a questa domanda specifica né fornisce una risposta generale per una famiglia di problemi simili. Questa è una risposta altamente localizzata per un'altra domanda del tutto .
Hermann Döppes il

0

Se si utilizza g++, assicurarsi che non si esegue gccinvece


3
Perché? Potresti elaborare un po '?
Ivan Ivković,

@ IvanIvković bene, gcc è il compilatore C, g ++ è il compilatore C ++. Mentre C ++ può compilare C, gcc non può compilare C ++.
Jean-Marc Zimmer,

0

Prova ad aggiungere -pthreadalla fine dell'elenco delle librerie nel Makefile .

Ha funzionato per me.


0

Se stai usando CMake, ci sono alcuni modi per risolverlo:

Soluzione 1: la più elegante

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

Soluzione 2: utilizzo di 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})

Soluzione 3: modificare i flag CMake

# 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")
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.