Развернуть все зависимости Qt при сборке
Я создал CMakeLists.txt
для создания простого приложения Qt (на самом деле оно имеет только один файл main.cpp
показывая пустое главное окно):
cmake_minimum_required (VERSION 3.7.0)
project(guitest)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
find_package(Qt5Widgets REQUIRED)
include_directories (${CMAKE_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR})
file (GLOB_RECURSE WSIMGUI_SRC *.cpp)
add_executable(${PROJECT_NAME} ${WSIMGUI_SRC})
target_link_libraries(${PROJECT_NAME} Qt5::Widgets)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Widgets> $<TARGET_FILE_DIR:${PROJECT_NAME}>)
Проект строит и add_custom_command
копирует Qt5Widgets.dll
файл в выходной каталог. Но когда я пытаюсь запустить программу, я получаю следующую ошибку:
Не удалось запустить это приложение, так как не удалось найти или загрузить плагин платформы Qt "windows" в "".
Я искал эту проблему, и я заметил, что я должен также скопировать platform
папка из моей установки Qt.
Как я могу сделать это внутри моего CMakeLists.txt
файл?
1 ответ
Qt предоставляет утилиту для развертывания зависимостей в Windows: windeployqt
,
Учитывая, что ваша установка Qt находится в <qt_install_prefix>
, вы должны использовать следующие команды:
set PATH=%PATH%;<qt_install_prefix>/bin
windeployqt --dir /path/to/deployment/dir /path/to/qt/application.exe
Гибкий способ использования windeployqt
с CMake сначала объявить импортированную цель:
find_package(Qt5 ...)
if(Qt5_FOUND AND WIN32 AND TARGET Qt5::qmake AND NOT TARGET Qt5::windeployqt)
get_target_property(_qt5_qmake_location Qt5::qmake IMPORTED_LOCATION)
execute_process(
COMMAND "${_qt5_qmake_location}" -query QT_INSTALL_PREFIX
RESULT_VARIABLE return_code
OUTPUT_VARIABLE qt5_install_prefix
OUTPUT_STRIP_TRAILING_WHITESPACE
)
set(imported_location "${qt5_install_prefix}/bin/windeployqt.exe")
if(EXISTS ${imported_location})
add_executable(Qt5::windeployqt IMPORTED)
set_target_properties(Qt5::windeployqt PROPERTIES
IMPORTED_LOCATION ${imported_location}
)
endif()
endif()
Затем вы можете использовать его следующим образом:
add_executable(foo ...)
if(TARGET Qt5::windeployqt)
# execute windeployqt in a tmp directory after build
add_custom_command(TARGET foo
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E remove_directory "${CMAKE_CURRENT_BINARY_DIR}/windeployqt"
COMMAND set PATH=%PATH%$<SEMICOLON>${qt5_install_prefix}/bin
COMMAND Qt5::windeployqt --dir "${CMAKE_CURRENT_BINARY_DIR}/windeployqt" "$<TARGET_FILE_DIR:foo>/$<TARGET_FILE_NAME:foo>"
)
# copy deployment directory during installation
install(
DIRECTORY
"${CMAKE_CURRENT_BINARY_DIR}/windeployqt/"
DESTINATION ${FOO_INSTALL_RUNTIME_DESTINATION}
)
endif()
Это может (должно?) Быть встроено в функцию cmake.
Обратите внимание, что с помощью GLOB
собирать исходные файлы не рекомендуется в документации CMake:
Мы не рекомендуем использовать GLOB для сбора списка исходных файлов из вашего исходного дерева. Если файл CMakeLists.txt не изменяется при добавлении или удалении источника, то сгенерированная система сборки не может знать, когда попросить CMake сгенерировать заново.
Если вы используете Visual C++, вы также можете установить Visual распространяемый, добавив следующий код в конце вашего CMakeLists.txt
файл:
set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP TRUE)
include(InstallRequiredSystemLibraries)
install(
PROGRAMS ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS}
DESTINATION ${FOO_INSTALL_RUNTIME_DESTINATION}
)
Вы можете взглянуть на один из моих проектов под названием Softbloks, для полной и работающей интеграции windeployqt
а также InstallRequiredSystemLibraries
,