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

查看:30
本文介绍了构建时部署所有 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_commandQt5Widgets.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 安装中复制 platform 文件夹.

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 文件中执行此操作?

How can I do this inside my CMakeLists.txt file?

推荐答案

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 的一种灵活方法是首先声明一个导入的目标:

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.

请注意,不鼓励在 CMake 的文档:

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

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

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 文件末尾添加以下代码来安装可视可再发行组件:


If you're using Visual C++, you may also want to install visual redistributable by adding the following code at the end of your 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,用于 windeployqtInstallRequiredSystemLibraries 的完整且有效的集成.

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天全站免登陆