Как скопировать DLL файлы в ту же папку, что и исполняемый файл, используя CMake?
Мы используем CMake для генерации файлов Visual Studio наших источников в нашем SVN. Теперь мой инструмент требует, чтобы некоторые файлы DLL находились в той же папке, что и исполняемый файл. Файлы DLL находятся в папке рядом с источником.
Как я могу изменить свой CMakeLists.txt
таким образом, чтобы сгенерированный проект Visual Studio либо имел уже определенные файлы DLL в папках выпуска/отладки, либо скопировал их при компиляции?
Ответы
Ответ 1
Я использовал бы add_custom_command
для достижения этого вместе с cmake -E copy_if_different...
. Для полной информации
cmake --help-command add_custom_command
cmake -E
Итак, в вашем случае, если у вас есть следующая структура каталогов:
/CMakeLists.txt
/src
/libs/test.dll
и ваша цель CMake, к которой применяется команда, - MyTest
, вы можете добавить следующее к вашему 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
Если вы хотите, чтобы все содержимое каталога /libs/
было скопировано, используйте 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>)
Если вам нужно скопировать разные DLL в зависимости от конфигурации (например, Release, Debug), вы можете иметь их в подкаталогах с соответствующей конфигурацией: /libs/Release
и /libs/Debug
. Затем вам нужно ввести тип конфигурации в путь к DLL в вызове add_custom_command
, например:
add_custom_command(TARGET MyTest POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${PROJECT_SOURCE_DIR}/libs/$<CONFIGURATION>"
$<TARGET_FILE_DIR:MyTest>)
Ответ 2
Я поместил эти строки в мой файл CMakeLists.txt верхнего уровня. Все библиотеки и исполняемые файлы, скомпилированные CMake, будут помещены в верхний уровень каталога сборки, чтобы исполняемые файлы могли найти библиотеки, и все было легко запустить.
set (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
Обратите внимание, что это не решает проблему OP, которая заключается в копировании предварительно скомпилированных двоичных файлов из исходного каталога проекта.
Ответ 3
Добавление к принятому ответу, добавленное как отдельный ответ, поэтому я получаю форматирование кода:
Если вы создаете свои DLL в одном проекте, они обычно будут в каталогах Release, Debug и т.д. Для правильной их копии вам придется использовать переменные среды Visual Studio. например:.
"${PROJECT_BINARY_DIR}/your_library/\$\(Configuration\)/your_library.dll"
для источника и
"${CMAKE_CURRENT_BINARY_DIR}/\$\(Configuration\)/your_library.dll"
для адресата. Обратите внимание на экранирование!
Вы не можете использовать переменную CMake CMAKE_BUILD_TYPE для конфигурации, так как она была разрешена при генерации проекта VS и всегда будет иметь значение по умолчанию.
Ответ 4
Это полезно для одного из них
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)
Ответ 5
Вероятно, вам нужно добавить пользовательскую цель и зависеть от одной из ваших исполняемых целей. Для копирования файла с использованием вышеуказанной функции используйте
COMMAND ${CMAKE_PROGRAM} -E copy_if_different ${CMAKE_BINARY_DIR}/path/to/file.dll ${CMAKE_BINARY_DIR}/where/to/put/file.dll
.
Ответ 6
Вы также можете использовать команду find_library:
find_library(<some_var> NAMES <name_of_lib> PATHS "<path/to/lib>")
С определенным EXECUTABLE_PATH, например:
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
Вы можете переместить .dll файлы, которые нужны вашему исполняемому файлу, с помощью
file(COPY ${<some_var>}
DESTINATION ${EXECUTABLE_OUTPUT_PATH})