GLFW – Erreurs d’éditeur de liens sur UBuntu 14.04 LTS

Je veux comstackr un exemple de code à partir de ce site (en bas). J’ai téléchargé le code source de GLFW 3.0.4 et je l’ai construit dans un emplacement personnalisé. J’ai utilisé des parameters par défaut et GLFW a été construit en tant que bibliothèque statique. Mon CMakeLists.txt ressemble à ceci:

cmake_minimum_required(VERSION 2.8) project(glfw_test_project) SET(CMAKE_CXX_FLAGS "-Wall -Werror -g -std=c++11") find_package(OpenGL REQUIRED) include_directories(/home/user/MyLibs/OpenGL/glfw-3.0.4/include) link_directories(/home/user/MyLibs/OpenGL/glfw-3.0.4/build/src) add_executable(glfw_test main.cpp) target_link_libraries(glfw_test ${OPENGL_gl_LIBRARY}) target_link_libraries(glfw_test glfw3) 

Quand je cours, je reçois les informations suivantes:

 Linking CXX executable glfw_test /usr/bin/ld: /home/user/MyLibs/OpenGL/glfw-3.0.4/build/src/libglfw3.a(x11_clipboard.co): undefined reference to symbol 'XConvertSelection' //usr/lib/x86_64-linux-gnu/libX11.so.6: error adding symbols: DSO missing from command line collect2: error: ld returned 1 exit status make[2]: *** [glfw_test] Error 1 make[1]: *** [CMakeFiles/glfw_test.dir/all] Error 2 make: *** [all] Error 2 

Qu’est-ce qui ne va pas ?

Edit1 Lorsque je construis GLFW en tant que bibliothèque dynamic, tout fonctionne bien. Ensuite, la dernière ligne de mon CMakeLists.txt doit être remplacée par:

 target_link_libraries(glfw_test glfw) 

Quel est le problème en utilisant une bibliothèque statique?

J’ai rencontré les mêmes problèmes sur Ubuntu 14.04 LTS.

Tout d’abord : error adding symbols: DSO missing from command line affiche un ordre incorrect des parameters de ligne de commande de l’éditeur de liens. Ce post m’a fait réaliser cela. Vous devez appeler $ make VERBOSE=1 pour voir l’appel de l’éditeur de liens et le vérifier de vos propres yeux. Rappelez-vous: TARGET_LINK_LIBRARIES() devrait être la dernière commande de votre CMakeLists.txt Et regardez cette explication de commande .

Deuxièmement : si vous construisez contre des bibliothèques GLFW3 statiques, toutes les bibliothèques X11 ne sont pas automatiquement ajoutées à votre appel d’éditeur de liens, comme cela a déjà été montré ci-dessus. Dans la documentation GLFW, vous pouvez trouver une variable cmake adaptée à vos besoins: ${GLFW_STATIC_LIBRARIES} . Pour l’utiliser et activer un processus de génération plus automatique, laissez pkg-config trouver toutes les dépendances pour les librairies X11:

 CMAKE_MINIMUM_REQUIRED(VERSION 2.8) PROJECT(myProject) FIND_PACKAGE( PkgConfig REQUIRED ) pkg_search_module( GLFW3 REQUIRED glfw3 ) # sets GLFW3 as prefix for glfw vars # now ${GLFW3_INCLUDE_DIR}, ${GLFW3_LIBRARIES} and ${GLFW3_STATIC_LIBRARIES} # are set INCLUDE_DIRECTORIES( ${GLFW3_INCLUDE_DIR} ) ADD_EXECUTABLE( myProject mySource.cpp ) TARGET_LINK_LIBRARIES( myProject ${GLFW_STATIC_LIBRARIES} ) # they include X11 libs 

Vérifiez maintenant les parameters $ make VERBOSE=1 l’éditeur de liens avec $ make VERBOSE=1 et vous devriez trouver beaucoup plus de librairies X11 comme: -lXrandr -lXi -lXrender -ldrm -lXdamage -lXxf86vm -lXext -lX11 et -lpthread .

Troisièmement: lors de la liaison avec la bibliothèque partagée, les dépendances à X11, etc. sont résolues dynamicment. C’est pourquoi vous n’avez pas besoin d’append explicitement des indicateurs de librairies X11 à l’éditeur de liens. Dans ce cas, vous avez uniquement besoin de: TARGET_LINK_LIBRARIES( myProject ${GLFW_LIBRARIES} )

Quasortingèmement : il m’est arrivé que certaines commandes glfwCommands avaient des undefined reference to erreurs de l’éditeur de liens. J’ai découvert que j’avais installé GLFW3 dans /usr/local/lib mais que l’éditeur de liens n’avait reçu que la variable d’environnement LD_LIBRARY_PATH qui n’était définie que sur /usr/lib32 . L’ajout du paramètre -L/usr/local/lib résolu le problème de référence. Pour l’éviter à l’avenir, j’ai défini LD_LIBRARY_PATH=/usr/lib32;/usr/local/lib; .

Astuce: pour vérifier quelles sont les valeurs de vos variables GLFW cmake, imprimez-les lors de la construction:

 FOREACH(item ${GLFW3_STATIC_LIBRARIES}) MESSAGE(STATUS " using lib: " ${item}) ENDFOREACH() 

Il semble que vous ayez résolu votre propre problème en reconstruisant GLFW en tant que bibliothèque partagée et en liant l’exemple de code à cela. Au lieu de cela, je vais essayer de répondre à votre question de suivi sur la raison pour laquelle cela ne fonctionne pas lorsque vous essayez de lier la bibliothèque statique.

Fondamentalement, si vous souhaitez libglfw3.a lien avec la bibliothèque statique libglfw3.a , vous devez lier toutes les bibliothèques X11 dépendantes. Vous obtenez une erreur lors de la liaison de la bibliothèque statique car vous n’avez pas spécifié de bibliothèques supplémentaires à lier, et CMake ne sait pas quelles sont ces dépendances. Vous ne recevez pas d’erreur lorsque vous liez la bibliothèque partagée libglfw.so car les bibliothèques X11 sont liées à la bibliothèque partagée et CMake sait les récupérer automatiquement.

Si vous souhaitez utiliser la bibliothèque statique, vous pouvez déterminer les bibliothèques nécessaires à lier comme suit. Selon le fichier .pc dans GLFW, vous pouvez taper ceci dans la ligne de commande pour savoir ce que sont:

 pkg-config --static --libs x11 xrandr xi xxf86vm gl 

Si vous traduisez cela en une commande CMake, cela ressemblera à ceci:

 target_link_libraries( glfw_test glfw3 Xrandr Xrender Xi GL m dl drm Xdamage X11-xcb xcb-glx xcb-dri2 xcb-dri3 xcb-present xcb-sync xshmfence Xxf86vm Xfixes Xext X11 pthread xcb Xau Xdmcp) 

Donc, si vous ajoutez ceci au CMakeLists.txt , l’exemple de code doit générer sans problème.

Par ailleurs, vous pouvez trouver automatiquement les bibliothèques X11 à l’aide de CMake de la manière suivante:

 find_package(X11 REQUIRED) target_link_libraries( my_program ${X11_LIBRARIES} ) 

Cependant, l’ensemble des bibliothèques stockées dans la variable X11_LIBRARIES contiendra uniquement un sous-ensemble des bibliothèques nécessaires à la liaison statique de GLFW.

Je ne sais pas vraiment comment gérer correctement les liaisons statiques / dynamics dans CMake, mais j’espère que cela vous aidera.