在构建时部署所有Qt依赖关系 [英] deploy all Qt dependencies when building

查看:184
本文介绍了在构建时部署所有Qt依赖关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个 CMakeLists.txt 来创建一个简单的Qt应用程序(实际上它只有一个文件 main.cpp 显示一个空的主窗口):

I've created a CMakeLists.txt for creating a simple Qt application (actually it has only one file main.cpp showing an empty main window):

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 文件输出目录。但是当我尝试运行该程序时,我会收到以下错误:

Project builds and the add_custom_command copies the Qt5Widgets.dll file to output directory. But when I try to run the program I get the following error:


此应用程序启动失败,因为找不到或加载Qt平台插件Windows在。

This application failed to start because it could not find or load the Qt platform plugin "windows" in "".

我一直在寻找这个问题,我注意到我也必须复制我的Qt安装中的平台文件夹。

I've been looking for this problem and I've noticed that I must also copy the platform folder from my Qt installation.

我如何在我的 CMakeLists .txt 文件?

推荐答案

Qt提供了在Windows上部署依赖关系的实用程序: windeployqt

Qt provides a utility to deploy dependencies on Windows: windeployqt.

鉴于您的Qt安装位于< qt_install_prefix> ,您应该使用以下命令:

Given your Qt installation is located in <qt_install_prefix>, you should use the following commands:

set PATH=%PATH%;<qt_install_prefix>/bin
windeployqt --dir /path/to/deployment/dir /path/to/qt/application.exe

使用CMake的 windeployqt 的灵活方法是首先声明一个impor ted target:

A flexible way to use windeployqt with CMake is to first declare an imported target:

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

然后可以将其用作如下:

You can then use it as follows:

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函数中。

This can (should?) be embedded in a cmake function.

请参阅 SO文档

请注意,在 GLOB 来收集源文件help / latest / command / file.htmlrel =noreferrer> CMake的文档

Note that using GLOB to collect source files is discouraged in CMake's doc:


我们不建议使用GLOB从源代码树中收集源文件列表。如果在添加或删除源代码时没有CMakeLists.txt文件更改,则生成的构建系统将无法知道何时要求重新生成。

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 file:

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

You can take a look to one of my project, named Softbloks, for a complete and working integration of windeployqt and InstallRequiredSystemLibraries.

这篇关于在构建时部署所有Qt依赖关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆