web-dev-qa-db-fra.com

cmake - find_library - emplacement de la bibliothèque personnalisée

J'essaie actuellement de faire fonctionner CMake pour mon projet (sous Windows). Je veux utiliser un emplacement personnalisé où toutes les bibliothèques sont installées. Pour informer CMake de ce chemin, j'ai essayé de le faire:

set(CMAKE_PREFIX_PATH D:/develop/cmake/libs)

Mais quand j'essaie de trouver la bibliothèque avec

find_library(CURL_LIBRARY NAMES curl curllib libcurl_imp curllib_static)

CMake ne le trouve pas. Lorsque je définis mon chemin de préfixe sur

set(CMAKE_PREFIX_PATH D:/develop/cmake/libs/curl)

... la bibliothèque est située. 

Ma question est donc la suivante: Comment configurer correctement CMake pour qu’il fonctionne avec une structure de répertoire située à un emplacement personnalisé ressemblant à ceci:

D:/develop/cmake/libs/
-> libA
   -> include
   -> lib
-> libB
   -> include
   -> lib
-> ...
   -> include
   -> lib

Dans "include", les en-têtes publics et dans "lib" sont les bibliothèques compilées.

J'espère que quelqu'un pourra m'aider - Merci d'avance

modifier: La solution actuelle pour moi est de le faire avant de chercher des bibliothèques:

set(CUSTOM_LIBRARY_PATH D:/develop/cmake/libs)
file(GLOB sub-dir ${CUSTOM_LIBRARY_PATH}/*)
foreach(dir ${sub-dir})
    if(IS_DIRECTORY ${dir})
        set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH};${dir})
    endif()
endforeach()

Mais de cette façon, le module par défaut de boost ne le trouvera que parce que la structure de répertoire de boost est un peu différente. 

boost -> include -> boost-1_50 -> *.hpp

Lorsque je déplace le contenu si "boost-1_50" doit "inclure" la bibliothèque peut être trouvée, mais de cette manière, il n'est pas possible de gérer plusieurs versions, n'est-ce pas?

44
Daniel

J'ai vu que deux personnes mettaient cette question dans leurs favoris, alors je vais essayer de répondre à la solution qui me convient: Ces fichiers sont extrêmement simples et peuvent également être utilisés pour définir des variables non standard. CMake recherchera (au moins sous Windows) ces fichiers de configuration dans 

CMAKE_PREFIX_PATH/<<package_name>>-<<version>>/<<package_name>>-config.cmake

(qui peut être défini via une variable d'environnement) . Ainsi, par exemple, la configuration de boost est dans le chemin

CMAKE_PREFIX_PATH/boost-1_50/boost-config.cmake

Dans cette configuration, vous pouvez définir des variables. Mon fichier de configuration pour boost ressemble à ceci:

set(boost_INCLUDE_DIRS ${boost_DIR}/include)
set(boost_LIBRARY_DIR ${boost_DIR}/lib)
foreach(component ${boost_FIND_COMPONENTS}) 
    set(boost_LIBRARIES ${boost_LIBRARIES} debug ${boost_LIBRARY_DIR}/libboost_${component}-vc110-mt-Gd-1_50.lib)
    set(boost_LIBRARIES ${boost_LIBRARIES} optimized ${boost_LIBRARY_DIR}/libboost_${component}-vc110-mt-1_50.lib)
endforeach()
add_definitions( -D_WIN32_WINNT=0x0501 )

Très simple, il est possible de réduire encore plus la taille des fichiers de configuration lorsque vous écrivez certaines fonctions d'assistance. Le seul problème que j'ai avec cette configuration est que je n'ai pas trouvé le moyen de donner une priorité aux fichiers de configuration par rapport aux modules de recherche - vous devez donc supprimer les modules de recherche.

J'espère que cela est utile pour d'autres personnes.

12
Daniel

La solution la plus simple consiste peut-être à ajouter HINTS à chaque demande find_* .

Par exemple:

find_library(CURL_LIBRARY
    NAMES curl curllib libcurl_imp curllib_static
    HINTS "${CMAKE_PREFIX_PATH}/curl/lib"
)

Pour Boost, je vous recommande vivement d'utiliser le module standard FindBoost et de définir la variable BOOST_DIR pour qu'elle pointe vers vos bibliothèques Boost.

21
Silas Parker

Il n’ya aucun moyen de définir automatiquement CMAKE_PREFIX_PATH comme vous le souhaitez. Je vois les moyens suivants pour résoudre ce problème:

  1. Placez tous les fichiers de bibliothèques dans le même répertoire. C'est-à-dire que include/ contiendrait des en-têtes pour toutes les bibliothèques, lib/ - binaires, etc. À titre d'information, il s'agit d'une disposition commune pour la plupart des systèmes de type UNIX.

  2. Définissez la variable d'environnement globale CMAKE_PREFIX_PATH sur D:/develop/cmake/libs/libA;D:/develop/cmake/libs/libB;.... Lorsque vous exécutez CMake, il va automatiquement sélectionner cette variable d’environnement et remplir son propre CMAKE_PREFIX_PATH.

  3. Écrivez un script .bat de wrapper, qui appelle la commande cmake avec l'argument -D CMAKE_PREFIX_PATH=....

7
arrowd

Vous avez un niveau supplémentaire d'imbrication . CMAKE recherchera sous $CMAKE_PREFIX_PATH/include pour les en-têtes et $CMAKE_PREFIX_PATH/libs pour les bibliothèques. 

De CMAKE documentation :

Pour chaque chemin de la liste CMAKE_PREFIX_PATH, CMake vérifiera "PATH/include" et "PATH" lorsque FIND_PATH () est appelé, "PATH/bin" et "PATH" lorsque FIND_PROGRAM () est appelé et "PATH/lib et" PATH "lorsque FIND_LIBRARY () est appelé.

4
Sameer Asal

Utilisez CMAKE_PREFIX_PATH en ajoutant plusieurs chemins (séparés par des points-virgules et pas d'espaces blancs). Vous pouvez le définir comme une variable d'environnement pour éviter d'avoir des chemins absolus dans vos fichiers de configuration cmake.

Notez que cmake recherchera le fichier de configuration dans l’un des dossiers suivants Où est l’un des chemins dans CMAKE_PREFIX_PATH et nom est le nom de la bibliothèque recherchée

<prefix>/                                               (W)
<prefix>/(cmake|CMake)/                                 (W)
<prefix>/<name>*/                                       (W)
<prefix>/<name>*/(cmake|CMake)/                         (W)
<prefix>/(lib/<Arch>|lib|share)/cmake/<name>*/          (U)
<prefix>/(lib/<Arch>|lib|share)/<name>*/                (U)
<prefix>/(lib/<Arch>|lib|share)/<name>*/(cmake|CMake)/  (U)

Dans votre cas, vous devez ajouter à CMAKE_PREFIX_PATH les deux chemins suivants:

D:/develop/cmake/libs/libA;D:/develop/cmake/libB
4
Pierluigi

J'ai rencontré un scénario similaire. Je l'ai résolu en ajoutant dans le code suivant juste avant find_library():

set(CMAKE_PREFIX_PATH /the/custom/path/to/your/lib/)

alors il peut trouver l'emplacement de la bibliothèque.

0
vivi