2012-05-20 13 views
65

Utilizamos 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 se encuentran en una carpeta junto a la fuente.Cómo copiar archivos DLL en la misma carpeta que el ejecutable usando CMake?

¿Cómo puedo cambiar mi CMakeLists.txt de modo que el proyecto de Visual Studio generado ya tenga los archivos DLL particulares en las carpetas de liberación/depuración o los copie en la compilación?

Respuesta

79

Usaría add_custom_command para lograr esto junto con cmake -E copy_if_different.... Para información completa ejecutar

cmake --help-command add_custom_command 
cmake -E 


Así, en su caso, si usted tiene la siguiente estructura de directorios:

/CMakeLists.txt 
/src 
/libs/test.dll 

y su objetivo CMake al que se aplica el comando es MyTest, entonces podría agregar lo siguiente a su CMakeLists.txt:

add_custom_command(TARGET MyTest POST_BUILD  # Adds a post-build event to MyTest 
    COMMAND ${CMAKE_COMMAND} -E copy_if_different # which executes "cmake - E copy_if_different..." 
     "${PROJECT_SOURCE_DIR}/libs/test.dll"  # <--this is in-file 
     $<TARGET_FILE_DIR:MyTest>)     # <--this is out-file path 


Si lo que desea todo el contenido del directorio /libs/ copiados, utilice cmake -E copy_directory:

add_custom_command(TARGET MyTest POST_BUILD 
    COMMAND ${CMAKE_COMMAND} -E copy_directory 
     "${PROJECT_SOURCE_DIR}/libs" 
     $<TARGET_FILE_DIR:MyTest>) 


Si necesita copiar diferentes dlls dependiendo de la configuración (Release, depuración, ej.) entonces podría tenerlos en subdirectorios nombrados con la configuración correspondiente: /libs/Release y /libs/Debug. A continuación, deberá inyectar el tipo de configuración en la ruta de acceso al archivo DLL en la llamada add_custom_command, así:

add_custom_command(TARGET MyTest POST_BUILD 
    COMMAND ${CMAKE_COMMAND} -E copy_directory 
     "${PROJECT_SOURCE_DIR}/libs/$<CONFIGURATION>" 
     $<TARGET_FILE_DIR:MyTest>) 
+1

Nota rápida de 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 cual el ejecutable principal se vincula opcionalmente, y esa biblioteca requiere una copia DLL si se agrega. Entonces, en el archivo CMakeLists.txt de esa biblioteca usé '$ {CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$ ' para el destino de destino. De lo contrario, lo copiaría en la ruta de compilación de la biblioteca, que fue inútil. – AberrantWolf

1

Probablemente necesite add custom target y hacerlo depender de uno de sus objetivos ejecutables. Para copiar el archivo usando la función anterior use

COMMAND ${CMAKE_PROGRAM} -E copy_if_different ${CMAKE_BINARY_DIR}/path/to/file.dll ${CMAKE_BINARY_DIR}/where/to/put/file.dll.

5

En una adición a la respuesta aceptada, añade como una respuesta por separado por lo que obtener código de formato:

Si está creando sus dlls en el mismo proyecto, generalmente estarán en los directorios Release, Debug, etc. Tendrá que usar las variables de entorno de Visual Studio para copiarlas correctamente. ej .:

"${PROJECT_BINARY_DIR}/your_library/\$\(Configuration\)/your_library.dll" 

para el origen y

"${CMAKE_CURRENT_BINARY_DIR}/\$\(Configuration\)/your_library.dll" 

para el destino. Tenga en cuenta el escaparse!

No se puede usar la variable CMake CMAKE_BUILD_TYPE para la configuración, ya que se resuelve en el tiempo de generación del proyecto VS y siempre será el valor predeterminado.

+5

La última parte de la respuesta aceptada aborda esto en la forma más limpia de CMake usando '$ ' –

1

Esto es útil para uno de ellos

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) 
9

pongo estas líneas en mi archivo CMakeLists.txt de nivel superior. Todas las bibliotecas y ejecutables 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}) 
0

También puede utilizar el comando find_library:

find_library(<some_var> NAMES <name_of_lib> PATHS "<path/to/lib>") 

Con un EXECUTABLE_PATH definido, por ejemplo:

set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) 

que podía mover los archivos .dll que su necesidad ejecutable, con

file(COPY ${<some_var>} 
    DESTINATION ${EXECUTABLE_OUTPUT_PATH}) 
Cuestiones relacionadas