IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Systèmes de compilation Discussion :

CMake : recherche de bibliothèques et compréhension des variables


Sujet :

Systèmes de compilation

  1. #1
    Membre habitué
    Homme Profil pro
    Doctorant en Astrophysique
    Inscrit en
    Mars 2009
    Messages
    312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Astrophysique
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2009
    Messages : 312
    Points : 176
    Points
    176
    Par défaut CMake : recherche de bibliothèques et compréhension des variables
    Bonjour.

    J'ai un gros problème de compréhension avec CMake (j'ai bien regardé les tutos avant) et notamment en ce qui concerne la définition des variables.

    Pour trouver les bibliothèques quand il y a des modules associés c'est assez pratique. Mais pour une bibliothèque qui n'a pas été prévue, j'ai beaucoup plus de mal.

    Prenons un exemple : un programme, à la compilation, va nécessiter GMP. L'utilisateur a installé GMP dans un répertoire de son choix, avec un sous répertoire include et un sous répertoire lib. Par exemple :

    /perso/gmp/include/gmp.h
    /perso/gmp/include/gmpxx.h
    /perso/gmp/lib/libgmp.a
    /perso/gmp/lib/libgmpxx.a


    J'ai tout un tas de questions :

    1) Comment faire pour que CMake essaye de les trouver automatiquement ?

    2) Comment faire que cela soit réglable au travers du gui cmake pour que l'utilisateur indique où se trouvent les bibliothèques ?

    3) Quand on fait à la fin, TARGET_LINK_LIBRARIES(exemple gmp) comment on sait quel nom de librairie on doit mettre. Là en l'occurence j'ai mis gmp, mais pourquoi pas GMP, pourquoi pas Gmp ou encore libgmp ? Comment je devine ce nom ? Cela correspond il au nom du fichier de bibliothèque (par exemple libgmp.a) auquel j'ai retiré le préfixe "lib" et l'extension ".a" ? Si je veux linker un fichier qui s'appelle libessai393lol.a, je mettrais TARGET_LINK_LIBRARIES(exemple essai393lol) ?

    4) J'ai posé le même genre de question sur stak overflow. Quelqu'un m'a répondu :
    CMake is not so hard to understand.

    First Step

    Use find_package to locate the libary.

    find_package(GMP REQUIRED)

    Second step

    Use include_directories to include the libary header files.

    include_directories(${GOBJECT_INCLUDE_DIR})

    Third Step

    Use target_link_libraries to link your binary against the libary.

    add_executable(ExecutableName Main.cpp)
    target_link_libraries(ExecutableName ${GOBJECT_LIBRARIES})
    Là en l'occurence, je ne comprends pas grand chose (voir questions suivantes) :

    5) find_package(GMP REQUIRED) : find_package n'est-il pas réservé à des "routines" pré écrites ? Là encore pourquoi GMP ? Est-ce parce que le fichier s'appelle libgmp.a, je retire lib et .a et je met ce qui reste en majuscules ? Par exemple pour libessai393lol.a, j'aurai mis find_package(ESSAI393LOL REQUIRED) ?

    6) Alors ensuite le ${GOBJECT_INCLUDE_DIR} et ${GOBJECT_LIBRARIES}, pour moi, ils sortent de l'espace... Est-ce des noms de variables complètement arbitraires qui seront indiqués par l'utilisateur lorsqu'il lancera Cmake ? Ou sinon comment je les trouve ces noms ? Est-ce que un nom de variable avec le suffixe _INCLUDE_DIR ou _LIBRARIES est interprété par CMake, ou j'aurai pu mettre genre ${GOBJECT_INC_DIR} et ${GOBJECT_LIB} ? Le GOBJECT il vient d'où ?

    7) Bon, là en l'occurence la question portait juste sur libgmp et libgmpxx. Admettons maintenant que j'ai un répertoire contenant une vingtaine de librairies. Comment faire pour les inclure/linker toutes ? Il faut que je les traite une par une ?

    Ces questions sont très naïves, mais pour l'instant, j'avance dans le brouillard : je me contente de recopier des trucs sans savoir ce qui sera interprété, ce qui sera proposé à l'utilisateur etc...

    Merci beaucoup à celui/ceux qui prendront le temps de m'éclairer

    EDIT : mon but est de comprendre comment linker simplement une bibliothèque pour laquelle il n'existe pas de module automatique ...

  2. #2
    Membre éprouvé
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2009
    Messages
    552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mars 2009
    Messages : 552
    Points : 1 060
    Points
    1 060
    Par défaut
    Salut,

    Citation Envoyé par Kaluza Voir le message
    1) Comment faire pour que CMake essaye de les trouver automatiquement ?
    Il y a deux méthodes pour que permettre un find_package :
    - soit un fichier de config (gmp-config.cmake ou GMPConfig.cmake) dont le dossier est pointé par la variable CMake GMP_DIR (en principe, plutôt quand la bibliothèque a un support CMake)
    - soit un fichier FindGMP.cmake qui effectue la recherche de la bibliothèque dont le dossier est alors listé dans CMAKE_MODULE_PATH :
    set( CMAKE_MODULE_PATH "/chemin/vers/mes/modules;${CMAKE_MODULE_PATH}" )

    Pour GMP, je crois que ce finder est prédéfini, mais tu peux écrire tes propres finders.

    Dans tous les cas, les variables suivante doivent être définit par le finder :
    <LALIB>_INCLUDE_DIRS repertoire d'include
    <LALIB>_LIBRARIES bibliothèques a lier
    et parfois
    <LALIB>_LIBRARY_DIRS répertoires des bibliothèques

    En général, les finders réagissent en fonction de variable. Par exemple, si tu écrivais un module find pour gmp, tu pourrais utiliser GMP_ENABLE_CXX et activer ou non la liaison à gmpxx.
    Ces finders sont documentés en entête du fichier Find<LALIB>.cmake en généra pour lister les variables influençant la recherche et les variables définies par le finder.

    Citation Envoyé par Kaluza Voir le message
    2) Comment faire que cela soit réglable au travers du gui cmake pour que l'utilisateur indique où se trouvent les bibliothèques ?
    Les finders utilisent des variables, par exemple, <LALIB>_INCLUDE_DIR et <LALIB>_LIBRARY_DIR. Les "set" peuvent être repris dans l'interface cmake-gui
    set( <LALIB>_INCLUDE_DIR "C:\MonDossier" CACHE FILEPATH "Chemin vers la bibliothèque <LALIB> )
    (http://www.cmake.org/cmake/help/cmake-2-8-docs.html, rubrique set)


    Citation Envoyé par Kaluza Voir le message
    3) Quand on fait à la fin, TARGET_LINK_LIBRARIES(exemple gmp) comment on sait quel nom de librairie on doit mettre. Là en l'occurence j'ai mis gmp, mais pourquoi pas GMP, pourquoi pas Gmp ou encore libgmp ? Comment je devine ce nom ? Cela correspond il au nom du fichier de bibliothèque (par exemple libgmp.a) auquel j'ai retiré le préfixe "lib" et l'extension ".a" ? Si je veux linker un fichier qui s'appelle libessai393lol.a, je mettrais TARGET_LINK_LIBRARIES(exemple essai393lol) ?
    Normalement, le finder définit cette variable et du coup, tu fais
    TARGET_LINK_LIBRARIES(exemple ${GMP_LIBRARIES})


    Citation Envoyé par Kaluza Voir le message
    4) J'ai posé le même genre de question sur stak overflow. Quelqu'un m'a répondu :
    ???


    Citation Envoyé par Kaluza Voir le message
    5) find_package(GMP REQUIRED) : find_package n'est-il pas réservé à des "routines" pré écrites ? Là encore pourquoi GMP ? Est-ce parce que le fichier s'appelle libgmp.a, je retire lib et .a et je met ce qui reste en majuscules ? Par exemple pour libessai393lol.a, j'aurai mis find_package(ESSAI393LOL REQUIRED) ?
    Tu aurais un message qui te dit de définir ESSAI93LOL_DIR sur le dossier contenant ESSAI93LOLConfig.cmake ou d'ajouter à CMAKE_MODULE_PATH le chemin vers FindESSAI93LOL.cmake

    Citation Envoyé par Kaluza Voir le message
    6) Alors ensuite le ${GOBJECT_INCLUDE_DIR} et ${GOBJECT_LIBRARIES}, pour moi, ils sortent de l'espace... Est-ce des noms de variables complètement arbitraires qui seront indiqués par l'utilisateur lorsqu'il lancera Cmake ? Ou sinon comment je les trouve ces noms ? Est-ce que un nom de variable avec le suffixe _INCLUDE_DIR ou _LIBRARIES est interprété par CMake, ou j'aurai pu mettre genre ${GOBJECT_INC_DIR} et ${GOBJECT_LIB} ? Le GOBJECT il vient d'où ?
    Ca pourrait être n'importe quoi, par convention (un peu trop faiblement affirmée dans les docs), ca ne l'est pas comme expliqué en 1.

    Citation Envoyé par Kaluza Voir le message
    7) Bon, là en l'occurence la question portait juste sur libgmp et libgmpxx. Admettons maintenant que j'ai un répertoire contenant une vingtaine de librairies. Comment faire pour les inclure/linker toutes ? Il faut que je les traite une par une ?
    Il vaut mieux les traiter une par une je pense. Note que pour certains linker l'ordre du link est important gmpxx gmp, et non gmp gmpxx...


    Citation Envoyé par Kaluza Voir le message
    EDIT : mon but est de comprendre comment linker simplement une bibliothèque pour laquelle il n'existe pas de module automatique ...
    - Soit tu apprends à écrire des modules automatiques (il en existe un tas de prédéfinit, sous windows, C:\Program Files\CMake\shared\modules\Find*.cmake)
    - Soit tu écris des fichiers de config en attendant de savoir écrire des modules find (moins puissant, approche non standard, mais moins tortueuse pour débuter que les macros find)

    Quelques ressources :
    http://www.vtk.org/Wiki/CMake/Tutorials/Packaging
    http://www.vtk.org/Wiki/CMake:How_To_Find_Libraries

    En espérant que ça t'aide à défricher...
    ++

  3. #3
    Membre habitué
    Homme Profil pro
    Doctorant en Astrophysique
    Inscrit en
    Mars 2009
    Messages
    312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Astrophysique
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2009
    Messages : 312
    Points : 176
    Points
    176
    Par défaut
    Merci beaucoup pour ta réponse détaillée . Ca m'aide effectivement pas mal à défricher. Le problème est qu'en fait, je dois passer assez rapidement un projet de taille moyenne (dans le cadre du "Summer of Code" de l'agence spatiale européenne) actuellement géré par qmake, à CMake pour faciliter le développement ultérieur par une communauté de développeurs. Je ne passe donc pas par la phase d'apprentissage classique qui consisterai à démarrer un petit projet avec des problèmes de linking au fur à mesure, mais là j'ai directement une bonne dizaine de dépendances à gérer (Qt, OSG, GMP, GSL, Qwt, Cspice, Boinc...) . Donc en plus, comme je ne connais pas trop CMake, ce n'est pas hyper évident de bien comprendre comment cela fonctionne...

    Je pense que d'autres questions viendront...

  4. #4
    Membre habitué
    Homme Profil pro
    Doctorant en Astrophysique
    Inscrit en
    Mars 2009
    Messages
    312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Astrophysique
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2009
    Messages : 312
    Points : 176
    Points
    176
    Par défaut
    Une petite question :

    Voilà, je veux que CMake me link libboinc_api.a et libboinc.a.
    Si je tappe (comme cela est fait pour la plupart des exemples fourni) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    FIND_LIBRARY(BOINC_LIBRARY NAMES libboinc_api libboinc
                 DOC "The Boinc libraries")
    MESSAGE(${BOINC_LIBRARY})
    CMake ne trouve rien.

    Si en revanche, je tappe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    FIND_LIBRARY(BOINC_LIBRARY NAMES libboinc_api.a libboinc.a
                 DOC "The Boinc libraries")
    MESSAGE(${BOINC_LIBRARY})
    Le message m'affiche /usr/lib/libboinc_api.a, c'est à dire juste la première (or l'autre est au même endroit).

    Ma question est la suivante :
    - comment cela se fait il que je sois forcé de préciser le .a alors que dans tous les modules fourni, cela n'est jamais précisé ?
    - comment faire pour qu'il me trouve les 2 (ou peut être qu'en l'état ça va, je ne sais pas bien comment CMake gère les choses) ?

    Merci beaucoup

  5. #5
    Membre éprouvé
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2009
    Messages
    552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mars 2009
    Messages : 552
    Points : 1 060
    Points
    1 060
    Par défaut
    Bonsoir,

    Alors rapidement, je pense (à vérifier) que pour chercher : libboinc_api.a, il faut chercher "boinc_api" (le préfixe "lib" étant typique gcc/linux). Avec visual, tu aurais "boinc_api.lib" au lieu de "libboinc_api.a"

    Je ne connais pas le comportement exact de find_library. Je pense qu'il cherche l'une des deux bibliothèques dans NAMES. Là, la présence de deux .a me laisse penser que tu dois faire deux find_library... (coeur et api)

    Recherche la fonction find_library dans la page d'aide pour plus de détail
    http://www.cmake.org/cmake/help/cmak...d:find_library


    ++

  6. #6
    Membre habitué
    Homme Profil pro
    Doctorant en Astrophysique
    Inscrit en
    Mars 2009
    Messages
    312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Astrophysique
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2009
    Messages : 312
    Points : 176
    Points
    176
    Par défaut
    Bien vu !
    Par contre il me trouve le .so au lieu du .a. Comment forcer la librairie statique ?

    De plus, sur Stack Overflow, on m'a conseillé de regarder findALSA.cmake qui est un exemple des bonnes pratiques. C'est effectivement pas mal comme exemple. Toutefois, il y a un truc que je ne comprends pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    find_path(ALSA_INCLUDE_DIR NAMES asoundlib.h
              PATH_SUFFIXES alsa
              DOC "The ALSA (asound) include directory"
    )
     
    find_library(ALSA_LIBRARY NAMES asound
              DOC "The ALSA (asound) library"
    )
     
    # handle the QUIETLY and REQUIRED arguments and set ALSA_FOUND to TRUE if 
    # all listed variables are TRUE
    include("${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake")
    FIND_PACKAGE_HANDLE_STANDARD_ARGS(ALSA DEFAULT_MSG ALSA_LIBRARY ALSA_INCLUDE_DIR)
     
    if(ALSA_FOUND)
      set( ALSA_LIBRARIES ${ALSA_LIBRARY} )
      set( ALSA_INCLUDE_DIRS ${ALSA_INCLUDE_DIR} )
    endif()
     
    mark_as_advanced(ALSA_INCLUDE_DIR ALSA_LIBRARY)
    Ce qui m'échappe c'est le :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if(ALSA_FOUND)
      set( ALSA_LIBRARIES ${ALSA_LIBRARY} )
      set( ALSA_INCLUDE_DIRS ${ALSA_INCLUDE_DIR} )
    endif()
    Cela veut-il dire que pour linker plusieurs bibliothèques, il faut que je fasse des FIND séparés, et les compiler ensuite dans "LIBRARIES" avec un "S" ?

  7. #7
    Membre éprouvé
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2009
    Messages
    552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mars 2009
    Messages : 552
    Points : 1 060
    Points
    1 060
    Par défaut
    Bonjour,

    C'est juste des définitions de variable à partir d'autre variable, à savoir
    ALSA_LIBRARIES := valeur de ALSA_LIBRARY
    ALSA_INCLUDE_DIRS := valeur de ALSA_INCLUDE_DIR

    Ce sont les deux variables obligatoires, au pluriel.

    Cela veut dire que pour linker, tu dois te reposer sur ces variables au pluriel et non ces variables au singulier.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    find_package( ALSA REQUIRED )
    include_directories( ${ALSA_INCLUDE_DIRS} )
    add_executable( MainBaseSurAlsa main.cpp )
    target_link_libraries( MainBaseSurAlsa ${ALSA_LIBRARIES} )
    Lorsque que tu as plusieurs fichier .a pour une même bibliothèque (si ALSA possède des extensions par exemple), tu auras plusieurs valeurs dans ALSA_LIBRARIES ("/chemin/vers/alsa.a;/chemin/vers/extension-alsa.a")

    Lorsque tu as plusieurs bibliothèques (Qt, ALSA, GMP), tu enchaînes en effet 3 find (ce qui permet au passage de réutiliser tes finders une fois écrit)

    ++

Discussions similaires

  1. [XML / XPATH] Compréhension des critères de recherche
    Par Skyou dans le forum XSL/XSLT/XPATH
    Réponses: 7
    Dernier message: 23/06/2010, 14h39
  2. [PHP 5.0] Recherche aléatoire des variables dans un fichier texte
    Par schats dans le forum Langage
    Réponses: 8
    Dernier message: 22/05/2010, 13h02
  3. Rechercher des données en fonction des variables d'un tableau
    Par BOU59000 dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 01/07/2009, 13h43
  4. Recherches de valeurs max parmi des variables
    Par pyratos dans le forum SQL
    Réponses: 3
    Dernier message: 25/06/2007, 09h53
  5. Réponses: 5
    Dernier message: 19/03/2006, 18h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo