Pregunta Cómo copiar archivos DLL en la misma carpeta que el ejecutable usando CMake?


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 se encuentran en una carpeta junto a la fuente.

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


74
2018-05-20 08:24


origen


Respuestas:


Yo usaría add_custom_command para lograr esto junto con cmake -E copy_if_different.... Para obtener información completa, ejecuta

cmake --help-command add_custom_command
cmake -E


Entonces en tu caso, si tienes la siguiente estructura de directorio:

/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 solo quieres todo el contenido de la /libs/ directorio copiado, uso 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, Debug, ej.), 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 al dll en el add_custom_command llamar, así:

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

89
2018-05-20 10:44



Puse 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})

10
2017-12-23 23:21



Una adición a la respuesta aceptada, agregada como una respuesta separada para obtener el formato del código:

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. p.ej.:

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

para la fuente y

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

para el destino Tenga en cuenta el escaparse!

No 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
2017-11-17 22:45



Probablemente necesites agregar un objetivo personalizado y hacer que dependa de uno de tus objetivos ejecutables. Para copiar el archivo usando el uso de la función anterior

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


1
2018-05-20 08:31



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)

1
2018-06-19 10:40



También puede usar 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)

puedes mover los archivos .dll que tu ejecutable necesita, con

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

-1
2018-02-02 18:23