CMake FIND_PACKAGE réussit mais renvoie un chemin incorrect

J’essaye d’avoir le lien de CMake 2.8.6 pour amplifier :: program_options en utilisant le code suivant dans mon CMakeLists.txt

FIND_PACKAGE(Boost COMPONENTS program_options REQUIRED) INCLUDE_DIRECTORIES (${Boost_INCLUDE_DIR}) ADD_EXECUTABLE (segment segment.cpp) TARGET_LINK_LIBRARIES (segment ${Boost_LIBRARIES}) 

La commande find semble réussir mais passe le mauvais répertoire à l’éditeur de liens. Le paquet est actuellement dans:

 `/usr/lib64/libboost_program_options-mt.so.5` 

mais CMakeFiles/segment.dir/link.txt répertorie les éléments suivants:

 /cm/shared/apps/gcc/4.4.6/bin/c++ CMakeFiles/segment.dir/segment.cpp.o -o segment -rdynamic /usr/lib64/lib64/libboost_program_options-mt.so.5 -lpthread -lrt -Wl,-rpath,/usr/lib64/lib64 

Notez l’extra lib64 dans le chemin. De plus, le drapeau -l devant le chemin semble manquer.

Lors de l’exécution de CMake, il indique qu’il a correctement trouvé le paquet et que la variable {$Boost_LIBRARIES} semble lister les bonnes bibliothèques:

 Boost found. Found Boost components: program_options ${Boost_LIBRARIES} - optimized;boost_program_options-mt-shared;debug;boost_program_options-mt-shared-debug 

Le fichier CMakeCache.txt généré commence par:

 //The directory containing a CMake configuration file for Boost. Boost_DIR:PATH=/usr/lib64/boost //Boost include directory Boost_INCLUDE_DIR:FILEPATH=/usr/include 

Ce qui semble être correct. Mais lors de l’exécution, make utilise le chemin dans link.txt ci-dessus et j’obtiens l’erreur suivante:

 make[2]: *** No rule to make target `/usr/lib64/lib64/libboost_program_options-mt.so.5', needed by `segment'. Stop. make[1]: *** [CMakeFiles/segment.dir/all] Error 2 make: *** [all] Error 2 

Qu’est-ce qui pourrait causer cette injection supplémentaire d’un sous-répertoire dans le chemin? Qu’est-ce qui pourrait causer Link.txt de cette manière? Et comment puis-je le réparer (ou le contourner)?

Ce problème se produit lors de l’utilisation d’anciennes versions de boost avec cmake-2.8.6-rc2 ou version ultérieure, où le code de recherche du paquet boost a été modifié.

Le problème peut être -DBoost_NO_BOOST_CMAKE=ON spécifiant -DBoost_NO_BOOST_CMAKE=ON sur la ligne de commande cmake.

Le commit actuel où ce problème est introduit est 7da796d1fdd7cca07df733d010cd343f6f8787a9 et peut être consulté ici .

Le problème vient du fichier dissortingbué boost-devel: /usr/lib64/boost/Boost-relwithdebinfo.cmake

Le paquetage cmake-2.6 n’utilise pas du tout ce fichier, car le fichier FindBoost.cmake renvoie des chemins d’access (corrects) complets pour renforcer les bibliothèques. Le fichier cmake28-2.8.8 FindBoost.cmake renvoie des chaînes de bibliothèque telles que “boost_date_time-mt-shared”, cibles définies dans /usr/lib64/boost/Boost-relwithdebinfo.cmake.

Tout en haut de /usr/lib64/boost/Boost-relwithdebinfo.cmake, une variable nommée _IMPORT_PREFIX est définie à partir de l’emplacement du fichier cmake lui-même, puis utilisée comme suit:

 #---------------------------------------------------------------- # Generated CMake target import file for configuration "RelWithDebInfo". #---------------------------------------------------------------- # Commands may need to know the format version. SET(CMAKE_IMPORT_FILE_VERSION 1) # Compute the installation prefix relative to this file. GET_FILENAME_COMPONENT(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH) GET_FILENAME_COMPONENT(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH) # Import target "boost_date_time-static" for configuration "RelWithDebInfo" SET_PROPERTY(TARGET boost_date_time-static APPEND PROPERTY IMPORTED_CONFIGURATIONS RELWITHDEBINFO) SET_TARGET_PROPERTIES(boost_date_time-static PROPERTIES IMPORTED_LOCATION_RELWITHDEBINFO "${_IMPORT_PREFIX}/lib64/libboost_date_time.a" ) 

Ceci définit _IMPORT_PREFIX sur “/ usr / lib64”, qui est concaténé avec une autre chaîne contenant également / lib64 /. J’ai constaté que si je modifiais simplement le fichier pour inclure un troisième appel GET_FILENAME_COMPONENT, cela fonctionnerait correctement. Ainsi:

 #---------------------------------------------------------------- # Generated CMake target import file for configuration "RelWithDebInfo". #---------------------------------------------------------------- # Commands may need to know the format version. SET(CMAKE_IMPORT_FILE_VERSION 1) # Compute the installation prefix relative to this file. GET_FILENAME_COMPONENT(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH) GET_FILENAME_COMPONENT(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH) GET_FILENAME_COMPONENT(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH) # Import target "boost_date_time-static" for configuration "RelWithDebInfo" SET_PROPERTY(TARGET boost_date_time-static APPEND PROPERTY IMPORTED_CONFIGURATIONS RELWITHDEBINFO) SET_TARGET_PROPERTIES(boost_date_time-static PROPERTIES IMPORTED_LOCATION_RELWITHDEBINFO "${_IMPORT_PREFIX}/lib64/libboost_date_time.a" ) 

Cela semble être un problème avec CMake 2.8.6 sur CentOS. Lorsque vous faites la même chose avec 2.6.4 ou 2.8.3, cela fonctionne correctement. Également avec 2.8.7 sur OS X, cela fonctionne également correctement.

Je vois aussi le problème sur la version 2.8.8 précompilée de cmake utilisant CentOS 64-bit 6.2

J’ai remarqué ce problème sur la version 2.8.11.2 de cmake avec boost-1.41.0-18.el6.x86_64.

La réponse approuvée ne semble pas satisfaisante car, en ajoutant cette définition à l’exécution de cmake, je reçois:

CMake Warning: Les variables spécifiées manuellement n’ont pas été utilisées par le projet:

 Boost_NO_BOOST_CMAKE 

Je n’arrive pas à commenter ou à faire baisser le nombre de voix car je ne participe pas suffisamment à stackoverflow. C’est un problème de poule et d’oeuf!

Je ne peux pas non plus sembler excuser l’explication de Kai Meyer. Cependant, je pense que cela explique vraiment le problème.

D’après ce que je comprends, il semble qu’en résumé, FindBoost.cmake fourni par CMake semble soudainement ne pas trouver Boost, le code de recherche cherche donc maintenant dans le script fourni par cmake pour cmake, qui à son tour a un bug et semble ne pas retourner le chemin correct.