我创建了一个 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
文件复制到输出目录。但是当我尝试运行该程序时,出现以下错误:
This application failed to start because it could not find or load the Qt platform plugin "windows" in "".
我一直在寻找这个问题,我注意到我还必须从我的 Qt 安装中复制 platform
文件夹。
如何在我的 CMakeLists.txt
文件中执行此操作?
最佳答案
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's doc 不鼓励收集源文件:
We do not recommend using GLOB to collect a list of source files from your source tree. If no CMakeLists.txt file changes when a source is added or removed then the generated build system cannot know when to ask CMake to regenerate.
如果您使用的是 Visual C++,您可能还想通过在 CMakeLists.txt
的末尾添加以下代码来安装 visual redistributable文件:
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
.
关于windows - 构建时部署所有 Qt 依赖项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41193584/