libpthread.so.0: erreur lors de l'ajout de symboles: DSO manquant dans la ligne de commande


205

Lorsque je compile openvswitch-1.5.0, j'ai rencontré l'erreur de compilation suivante:

 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

Si j'essaie de voir les symboles de libpthread, ça a l'air bien.

$ 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

Pourriez-vous donner des conseils ou des conseils?



link_libraries (pthread)
Alex Punnen

# readelf -s /lib/x86_64-linux-gnu/libncurses.so readelf: Erreur: impossible de localiser '/lib/x86_64-linux-gnu/libncurses.so'. Message d'erreur système: Trop de niveaux de liens symboliques
Ashish Karpe


4
Bon sang, je ne l'ai gccpas faitg++
Post Self

Réponses:


164

Vous devez mentionner la bibliothèque sur la ligne de commande après la compilation des fichiers objets:

 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 

Explication: la liaison dépend de l'ordre des modules. Les symboles sont d'abord demandés, puis liés à partir d'une bibliothèque qui les possède. Vous devez donc spécifier les modules qui utilisent les bibliothèques en premier, et les bibliothèques après eux. Comme ça:

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

De plus, en cas de dépendance circulaire, vous devez spécifier plusieurs fois la même bibliothèque sur la ligne de commande. Donc, dans le cas où a libbbesoin d'un symbole libcet d'un libcsymbole libb, la ligne de commande doit être:

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

24
Je pense que vous pouvez le faire -Wl,--start-group -la -lb- -lc -Wl,--end-grouppour les dépendances circulaires.
Z boson

2
Notez que cela s'applique également aux fichiers source - ils doivent être répertoriés avant les bibliothèques. Vous pouvez penser aux fichiers objets résultants à la place des fichiers source dans la ligne de commande et appliquer le même ordre que ci-dessus.
jspencer

Où faut-il ajouter -lpthread lors de l'utilisation de make pour construire l'application?
codezombie

50

Le message d'erreur dépend de la version de distribution / compilateur:

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: (plus informatif)

/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

Solution: il se peut que vous manquiez une bibliothèque dans vos étapes de compilation, pendant l'étape de liaison. Dans mon cas, j'ai ajouté «-lz» aux drapeaux makefile / GCC.

Contexte: DSO est un objet partagé dynamique ou une bibliothèque partagée.


1
J'ai utilisé cette solution pour construire un autre projet qui donnait la même erreur en ajoutant -lz au LDFLAGS et cela a parfaitement fonctionné. Merci!
Mark Ellul

L'erreur persiste pour moi: / usr / bin / ld: gaSim.o: référence non définie au symbole 'pthread_create @@ GLIBC_2.1' /lib/i386-linux-gnu/libpthread.so.0: erreur lors de l'ajout de symboles: DSO absent de la ligne de commande
Aerox

En partie résolu l'ajout de '-lpthread', mais maintenant il me montre: gaSim.c :(. Text + 0x11d6): référence non définie à `glewInit '
Aerox

@Aerox: for glewInit, you need-lGLEW
mchiasson

19

Contexte

Le DSO missing from command linemessage s'affiche lorsque l'éditeur de liens ne trouve pas le symbole requis avec sa recherche normale mais que le symbole est disponible dans l'une des dépendances d'une bibliothèque dynamique directement spécifiée.

Dans le passé, l'éditeur de liens considérait que les symboles dans les dépendances des langues spécifiées étaient disponibles. Mais cela a changé dans une version ultérieure et maintenant l'éditeur de liens impose une vue plus stricte de ce qui est disponible. Le message vise donc à faciliter cette transition.

Que faire?

Si vous êtes le responsable du logiciel

Vous devez résoudre ce problème en vous assurant que toutes les bibliothèques nécessaires pour satisfaire les symboles nécessaires sont directement spécifiées sur la ligne de commande de l'éditeur de liens. Gardez également à l'esprit que l'ordre compte souvent.

Si vous essayez simplement de compiler le logiciel

Comme solution de contournement, il est possible de revenir à la vue plus permissive des symboles disponibles en utilisant l'option -Wl,--copy-dt-needed-entries.

Les moyens courants d'injecter cela dans une build sont d'exporter LDFLAGS avant de lancer configureou similaire comme ceci:

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

Parfois, passer LDFLAGS="-Wl,--copy-dt-needed-entries"directement à makepourrait également fonctionner.


gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1 ~ 18.04.1) n'a pas reconnu cet indicateur.
UserX

1
Ce n'est pas une option gcc, donc soit vous manquez le -Wl,bit, soit vous avez un éditeur de liens qui ne prend pas en charge ces options. Quel éditeur de liens utilisez-vous? Cette réponse suppose que l'éditeur de liens binutils classique (ld.bfd). Le lieur d'or binutils (ld.gold) indique --copy-dt-needed-entriesque "Non pris en charge". Donc, si vous avez cela (ou tout autre éditeur de liens qui ne prend pas en charge cette option) par défaut, vous devrez peut-être suivre la section pour les responsables ou passer au ld classique pour la liaison. Je pense que vous pouvez l'utiliser -fuse-ld=ld.bfdpour cela.
texthell

14

J'ai trouvé un autre cas et donc je pense que vous vous trompez tous.

Voici ce que j'avais:

/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

Le problème est que la ligne de commande ne contenait PAS -lX11- bien que le libX11.so doive être ajouté en tant que dépendance car il y avait aussi des bibliothèques GTK et GNOME dans les arguments.

Donc, la seule explication pour moi est que ce message était peut-être destiné à vous aider , mais il ne l'a pas fait correctement. C'était probablement simple: la bibliothèque qui fournit le symbole n'a pas été ajoutée à la ligne de commande.

Veuillez noter trois règles importantes concernant la liaison dans POSIX:

  • Les bibliothèques dynamiques ont des dépendances définies, donc seules les bibliothèques de la dépendance supérieure doivent être fournies dans n'importe quel ordre (bien qu'après les bibliothèques statiques)
  • Les bibliothèques statiques ont juste des symboles non définis - c'est à vous de connaître leurs dépendances et de les fournir toutes en ligne de commande
  • L'ordre dans les bibliothèques statiques est toujours: le demandeur d'abord , le fournisseur suit . Sinon, vous obtiendrez un message de symbole non défini, tout comme lorsque vous avez oublié d'ajouter la bibliothèque à la ligne de commande
  • Lorsque vous spécifiez la bibliothèque avec -l<name>, vous ne savez jamais si elle prendra lib<name>.soou lib<name>.a. La bibliothèque dynamique est préférée, si elle est trouvée, et seules les bibliothèques statiques peuvent être appliquées par l'option du compilateur - c'est tout. Et si vous avez des problèmes comme ci-dessus, cela dépend si vous aviez des bibliothèques statiques ou dynamiques
  • Eh bien, parfois les dépendances peuvent faire défaut dans les bibliothèques dynamiques: D

Il n'est pas seulement destiné à vous aider, il est requis par l'éditeur de liens pour résoudre les noms en question. L'erreur est complètement valide. Si le compilateur décidait de laisser passer cela, vous obtiendriez simplement un segfault pour accéder à quelque chose qui n'est pas là dans le runtime binaire.
kevr

1
Pour ajouter, il est possible que sur différentes plateformes, la source soit compilée différemment; ce qui est lié sur un système peut ne pas l'être sur un autre. Ce n'est généralement pas le cas, mais c'est 100% plausible.
kevr

Le problème n'est pas qu'il n'est pas valide, mais qu'il n'est pas vraiment utile de trouver la cause du problème.
Ethouris

7

J'ai trouvé que j'avais la même erreur. Je compilais un code avec lapack et blas. Lorsque j'ai changé l'ordre d'appellation des deux bibliothèques, l'erreur a disparu.

"LAPACK_LIB = -llapack -lblas" a fonctionné là où "LAPACK_LIB = -lblas -llapack" a donné l'erreur décrite ci-dessus.


9
J'obtiens cette erreur dans un projet défini par cmake ... donc y a-t-il un bogue dans Cmake qui fait que l'ordre de l'éditeur de liens est faux?
peter karasev

en réponse à @peterkarasev: essayez d'utiliser find_package(Threads)ettarget_link_libraries( ... ${CMAKE_THREAD_LIBS_INIT})
activedecay

7

J'ai également rencontré le même problème. Je ne sais pas pourquoi, j'ajoute juste une -lpthreadoption au compilateur et tout va bien.

Vieux:

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

obtenu l'erreur suivante. Si j'ajoute l' -lpthreadoption à la commande ci-dessus, alors 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

Cela a fonctionné pour moi; J'ai dû ajouter un deuxième, "redondant" -lpthread à la commande g ++ dans le makefile qui fait le lien. (Il est déjà apparu une fois dans la liste LIBS dans le makefile.) J'ai également ajouté "-L / lib / x86_64-linux-gnu" à la définition LDFLAGS dans le makefile.
UserX

2

Ce que j'ai trouvé, c'est que parfois la bibliothèque dont l'éditeur de liens se plaint n'est pas celle qui cause le problème. Il existe peut-être un moyen intelligent de déterminer où se situe le problème, mais voici ce que je fais:

  • Mettez en commentaire toutes les bibliothèques liées dans la commande link.
  • Nettoyez tous les .o, .so, etc. (Habituellement, nettoyer est suffisant, mais vous pouvez exécuter une recherche récursive + rm, ou quelque chose de similaire).
  • Décommentez les bibliothèques dans la commande de liaison une à la fois et réorganisez la commande si nécessaire.

@peter karasev: J'ai rencontré le même problème avec un projet gcc 4.8.2 cmake sur CentOS7. L'ordre des bibliothèques dans la section "target_link_libraries" est important. Je suppose que cmake transmet simplement la liste à l'éditeur de liens tel quel, c'est-à-dire qu'il n'essaie pas de trouver le bon ordre. C'est raisonnable - quand vous y pensez, cmake ne peut pas savoir quel est l'ordre correct jusqu'à ce que la liaison soit terminée avec succès.



1

Le même problème m'est arrivé lorsque j'utilise distccpour créer mon projet c ++; Enfin, je l'ai résolu avec export CXX="distcc g++".


1

si vous utilisez cmake et pthreads utilisés, essayez d'ajouter les lignes suivantes

find_package(Threads)
target_link_libraries(${CMAKE_THREAD_LIBS_INIT})

0

La même chose m'est arrivée lors de l'installation du test HPCC (inclut HPL et quelques autres tests). J'ai ajouté -lmaux drapeaux du compilateur dans mon script de construction, puis il a été compilé avec succès.


3
Cela ne répond ni à cette question spécifique ni à une réponse générale pour une famille de problèmes similaires. Il s'agit d'une réponse très localisée pour une autre question entièrement .
Hermann Döppes

0

Si vous utilisez g++, assurez-vous que vous ne courez pas à la gccplace


3
Pourquoi? Pourriez-vous développer un peu?
Ivan Ivković

@ IvanIvković bien, gcc est le compilateur C, g ++ est le compilateur C ++. Alors que C ++ peut compiler C, gcc ne peut pas compiler C ++.
Jean-Marc Zimmer

0

Essayez d'ajouter -pthreadà la fin de la liste de bibliothèques dans le Makefile .

Ça a marché pour moi.


0

Si vous utilisez CMake, vous pouvez le résoudre de plusieurs manières:

Solution 1: la plus élégante

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

Solution 2: utiliser 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})

Solution 3: modifier les indicateurs 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")
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.