¿Cómo copiar archivos DLL en la misma carpeta que el ejecutable usando CMake?
98
Usamos CMake para generar los archivos de Visual Studio de nuestras fuentes en nuestro SVN. Ahora mi herramienta requiere que algunos archivos DLL estén en la misma carpeta que el ejecutable. Los archivos DLL están en una carpeta junto a la fuente.
¿Cómo puedo cambiar mi de CMakeLists.txtmodo que el proyecto de Visual Studio generado ya tenga los archivos DLL particulares en las carpetas de liberación / depuración o los copie al compilarlos?
Si necesita copiar diferentes dlls dependiendo de la configuración (Release, Debug, por ejemplo), entonces puede tenerlos en subdirectorios nombrados con la configuración correspondiente:, /libs/Releasey /libs/Debug. Luego, debe inyectar el tipo de configuración en la ruta a la dll en la add_custom_commandllamada, así:
Nota rápida para lo que funcionó en mi caso en caso de que ayude a alguien más en el futuro: tengo un proyecto de biblioteca estática con el que el ejecutable principal se vincula opcionalmente, y esa biblioteca requiere que se copie una DLL si se agrega. Entonces, en el archivo CMakeLists.txt de esa biblioteca que usé ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIG>para el destino de destino. De lo contrario, lo copiaría a la ruta de construcción de la biblioteca, lo cual era inútil.
AberrantWolf
¿No es el objetivo de las install()directivas cmake ensamblar los binarios? ¿O tal vez hacer LIBRARYcosas? Realmente no conozco la cadena de herramientas.
Sandburg
1
$<TARGET_FILE_DIR:MyTest>- ¿Qué es? Cómo imprimir información, qué significa exactamente
ilw
A menos que me perdí algo cuando estaba integrando el comando, este método no funciona para las bibliotecas agregadas IMPORTED_LIBRARIES. Se queja de no poder ejecutar un comando posterior a la compilación cuando no se ha compilado nada.
Tzalumen
2
Al probar y presionar mi cmake: si está usando IMPORTEDbibliotecas y necesita reubicar las DLL, debe usar un comando de variante. Si ha agregado su IMPORTEDbiblioteca como MyImportedLiblo usaría, tenga en COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:MyImportedLib> $<TARGET_FILE_DIR:MyTest>cuenta que para ejecutar varios comandos posteriores a la compilación los necesita todos enlazados en un comando personalizado, por ejemploadd_custom_command(TARGET MyTest POST_BUILD COMMAND #your first command# COMMAND #Your second command#)
Tzalumen
24
Pongo estas líneas en mi archivo CMakeLists.txt de nivel superior. Todas las bibliotecas y ejecutables compilados por CMake se colocarán en el nivel superior del directorio de compilación para que los ejecutables puedan encontrar las bibliotecas y sea fácil ejecutar todo.
set (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
Tenga en cuenta que esto no resuelve el problema del OP de copiar archivos binarios precompilados del directorio fuente del proyecto.
Hoy he tenido este problema cuando intenté hacer una compilación de Windows de mi programa. Y terminé investigando un poco, ya que todas estas respuestas no me satisfacían. Hubo tres problemas principales:
Quería que las compilaciones de depuración estuvieran vinculadas con las versiones de depuración de las bibliotecas y que las compilaciones de lanzamiento estuvieran vinculadas con las compilaciones de lanzamiento de las bibliotecas, respectivamente.
Además de eso, quería que las versiones correctas de los archivos DLL (Debug / Release) se copiaran en los directorios de salida.
Y quería lograr todo esto sin escribir guiones complejos y frágiles.
Después de navegar por algunos manuales de CMake y algunos proyectos multiplataforma en github, encontré esta solución:
Declare su biblioteca como destino con el atributo "IMPORTADO", haga referencia a su depuración y libere los archivos .lib y .dll.
Vincula este objetivo con tu proyecto como de costumbre
target_link_libraries(YourProg sdl2 ...)
Realice un paso de compilación personalizado para copiar el archivo dll a su destino si se ha modificado de alguna manera desde la compilación anterior
Un apéndice a la respuesta aceptada, agregado como una respuesta separada para obtener el formato de código:
Si está compilando sus dlls en el mismo proyecto, normalmente estarán en los directorios Release, Debug, etc. Tendrá que usar las variables de entorno de Visual Studio para copiarlas correctamente. p.ej:
No puede usar la variable CMake CMAKE_BUILD_TYPE para la configuración, ya que se resuelve en el momento de la generación del proyecto VS y siempre será el valor predeterminado.
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)
Soy un principiante de CMake, pero aún así quería compartir mi experiencia. En mi caso, necesitaba una copia posterior a la instalación para que todos mis binarios estén en. En el caso de binarios de terceros que se pueden importar dentro de CMake, lo siguiente funciona para mí:
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()
Obviamente, IMPORTED_LOCATION_RELEASE puede tener variantes dependiendo de cómo se construyó / instaló la biblioteca compartida. Podría ser IMPORTED_LOCATION_DEBUG.
Quizás haya una mejor manera de obtener ese nombre de propiedad, no lo sé.
Mover archivos durante la compilación usando install
Tuve este problema al intentar seguir el tutorial oficial de CMake en el Paso 9 . Esta era la ubicación del archivo que quería mover:
src
|_build
|_Debug
- `MathFunctions.dll`
Esta era la ubicación en la que quería que estuviera el archivo:
src
|_build
|_install
|_bin
- `MathFunctions.dll`
Dado que esta DLL se generó como una biblioteca compartida, todo lo que hice fue incluir esta línea CMakeLists.txten el subdirectorio que contenía el código fuente de la bibliotecasrc/Mathfunctions/CMakeLists.txt
Gracias a tus respuestas pude pensar en este. Es solo una línea, así que creo que está bien. El $<CONFIG>puede tener dos valores de depuración o la versión Dependiendo de cómo se construye el proyecto, ya que la pregunta original requiere.
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIG>
para el destino de destino. De lo contrario, lo copiaría a la ruta de construcción de la biblioteca, lo cual era inútil.install()
directivas cmake ensamblar los binarios? ¿O tal vez hacerLIBRARY
cosas? Realmente no conozco la cadena de herramientas.$<TARGET_FILE_DIR:MyTest>
- ¿Qué es? Cómo imprimir información, qué significa exactamenteIMPORTED_LIBRARIES
. Se queja de no poder ejecutar un comando posterior a la compilación cuando no se ha compilado nada.IMPORTED
bibliotecas y necesita reubicar las DLL, debe usar un comando de variante. Si ha agregado suIMPORTED
biblioteca comoMyImportedLib
lo usaría, tenga enCOMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:MyImportedLib> $<TARGET_FILE_DIR:MyTest>
cuenta que para ejecutar varios comandos posteriores a la compilación los necesita todos enlazados en un comando personalizado, por ejemploadd_custom_command(TARGET MyTest POST_BUILD COMMAND #your first command# COMMAND #Your second command#)
Pongo estas líneas en mi archivo CMakeLists.txt de nivel superior. Todas las bibliotecas y ejecutables compilados por CMake se colocarán en el nivel superior del directorio de compilación para que los ejecutables puedan encontrar las bibliotecas y sea fácil ejecutar todo.
Tenga en cuenta que esto no resuelve el problema del OP de copiar archivos binarios precompilados del directorio fuente del proyecto.
fuente
Hoy he tenido este problema cuando intenté hacer una compilación de Windows de mi programa. Y terminé investigando un poco, ya que todas estas respuestas no me satisfacían. Hubo tres problemas principales:
Quería que las compilaciones de depuración estuvieran vinculadas con las versiones de depuración de las bibliotecas y que las compilaciones de lanzamiento estuvieran vinculadas con las compilaciones de lanzamiento de las bibliotecas, respectivamente.
Además de eso, quería que las versiones correctas de los archivos DLL (Debug / Release) se copiaran en los directorios de salida.
Y quería lograr todo esto sin escribir guiones complejos y frágiles.
Después de navegar por algunos manuales de CMake y algunos proyectos multiplataforma en github, encontré esta solución:
Declare su biblioteca como destino con el atributo "IMPORTADO", haga referencia a su depuración y libere los archivos .lib y .dll.
Vincula este objetivo con tu proyecto como de costumbre
Realice un paso de compilación personalizado para copiar el archivo dll a su destino si se ha modificado de alguna manera desde la compilación anterior
fuente
Un apéndice a la respuesta aceptada, agregado como una respuesta separada para obtener el formato de código:
Si está compilando sus dlls en el mismo proyecto, normalmente estarán en los directorios Release, Debug, etc. Tendrá que usar las variables de entorno de Visual Studio para copiarlas correctamente. p.ej:
para la fuente y
para el destino. ¡Tenga en cuenta el escape!
No puede usar la variable CMake CMAKE_BUILD_TYPE para la configuración, ya que se resuelve en el momento de la generación del proyecto VS y siempre será el valor predeterminado.
fuente
$<CONFIGURATION>
También puede usar el comando find_library:
Con un EXECUTABLE_PATH definido, por ejemplo:
podría mover los archivos .dll que necesita su ejecutable, con
fuente
Esto es útil para uno de ellos.
fuente
Probablemente necesite agregar un destino personalizado y hacer que dependa de uno de sus destinos ejecutables.
Para copiar un archivo usando la función anterior, use:
fuente
Soy un principiante de CMake, pero aún así quería compartir mi experiencia. En mi caso, necesitaba una copia posterior a la instalación para que todos mis binarios estén en. En el caso de binarios de terceros que se pueden importar dentro de CMake, lo siguiente funciona para mí:
Obviamente, IMPORTED_LOCATION_RELEASE puede tener variantes dependiendo de cómo se construyó / instaló la biblioteca compartida. Podría ser IMPORTED_LOCATION_DEBUG.
Quizás haya una mejor manera de obtener ese nombre de propiedad, no lo sé.
fuente
Mover archivos durante la compilación usando
install
Tuve este problema al intentar seguir el tutorial oficial de CMake en el Paso 9 . Esta era la ubicación del archivo que quería mover:
Esta era la ubicación en la que quería que estuviera el archivo:
Dado que esta DLL se generó como una biblioteca compartida, todo lo que hice fue incluir esta línea
CMakeLists.txt
en el subdirectorio que contenía el código fuente de la bibliotecasrc/Mathfunctions/CMakeLists.txt
Gracias a tus respuestas pude pensar en este. Es solo una línea, así que creo que está bien. El
$<CONFIG>
puede tener dos valores de depuración o la versión Dependiendo de cómo se construye el proyecto, ya que la pregunta original requiere.fuente