J'essaie d'utiliser ExternalProject_add () pour télécharger/installer les dépendances. Il s'installe correctement, mais je ne sais pas comment lier réellement les bibliothèques après leur téléchargement.
Je veux appeler target_link_libraries () sur la bibliothèque qui vient d'être téléchargée, mais le chemin d'accès à la bibliothèque variera selon le système.
S'il s'agissait d'une dépendance système, je pourrais simplement appeler find_package () - mais les packages n'étaient pas installés sur le chemin de recherche par défaut. Je ne pense pas que vous puissiez spécifier un chemin de recherche pour find_package en mode module.
Voici un extrait de mon CMakeLists.txt qui ne fonctionne pas:
ExternalProject_Add(
protobuf
URL http://protobuf.googlecode.com/files/protobuf-2.4.1.tar.gz
CONFIGURE_COMMAND <SOURCE_DIR>/configure --prefix=<INSTALL_DIR>
PREFIX ${MYPROJ_SOURCE_DIR}/dependencies
)
find_package(protobuf REQUIRED)
set(LIBS ${LIBS} ${PROTOBUF_LIBRARIES})
target_link_libraries (mybinary ${LIBS})
Lorsque vous utilisez ExternalProject_Add, vous ne pouvez pas utiliser find_package, car il n'y a rien à trouver lorsque CMake s'exécute pour configurer le projet externe.
Donc, si l'emplacement des bibliothèques varie selon la plateforme, vous aurez besoin d'une logique conditionnelle basée sur votre plateforme. (Je ne connais pas les bibliothèques ou la structure de protobuf ici, donc ce n'est qu'un exemple, mais cela devrait vous aider à aller dans la bonne direction ...) Quelque chose comme ça:
if(WIN32)
set(PROTOBUF_LIB_DIR "${MYPROJ_SOURCE_DIR}/dependencies/win"
set(prefix "")
set(suffix ".lib")
elseif(Apple)
set(PROTOBUF_LIB_DIR "${MYPROJ_SOURCE_DIR}/dependencies/mac"
set(prefix "lib")
set(suffix ".a")
else()
set(PROTOBUF_LIB_DIR "${MYPROJ_SOURCE_DIR}/dependencies/linux"
set(prefix "lib")
set(suffix ".a")
endif()
set(PROTOBUF_LIBRARIES
"${PROTOBUF_LIB_DIR}/${prefix}protobufLib1${suffix}"
"${PROTOBUF_LIB_DIR}/${prefix}protobufLib2${suffix}")
Certes, c'est moins pratique que d'utiliser find_package. Si vous pouvez utiliser un package pré-construit/pré-installé, vous devriez, afin que vous puissiez utiliser find_package. Si vous devez créer l'autre package à partir du code source dans le cadre de votre projet, ExternalProject_Add est utile, même s'il n'est pas en mesure d'abstraire tous les détails pour vous.
Parce que vous téléchargez le projet externe, vous savez déjà où tout se trouve parce que vous venez de le télécharger, il n'a donc pas besoin d'être "trouvé".
Je l'ai fait fonctionner avec add_library. Ceci est mon code réel qui fonctionne:
ExternalProject_Add(ForexConnectDownload
PREFIX 3rd_party
#--Download step--------------
URL http://fxcodebase.com/bin/forexconnect/1.3.1/ForexConnectAPI-1.3.1-Linux-x86_64.tar.gz
URL_HASH SHA1=7fdb90a2d45085feb8b76167cae419ad4c211d6b
#--Configure step-------------
CONFIGURE_COMMAND ""
#--Build step-----------------
BUILD_COMMAND ""
#--Install step---------------
UPDATE_COMMAND "" # Skip annoying updates for every build
INSTALL_COMMAND ""
)
SET(FXCM_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/3rd_party/src/ForexConnectDownload/include)
SET(FXCM_LIB_DIR ${CMAKE_CURRENT_BINARY_DIR}/3rd_party/src/ForexConnectDownload/lib)
add_library(ForexConnect SHARED IMPORTED)
set_target_properties(ForexConnect PROPERTIES IMPORTED_LOCATION ${FXCM_LIB_DIR}/libForexConnect.so)
À partir de là, chaque programme qui en dépend a besoin d'un add_dependencies
et bien sûr target_link_libraries
. Par exemple:
include_directories(${FXCM_INCLUDE_DIR})
add_executable(syncDatabase syncDatabase.cpp trader/database.cpp trader/fxcm.cpp)
target_link_libraries(syncDatabase ForexConnect)
add_dependencies(syncDatabase ForexConnectDownload)
Les add_dependencies le font attendre avant d'essayer d'inclure les répertoires nécessaires.
Cela fait l'affaire pour moi. Fonctionne avec make -j4. Obtenez toutes les dépendances à droite.
Pour développer la réponse DLRdave ci-dessus, vous n'avez pas besoin de définir manuellement les préfixes et suffixes pour les bibliothèques statiques car CMAKE fournit des variables avec les bonnes pour chaque plate-forme.
Voir CMake Variables utiles pour plus d'informations.
Par exemple:
Un autre idiome que vous pouvez utiliser pour résoudre ce problème:
Vous pouvez voir cet idiome en action dans https://github.com/biometrics/l prévue .
Vous pouvez utiliser la commande link_directories pour lier des bibliothèques dans un répertoire spécifique. Dans votre cas, le répertoire où votre projet externe est construit.
ExternalProject_Add(MyExternalLibrary ...)
Ajoutez le répertoire de sortie au chemin de recherche:
link_directories(${CMAKE_BINARY_DIR}/lib/MyExternalLibrary-prefix/lib)
Assurez-vous d'ajouter l'exécutable après en spécifiant le répertoire de liens:
add_executable(MyProgram main.c)
Spécifiez les bibliothèques auxquelles votre projet doit être lié:
target_link_libraries(MyProgram ExternalLibraryName)
N'oubliez pas de dépendre du projet externe:
add_dependencies(MyProgram MyExternalLibrary)