应用部署与发布
开发完成的 Qt 应用程序需要经过部署才能交付给最终用户。部署过程包括打包应用程序、收集依赖项、创建安装程序等步骤。本章将详细介绍 Qt 应用在各平台上的部署方法。
部署概述
静态链接 vs 动态链接
部署 Qt 应用有两种主要方式:
| 方式 | 优点 | 缺点 |
|---|---|---|
| 静态链接 | 单一可执行文件,部署简单;无外部依赖 | 文件体积大;无法使用插件;需要重新编译才能更新 Qt 版本 |
| 动态链接 | 文件体积小;支持插件;可独立更新 Qt 库 | 需要部署多个文件;依赖管理复杂 |
推荐:对于大多数应用,使用动态链接方式部署。Qt 官方提供的预编译版本也是动态库形式。
部署的核心要素
无论采用哪种方式,部署 Qt 应用需要考虑以下要素:
- 应用程序可执行文件:编译生成的
.exe(Windows)或可执行文件(Linux/macOS) - Qt 动态库:应用程序使用的 Qt 模块对应的动态库
- Qt 插件:平台插件、图像格式插件、数据库驱动等
- 编译器运行时:Visual C++ 运行时或 MinGW 运行时
- QML 模块:如果使用 Qt Quick,需要部署 QML 模块
- 翻译文件:应用程序和 Qt 模块的翻译文件
- 第三方库:应用程序依赖的其他库
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.dll、Qt6Gui.dll、Qt6Widgets.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.dll、msvcp140.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 应用需要:
- 编译为 Release 模式
- 确定依赖的共享库:
ldd yourapp
- 创建部署目录结构:
yourapp/
├── bin/
│ └── yourapp
├── lib/
│ └── (Qt 和第三方库)
├── plugins/
│ ├── platforms/
│ │ └── libqxcb.so
│ └── imageformats/
│ └── *.so
└── qml/
└── (QML 模块)
- 使用包装脚本启动:
#!/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 会自动读取配置。
部署最佳实践
版本管理
- 使用版本号:在应用程序属性和安装程序中包含版本信息
- 更新机制:实现自动更新或提供更新通知
- 向后兼容:确保新版本能处理旧版本的数据
安全考虑
- 代码签名:对所有可执行文件进行数字签名
- HTTPS 更新:通过 HTTPS 分发更新
- 权限最小化:只请求必要的系统权限
体积优化
- 排除不需要的模块:只部署实际使用的 Qt 模块
- 排除不需要的插件:只部署必需的平台和图像格式插件
- 压缩资源:使用 UPX 等工具压缩可执行文件(注意杀毒软件可能误报)
- 分离翻译文件:只包含目标市场的语言
测试部署
部署完成后,务必在以下环境中测试:
- 纯净系统:没有安装 Qt 和开发工具的系统
- 不同版本系统:Windows 10/11、不同 Linux 发行版
- 不同架构:x86_64、ARM(如适用)
- 用户权限:普通用户和管理员账户
部署检查清单
Windows
- 使用 Release 模式编译
- 运行
windeployqt收集依赖 - 包含 Visual C++ 运行时或安装程序
- 测试在纯净系统上运行
- 创建安装程序(.exe 或 .msi)
- 添加应用程序图标和版本信息
Linux
- 使用 Release 模式编译
- 确定系统依赖和打包格式
- 创建 DEB/RPM/AppImage 包
- 包含必要的启动脚本
- 测试在不同发行版上运行
macOS
- 使用 Release 模式编译
- 运行
macdeployqt创建 .app 包 - 签名应用程序
- 创建 DMG 安装镜像
- 提交公证(如分发到 App Store)