Erreur de liaison étrange: DSO manquant dans la ligne de commande

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

gcc -Wssortingct-prototypes -Wall -Wno-sign-compare -Wpointer-arith -Wdeclaration-after-statement -Wformat-security -Wswitch-enum -Wunused-parameter -Wssortingct-aliasing -Wbad-function-cast -Wcast-align -Wssortingct-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 indications?

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

      gcc -Wssortingct-prototypes -Wall -Wno-sign-compare -Wpointer-arith -Wdeclaration-after-statement -Wformat-security -Wswitch-enum -Wunused-parameter -Wssortingct-aliasing -Wbad-function-cast -Wcast-align -Wssortingct-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 contient. Vous devez donc spécifier les modules qui utilisent d’abord les bibliothèques et les bibliothèques après eux. Comme ça:

     gcc xo yo zo -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, si libb besoin du symbole de libc et que libc besoin du symbole de libb , la ligne de commande devrait être:

     gcc xo yo zo -la -lb -lc -lb 

    Le message d’erreur dépend de la version de dissortingbution / 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 est possible que vous manquiez une bibliothèque dans vos étapes de compilation, pendant la phase de liaison. Dans mon cas, j’ai ajouté ‘-lz’ aux indicateurs makefile / GCC.

    Contexte: DSO est un object partagé dynamic ou une bibliothèque partagée.

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

    C’est ce que j’ai eu:

     /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 – même si la libX11.so doit être ajoutée en tant que dépendance, car les arguments contiennent également des bibliothèques GTK et GNOME.

    Donc, la seule explication pour moi est que ce message pourrait avoir été conçu pour 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 le couplage dans POSIX:

    • Les bibliothèques dynamics ont des dépendances définies, de sorte que seules les bibliothèques de la dépendance supérieure doivent être fournies dans n’importe quel ordre (même après les bibliothèques statiques)
    • Les bibliothèques statiques ne contiennent que des symboles non définis – il vous appartient de connaître leurs dépendances et de les fournir toutes dans la ligne de commande.
    • L’ordre dans les bibliothèques statiques est toujours: demandeur d’abord , fournisseur suit . Sinon, vous obtiendrez un message de symbole non défini, comme lorsque vous avez oublié d’append la bibliothèque à la ligne de commande.
    • Lorsque vous spécifiez la bibliothèque avec -l , vous ne savez jamais si elle prendra lib.so ou lib.a . La bibliothèque dynamic est préférable, 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 avez des bibliothèques statiques ou dynamics
    • Eh bien, parfois les dépendances manquent dans les bibliothèques dynamics: D

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

    “LAPACK_LIB = -llapack -lblas” fonctionnait où “LAPACK_LIB = -lblas -llapack” donnait l’erreur décrite ci-dessus.

    J’ai aussi rencontré le même problème. Je ne sais pas pourquoi, je viens d’append l’option -lpthread au compilateur et tout va bien.

    Vieux:

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

    erreur suivante Si -lpthread 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 

    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. Peut-être existe-t-il un moyen astucieux de déterminer le problème, mais c’est ce que je fais:

    • Commentez toutes les bibliothèques liées dans la commande link.
    • Nettoyez tous les .o, les .so, etc (Généralement, make clean suffit, mais vous pouvez lancer une recherche récursive + rm, ou quelque chose de similaire).
    • Décommentez les bibliothèques dans la commande de liaison une par une 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 ne fait que transmettre la liste à l’éditeur de liens, c’est-à-dire qu’elle n’essaie pas de trouver le bon ordre. C’est raisonnable – lorsque vous pensez à ce sujet, cmake ne peut pas savoir quel est le bon ordre tant que la liaison n’est pas terminée avec succès.

    S’il vous plaît append: CFLAGS="-lrt" et LDFLAGS="-lrt"

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

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

    Si vous utilisez g++ , assurez-vous de ne pas utiliser gcc place