Étrange erreur de liaison: DSO manquant de la ligne de commande

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, il semble 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

Peut vous donner des conseils ou des pointeurs?

149
demandé sur Adam 2013-11-11 12:33:39

10 réponses

Vous devriez mentionner la bibliothèque sur la ligne de commande après les fichiers objet en cours de compilation:

 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 a. Vous devez donc spécifier les modules qui utilisent d'abord les bibliothèques, et les bibliothèques après eux. Comme ceci:

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

De plus, en cas de dépendance circulaire, vous devez spécifier la même bibliothèque sur la ligne de commande plusieurs temps. Ainsi dans le cas libb besoins symbole de libc et libc besoins symbole de libb, la ligne de commande doit être:

gcc x.o y.o z.o -la -lb -lc -lb
115
répondu Michael Pankov 2015-12-21 15:04:04

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

Ubuntu Coquine:

/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 vous manque peut - être une bibliothèque dans vos étapes de compilation, pendant la phase de liaison. Dans mon cas, j'ai ajouté '-lz' aux Drapeaux makefile / GCC.

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

37
répondu kevinf 2018-05-16 05:46:37

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

C'est 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 contient pas -lX11 - bien que le libX11.so devrait ê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 aurait pu ê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é à la ligne de commande.

Veuillez noter trois règles importantes concernant le lien 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 n'ont que des symboles indéfinis - c'est à vous de connaître leurs dépendances et de les fournir toutes dans la ligne de commande
  • l'ordre dans les bibliothèques statiques c'est toujours: demandeur première, fournisseur suit. Sinon, vous obtiendrez un message de symbole indé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 il faudra lib<name>.so ou lib<name>.a. La Bibliothèque dynamique est préférée, si elle est trouvée, et les bibliothèques statiques ne peuvent être appliquées que par l'option du compilateur-c'est tout. Et si vous avez des problèmes comme ci-dessus, cela dépend si vous aviez statique ou dynamique bibliothèques
  • Eh bien, parfois les dépendances peuvent manquer dans les bibliothèques dynamiques: D
12
répondu Ethouris 2016-07-14 13:34:08

J'ai trouvé que j'avais la même erreur. Je compilais un code avec lapack et blas. Quand j'ai changé l'ordre que les deux bibliothèques ont été appelées l'erreur est partie.

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

5
répondu user3112632 2013-12-17 19:30:29

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

Ancien:

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

A obtenu l'erreur suivante. Si j'ajoute l'option -lpthread à 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
4
répondu osexp2003 2016-08-29 16:43:32

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

  • Commentez toutes les bibliothèques liées dans la commande link.
  • nettoie tout .o,. so etc (généralement faire propre est suffisant, mais vous pouvez lancer une recherche récursive + rm , ou quelque chose de similaire).
  • décommentez les bibliothèques dans la commande link 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 "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 réfléchissez, cmake ne peut pas savoir quel est l'ordre correct jusqu'à ce que la liaison soit terminée avec succès.

2
répondu AhrB 2015-02-05 09:31:04

S'il vous Plaît ajouter: CFLAGS="-lrt" et LDFLAGS="-lrt"

2
répondu 劉大為 2017-04-13 08:26:45

La même chose m'est arrivée alors que j'installais le benchmark HPCC (inclut HPL et quelques autres benchmarks). J'ai ajouté -lm aux drapeaux du compilateur dans mon script de construction, puis il a été compilé avec succès.

0
répondu Jon Doh 2016-12-04 18:41:04

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

0
répondu Kenny J 2018-02-09 04:24:54

Si vous utilisez g++, assurez-vous que vous n'exécutez pas gcc plutôt que

0
répondu Martin R. 2018-06-21 22:46:04