【问题标题】:deploy all Qt dependencies when building构建时部署所有 Qt 依赖项
【发布时间】:2017-05-02 19:01:26
【问题描述】:

我创建了一个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_commandQt5Widgets.dll 文件复制到输出目录。但是当我尝试运行程序时,出现以下错误:

此应用程序无法启动,因为它无法在“”中找到或加载 Qt 平台插件“windows”。

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

如何在我的 CMakeLists.txt 文件中执行此操作?

【问题讨论】:

    标签: windows qt deployment cmake qt5


    【解决方案1】:

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

    鉴于您的 Qt 安装位于 &lt;qt_install_prefix&gt;,您应该使用以下命令:

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

    在 CMake 中使用windeployqt 的一种灵活方法是首先声明一个导入的目标:

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


    注意CMake's doc不鼓励使用GLOB收集源文件:

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


    如果您使用的是 Visual C++,您可能还想通过在 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 的项目,以获得 windeployqtInstallRequiredSystemLibraries 的完整且有效的集成。

    【讨论】:

      猜你喜欢
      • 2019-10-20
      • 2015-04-30
      • 1970-01-01
      • 1970-01-01
      • 2017-04-05
      • 1970-01-01
      • 1970-01-01
      • 2012-04-01
      • 2014-11-27
      相关资源
      最近更新 更多