跳到主要内容

应用部署与发布

开发完成的 Qt 应用程序需要经过部署才能交付给最终用户。部署过程包括打包应用程序、收集依赖项、创建安装程序等步骤。本章将详细介绍 Qt 应用在各平台上的部署方法。

部署概述

静态链接 vs 动态链接

部署 Qt 应用有两种主要方式:

方式优点缺点
静态链接单一可执行文件,部署简单;无外部依赖文件体积大;无法使用插件;需要重新编译才能更新 Qt 版本
动态链接文件体积小;支持插件;可独立更新 Qt 库需要部署多个文件;依赖管理复杂

推荐:对于大多数应用,使用动态链接方式部署。Qt 官方提供的预编译版本也是动态库形式。

部署的核心要素

无论采用哪种方式,部署 Qt 应用需要考虑以下要素:

  1. 应用程序可执行文件:编译生成的 .exe(Windows)或可执行文件(Linux/macOS)
  2. Qt 动态库:应用程序使用的 Qt 模块对应的动态库
  3. Qt 插件:平台插件、图像格式插件、数据库驱动等
  4. 编译器运行时:Visual C++ 运行时或 MinGW 运行时
  5. QML 模块:如果使用 Qt Quick,需要部署 QML 模块
  6. 翻译文件:应用程序和 Qt 模块的翻译文件
  7. 第三方库:应用程序依赖的其他库

Windows 平台部署

使用 windeployqt 工具

windeployqt 是 Qt 提供的自动部署工具,能够自动分析应用程序依赖并复制所需的 Qt 文件。

基本用法

# 进入 Qt 构建环境(假设 Qt 安装在 C:\Qt\6.8.0\msvc2022_64)
C:\Qt\6.8.0\msvc2022_64\bin\qtenv2.bat

# 进入应用程序目录
cd C:\path\to\your\app\release

# 运行 windeployqt
windeployqt yourapp.exe

工具会自动完成以下工作:

  • 分析可执行文件的 Qt 依赖
  • 复制所需的 Qt 动态库(如 Qt6Core.dllQt6Gui.dllQt6Widgets.dll
  • 创建 platforms 目录并复制平台插件 qwindows.dll
  • 复制其他必需的插件和翻译文件
  • 复制 Visual C++ 运行时库

部署 Qt Quick 应用

对于使用 QML 的应用,需要指定 QML 文件目录:

windeployqt --qmldir C:\path\to\qml\files yourapp.exe

这会额外扫描 QML 文件的导入依赖,并复制相应的 QML 模块。

常用命令选项

# 指定部署目录
windeployqt --dir C:\deploy\folder yourapp.exe

# 使用指定的 qmake
windeployqt --qmake C:\Qt\6.8.0\msvc2022_64\bin\qmake.exe yourapp.exe

# 部署调试版本
windeployqt --debug yourapp.exe

# 部署特定翻译语言
windeployqt --translations de,fr yourapp.exe

# 模拟运行(不实际复制文件)
windeployqt --dry-run yourapp.exe

# 详细输出
windeployqt --verbose 2 yourapp.exe

静态链接部署

如果使用静态链接方式,需要在编译 Qt 时启用静态选项:

# 配置 Qt 静态编译
cd C:\Qt\Source\6.8.0
configure -static -release -prefix "C:\Qt\6.8.0\static"

# 编译
cmake --build . --parallel
cmake --install .

然后使用静态版本的 Qt 编译应用程序:

# 使用静态 Qt 编译应用
C:\Qt\6.8.0\static\bin\qmake.exe yourproject.pro
nmake release

静态编译的可执行文件体积较大(通常 20-50 MB),但部署时只需复制这一个文件。

手动部署

如果需要更精细的控制,可以手动部署:

确定依赖项

使用 Dependency Walker 或 dumpbin 工具查看依赖:

# 使用 dumpbin 查看 DLL 依赖
dumpbin /dependents yourapp.exe

复制 Qt 库

典型的 Qt Widgets 应用需要以下文件:

yourapp.exe           # 应用程序
Qt6Core.dll # 核心库
Qt6Gui.dll # GUI 库
Qt6Widgets.dll # Widgets 库
platforms/
qwindows.dll # Windows 平台插件
styles/
qwindowsvistastyle.dll # Vista 样式插件

复制编译器运行时

使用 Visual Studio 编译的应用需要部署 VC++ 运行时:

  • 推荐方式:在安装程序中包含 vc_redist.x64.exe(可从微软官网下载)
  • 备选方式:复制运行时 DLL(vcruntime140.dllmsvcp140.dll 等)

创建安装程序

使用 Qt Installer Framework

Qt Installer Framework 是 Qt 官方提供的安装程序制作工具,支持跨平台安装程序。

安装 Qt Installer Framework

在 Qt Maintenance Tool 中选择 "Qt Installer Framework" 组件安装。

基本结构

installer/
├── config/
│ └── config.xml # 安装程序配置
├── packages/
│ └── com.yourcompany.yourapp/
│ ├── meta/
│ │ ├── package.xml # 包信息
│ │ └── installscript.qs # 安装脚本(可选)
│ └── data/
│ └── yourapp.7z # 应用程序数据
└── config.xml # 根配置文件

config.xml 配置示例

<?xml version="1.0" encoding="UTF-8"?>
<Installer>
<Name>我的应用程序</Name>
<Version>1.0.0</Version>
<Title>我的应用程序安装向导</Title>
<Publisher>您的公司</Publisher>
<StartMenuDir>我的应用程序</StartMenuDir>
<TargetDir>@ApplicationsDir@/我的应用程序</TargetDir>
<AdminTargetDir>@RootDir@/Program Files/我的应用程序</AdminTargetDir>
<RunProgram>@TargetDir@/yourapp.exe</RunProgram>
<RunProgramArguments></RunProgramArguments>
<RunProgramDescription>启动应用程序</RunProgramDescription>
</Installer>

package.xml 配置示例

<?xml version="1.0" encoding="UTF-8"?>
<Package>
<DisplayName>应用程序核心</DisplayName>
<Description>安装我的应用程序的核心组件。</Description>
<Version>1.0.0</Version>
<ReleaseDate>2024-01-01</ReleaseDate>
<Default>true</Default>
<Script>installscript.qs</Script>
</Package>

打包数据

# 进入包目录
cd packages/com.yourcompany.yourapp/data

# 创建 7z 压缩包
7z a yourapp.7z C:\path\to\deployed\app\*

创建安装程序

# 使用 binarycreator 创建离线安装程序
C:\Qt\Tools\QtInstallerFramework\4.6\bin\binarycreator.exe -c config/config.xml -p packages installer.exe

使用 NSIS 或 Inno Setup

除了 Qt Installer Framework,还可以使用第三方工具:

Inno Setup 示例脚本

[Setup]
AppName=我的应用程序
AppVersion=1.0.0
DefaultDirName={pf}\我的应用程序
DefaultGroupName=我的应用程序
OutputBaseFilename=setup
Compression=lzma
SolidCompression=yes

[Files]
Source: "release\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs

[Icons]
Name: "{group}\我的应用程序"; Filename: "{app}\yourapp.exe"
Name: "{commondesktop}\我的应用程序"; Filename: "{app}\yourapp.exe"

[Run]
Filename: "{app}\yourapp.exe"; Description: "启动应用程序"; Flags: nowait postinstall skipifsilent

Linux 平台部署

使用 CMake 部署 API

Qt 6.5 及以上版本提供了 CMake 部署 API,可以简化 Linux 上的部署过程。

CMakeLists.txt 配置

cmake_minimum_required(VERSION 3.16)
project(MyApp VERSION 1.0.0 LANGUAGES CXX)

find_package(Qt6 REQUIRED COMPONENTS Core Widgets)

qt_add_executable(MyApp main.cpp)

target_link_libraries(MyApp PRIVATE Qt6::Core Qt6::Widgets)

# 设置部署目标
qt_generate_deploy_app_script(
TARGET MyApp
OUTPUT_SCRIPT deploy_script
NO_UNSUPPORTED_PLATFORM_ERROR
)

install(TARGETS MyApp
BUNDLE DESTINATION .
LIBRARY DESTINATION lib
)

# 执行部署脚本
install(SCRIPT ${deploy_script})

创建 DEB 包

对于 Debian/Ubuntu 系统:

# 添加 DEB 包支持
set(CPACK_GENERATOR "DEB")
set(CPACK_PACKAGE_NAME "myapp")
set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "我的应用程序")
set(CPACK_PACKAGE_VENDOR "Your Company")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "[email protected]")
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libqt6core6, libqt6widgets6")

include(CPack)

构建和打包:

cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
cd build
cpack -G DEB

创建 AppImage

AppImage 是一种跨发行版的打包格式,用户无需安装即可运行:

# 使用 linuxdeployqt 创建 AppImage
wget https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage
chmod +x linuxdeployqt-continuous-x86_64.AppImage

# 部署
./linuxdeployqt-continuous-x86_64.AppImage yourapp -appimage

手动部署

手动部署 Linux 应用需要:

  1. 编译为 Release 模式
  2. 确定依赖的共享库:
ldd yourapp
  1. 创建部署目录结构:
yourapp/
├── bin/
│ └── yourapp
├── lib/
│ └── (Qt 和第三方库)
├── plugins/
│ ├── platforms/
│ │ └── libqxcb.so
│ └── imageformats/
│ └── *.so
└── qml/
└── (QML 模块)
  1. 使用包装脚本启动:
#!/bin/bash
APP_DIR=$(dirname "$(readlink -f "$0")")
export LD_LIBRARY_PATH="$APP_DIR/lib:$LD_LIBRARY_PATH"
export QT_PLUGIN_PATH="$APP_DIR/plugins"
export QML2_IMPORT_PATH="$APP_DIR/qml"
"$APP_DIR/bin/yourapp" "$@"

macOS 平台部署

创建应用程序包

macOS 应用通常打包为 .app 包格式:

# 使用 macdeployqt
macdeployqt yourapp.app -dmg

这会创建一个带有所有依赖的 .app 包和一个 DMG 安装镜像。

应用程序签名

发布到 Mac App Store 或给其他用户使用时需要签名:

# 签名应用程序
codesign --deep --force --verify --verbose --sign "Developer ID Application: Your Name" yourapp.app

# 公证(提交到 Apple 审核)
xcrun notarytool submit yourapp.dmg --apple-id [email protected] --team-id YOURTEAM --password app-specific-password --wait

# 钉住公证结果
xcrun stapler staple yourapp.dmg

Qt 配置文件(qt.conf)

qt.conf 文件用于配置 Qt 库的路径设置,在部署时非常有用:

[Paths]
# 指定插件目录(相对于可执行文件)
Plugins = plugins
# 指定 QML 导入路径
Imports = qml
# 指定翻译文件路径
Translations = translations
# 指定数据路径
Data = .
# 指定文档路径
Documentation = doc

qt.conf 放在可执行文件同级目录,Qt 会自动读取配置。

部署最佳实践

版本管理

  1. 使用版本号:在应用程序属性和安装程序中包含版本信息
  2. 更新机制:实现自动更新或提供更新通知
  3. 向后兼容:确保新版本能处理旧版本的数据

安全考虑

  1. 代码签名:对所有可执行文件进行数字签名
  2. HTTPS 更新:通过 HTTPS 分发更新
  3. 权限最小化:只请求必要的系统权限

体积优化

  1. 排除不需要的模块:只部署实际使用的 Qt 模块
  2. 排除不需要的插件:只部署必需的平台和图像格式插件
  3. 压缩资源:使用 UPX 等工具压缩可执行文件(注意杀毒软件可能误报)
  4. 分离翻译文件:只包含目标市场的语言

测试部署

部署完成后,务必在以下环境中测试:

  1. 纯净系统:没有安装 Qt 和开发工具的系统
  2. 不同版本系统:Windows 10/11、不同 Linux 发行版
  3. 不同架构:x86_64、ARM(如适用)
  4. 用户权限:普通用户和管理员账户

部署检查清单

Windows

  • 使用 Release 模式编译
  • 运行 windeployqt 收集依赖
  • 包含 Visual C++ 运行时或安装程序
  • 测试在纯净系统上运行
  • 创建安装程序(.exe 或 .msi)
  • 添加应用程序图标和版本信息

Linux

  • 使用 Release 模式编译
  • 确定系统依赖和打包格式
  • 创建 DEB/RPM/AppImage 包
  • 包含必要的启动脚本
  • 测试在不同发行版上运行

macOS

  • 使用 Release 模式编译
  • 运行 macdeployqt 创建 .app 包
  • 签名应用程序
  • 创建 DMG 安装镜像
  • 提交公证(如分发到 App Store)

参考资源