Comment copier des fichiers DLL dans le même dossier que l'exécutable à l'aide de CMake?
98
Nous utilisons CMake pour générer les fichiers Visual Studio de nos sources dans notre SVN. Maintenant, mon outil nécessite que certains fichiers DLL se trouvent dans le même dossier que l'exécutable. Les fichiers DLL sont dans un dossier à côté de la source.
Comment puis-je changer mon CMakeLists.txtafin que le projet Visual Studio généré contienne déjà les fichiers DLL particuliers dans les dossiers release / debug ou les copie lors de la compilation?
Si vous avez besoin de copier différentes DLL en fonction de la configuration (Release, Debug, par exemple), vous pouvez les avoir dans des sous-répertoires nommés avec la configuration correspondante:, /libs/Releaseet /libs/Debug. Vous devez ensuite injecter le type de configuration dans le chemin de la dll dans l' add_custom_commandappel, comme ceci:
Note rapide pour ce qui a fonctionné dans mon cas au cas où cela aiderait quelqu'un d'autre à l'avenir: j'ai un projet de bibliothèque statique auquel l'exécutable principal est éventuellement lié, et cette bibliothèque nécessite une DLL à copier si elle est ajoutée. Donc, dans le fichier CMakeLists.txt de cette bibliothèque, j'ai utilisé ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIG>pour la destination cible. Sinon, il le copierait dans le chemin de construction de la bibliothèque, ce qui était inutile.
AberrantWolf le
n'est-ce pas le but des install()directives cmake d'assembler les binaires? Ou peut-être faire des LIBRARYchoses? Je ne connais pas vraiment la chaîne d'outils.
Sandburg
1
$<TARGET_FILE_DIR:MyTest>- qu'Est-ce que c'est? Comment imprimer des informations, que signifient exactement
ilw
Sauf si j'ai manqué quelque chose lors de l'intégration de la commande, cette méthode ne fonctionne pas pour les bibliothèques ajoutées avec IMPORTED_LIBRARIES. Il se plaint de ne pas pouvoir exécuter une commande post-build alors que rien n'a été construit.
Tzalumen
2
Après avoir testé et poussé mon cmake: si vous utilisez des IMPORTEDbibliothèques et que vous devez déplacer les DLL, vous devez utiliser une commande variant. Si vous avez ajouté votre IMPORTEDbibliothèque comme MyImportedLibvous le feriez, COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:MyImportedLib> $<TARGET_FILE_DIR:MyTest>notez que pour exécuter plusieurs commandes de post-construction, vous devez toutes les add_custom_command(TARGET MyTest POST_BUILD COMMAND #your first command# COMMAND #Your second command#)
relier
24
J'ai mis ces lignes dans mon fichier CMakeLists.txt de niveau supérieur. Toutes les bibliothèques et exécutables compilés par CMake seront placés dans le niveau supérieur du répertoire de construction afin que les exécutables puissent trouver les bibliothèques et il est facile de tout exécuter.
set (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
Notez que cela ne résout pas le problème de l'OP de copier des binaires précompilés à partir du répertoire source du projet.
J'ai eu ce problème aujourd'hui lorsque j'ai essayé de créer une version Windows de mon programme. Et j'ai fini par faire des recherches moi-même puisque toutes ces réponses ne me satisfaisaient pas. Il y avait trois problèmes principaux:
Je voulais que les versions de débogage soient liées aux versions de débogage des bibliothèques et que les versions de version soient liées aux versions de version des bibliothèques, respectivement.
En plus de cela, je voulais que les versions correctes des fichiers DLL (Debug / Release) soient copiées dans les répertoires de sortie.
Et je voulais réaliser tout cela sans écrire de scripts complexes et fragiles.
Après avoir parcouru certains manuels CMake et certains projets multiplateformes sur github, j'ai trouvé cette solution:
Déclarez votre bibliothèque comme cible avec l'attribut "IMPORTED", référencez son débogage et publiez les fichiers .lib et .dll.
Associez cette cible à votre projet comme d'habitude
target_link_libraries(YourProg sdl2 ...)
Faites une étape de construction personnalisée pour copier le fichier dll vers sa destination s'il a été modifié d'une manière ou d'une autre depuis la construction précédente
Un addendum à la réponse acceptée, ajouté en tant que réponse distincte afin d'obtenir le formatage du code:
Si vous construisez vos dll dans le même projet, elles seront généralement dans les répertoires Release, Debug, etc. Vous devrez utiliser les variables d'environnement Visual Studio pour les copier correctement. par exemple:
Vous ne pouvez pas utiliser la variable CMake CMAKE_BUILD_TYPE pour la configuration car elle est résolue au moment de la génération du projet VS et sera toujours la valeur par défaut.
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY
${PROJECT_SOURCE_DIR}/lib CACHE
PATH "Directory where all the .lib files are dumped." FORCE)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY
${PROJECT_SOURCE_DIR}/bin CACHE
PATH "Directory where .exe and .dll files are dumped." FORCE)
Je suis un débutant CMake, mais je voulais quand même partager mon expérience. Dans mon cas, j'avais besoin d'une copie post-installation pour que tous mes binaires soient inclus. Dans le cas d'un binaire tiers pouvant être importé dans CMake, ce qui suit fonctionne pour moi:
find_package( dependency REQUIRED )
if( MSVC )
# If done properly and if the dependency has a correct config file, IMPORTED_LOCATION_RELEASE should be defined
get_target_property( DEP_SHARED_LIB_PATH dependency IMPORTED_LOCATION_RELEASE )
# Create a bin directory in the install folder
add_custom_command(TARGET BGS POST_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_INSTALL_PREFIX}/bin/)
# Copy the shared lib file
add_custom_command(TARGET BGS POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${DEP_SHARED_LIB_PATH} ${CMAKE_INSTALL_PREFIX}/bin/)
endif()
De toute évidence, IMPORTED_LOCATION_RELEASE peut avoir des variantes en fonction de la manière dont la bibliothèque partagée a été construite / installée. Peut-être IMPORTED_LOCATION_DEBUG.
Il y a peut-être une meilleure façon d'obtenir ce nom de propriété, je ne sais pas.
Déplacement de fichiers pendant la construction à l'aide de install
J'ai eu ce problème en essayant de suivre le didacticiel officiel de CMake à l' étape 9 . C'était l'emplacement du fichier que je voulais déplacer:
src
|_build
|_Debug
- `MathFunctions.dll`
C'était l'emplacement dans lequel je voulais que le fichier se trouve:
src
|_build
|_install
|_bin
- `MathFunctions.dll`
Étant donné que cette DLL a été générée en tant que bibliothèque partagée, tout ce que j'ai fait était d'inclure cette ligne dans le CMakeLists.txtsous- répertoire contenant le code source de la bibliothèquesrc/Mathfunctions/CMakeLists.txt
Grâce à vos réponses, j'ai pu réfléchir à celle-ci. Est juste une ligne, donc je pense que ça va. Le $<CONFIG>peut avoir deux valeurs Debug ou Release Selon la façon dont le projet est construit, comme la question d'origine l'exige.
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIG>
pour la destination cible. Sinon, il le copierait dans le chemin de construction de la bibliothèque, ce qui était inutile.install()
directives cmake d'assembler les binaires? Ou peut-être faire desLIBRARY
choses? Je ne connais pas vraiment la chaîne d'outils.$<TARGET_FILE_DIR:MyTest>
- qu'Est-ce que c'est? Comment imprimer des informations, que signifient exactementIMPORTED_LIBRARIES
. Il se plaint de ne pas pouvoir exécuter une commande post-build alors que rien n'a été construit.IMPORTED
bibliothèques et que vous devez déplacer les DLL, vous devez utiliser une commande variant. Si vous avez ajouté votreIMPORTED
bibliothèque commeMyImportedLib
vous le feriez,COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:MyImportedLib> $<TARGET_FILE_DIR:MyTest>
notez que pour exécuter plusieurs commandes de post-construction, vous devez toutes lesadd_custom_command(TARGET MyTest POST_BUILD COMMAND #your first command# COMMAND #Your second command#)
J'ai mis ces lignes dans mon fichier CMakeLists.txt de niveau supérieur. Toutes les bibliothèques et exécutables compilés par CMake seront placés dans le niveau supérieur du répertoire de construction afin que les exécutables puissent trouver les bibliothèques et il est facile de tout exécuter.
Notez que cela ne résout pas le problème de l'OP de copier des binaires précompilés à partir du répertoire source du projet.
la source
J'ai eu ce problème aujourd'hui lorsque j'ai essayé de créer une version Windows de mon programme. Et j'ai fini par faire des recherches moi-même puisque toutes ces réponses ne me satisfaisaient pas. Il y avait trois problèmes principaux:
Je voulais que les versions de débogage soient liées aux versions de débogage des bibliothèques et que les versions de version soient liées aux versions de version des bibliothèques, respectivement.
En plus de cela, je voulais que les versions correctes des fichiers DLL (Debug / Release) soient copiées dans les répertoires de sortie.
Et je voulais réaliser tout cela sans écrire de scripts complexes et fragiles.
Après avoir parcouru certains manuels CMake et certains projets multiplateformes sur github, j'ai trouvé cette solution:
Déclarez votre bibliothèque comme cible avec l'attribut "IMPORTED", référencez son débogage et publiez les fichiers .lib et .dll.
Associez cette cible à votre projet comme d'habitude
Faites une étape de construction personnalisée pour copier le fichier dll vers sa destination s'il a été modifié d'une manière ou d'une autre depuis la construction précédente
la source
Un addendum à la réponse acceptée, ajouté en tant que réponse distincte afin d'obtenir le formatage du code:
Si vous construisez vos dll dans le même projet, elles seront généralement dans les répertoires Release, Debug, etc. Vous devrez utiliser les variables d'environnement Visual Studio pour les copier correctement. par exemple:
pour la source et
pour la destination. Notez la fuite!
Vous ne pouvez pas utiliser la variable CMake CMAKE_BUILD_TYPE pour la configuration car elle est résolue au moment de la génération du projet VS et sera toujours la valeur par défaut.
la source
$<CONFIGURATION>
Vous pouvez également utiliser la commande find_library:
Avec un EXECUTABLE_PATH défini, par exemple:
vous pouvez déplacer les fichiers .dll dont votre exécutable a besoin, avec
la source
Ceci est utile pour l'un d'eux
la source
Vous devez probablement ajouter une cible personnalisée et la rendre dépendante de l'une de vos cibles exécutables.
Pour copier un fichier en utilisant la fonction ci-dessus, utilisez:
la source
Je suis un débutant CMake, mais je voulais quand même partager mon expérience. Dans mon cas, j'avais besoin d'une copie post-installation pour que tous mes binaires soient inclus. Dans le cas d'un binaire tiers pouvant être importé dans CMake, ce qui suit fonctionne pour moi:
De toute évidence, IMPORTED_LOCATION_RELEASE peut avoir des variantes en fonction de la manière dont la bibliothèque partagée a été construite / installée. Peut-être IMPORTED_LOCATION_DEBUG.
Il y a peut-être une meilleure façon d'obtenir ce nom de propriété, je ne sais pas.
la source
Déplacement de fichiers pendant la construction à l'aide de
install
J'ai eu ce problème en essayant de suivre le didacticiel officiel de CMake à l' étape 9 . C'était l'emplacement du fichier que je voulais déplacer:
C'était l'emplacement dans lequel je voulais que le fichier se trouve:
Étant donné que cette DLL a été générée en tant que bibliothèque partagée, tout ce que j'ai fait était d'inclure cette ligne dans le
CMakeLists.txt
sous- répertoire contenant le code source de la bibliothèquesrc/Mathfunctions/CMakeLists.txt
Grâce à vos réponses, j'ai pu réfléchir à celle-ci. Est juste une ligne, donc je pense que ça va. Le
$<CONFIG>
peut avoir deux valeurs Debug ou Release Selon la façon dont le projet est construit, comme la question d'origine l'exige.la source