Qt 实战 之 打包部署
Qt 开发在将应用打包移植时会遇到各种问题:缺少 DLL、运行时崩溃、平台兼容性错误等。
本文主要记录 Windows、Linux 平台下 Qt 应用的打包部署流程,包含工具、自动化脚本和常见问题及解决方法,实现 Qt 应用的绿色分发。
一、打包部署前的准备工作
在开始打包前,准备一下工作最好,这将减少后续 80% 的问题:
- 关键检查
使用 Release 模式编译应用(Debug 模式依赖调试库,体积大且不适合分发)
确认 Qt 版本一致性(避免混合使用不同版本的 Qt 库)
查看是否依赖第三方库(如 OpenSSL、FFmpeg 等,需单独处理) - 一些工具清单(辅助工具可选)
平台 核心工具 辅助工具 Windows windeployqt(Qt 自带) Dependency Walker、7-Zip Linux linuxdeployqt(第三方) ldd、AppImageTool macOS macdeployqt(Qt 自带) otool、install_name_tool、DMG Canvas
二、Windows 平台打包部署(最常用场景)
Windows 平台因缺乏统一的包管理系统,是 Qt 部署最容易出问题的环境。推荐使用 Qt 官方工具 windeployqt
自动化处理。
windeployqt.exe
会到当前的环境变量PATH配置的搜索路径中,查找应用程序所需要的库和资源,拷贝到应用程序目录中。
1. 基础部署流程(以 Qt 5.15 + MinGW 为例)
步骤 1:编译 Release 版本应用
在 Qt Creator 中:
- 切换构建模式为 Release(在左下角可选择)
- 点击构建按钮(锤子图标),生成可执行文件(我的名字是
MyApp.exe
) - 找到输出目录中的生成的可执行文件(通常在
build-xxx-Release
文件夹下)
步骤 2:使用 windeployqt 自动收集依赖
使用 windeployqt 命令会在可执行文件所在目录收集依赖,而不是Qt命令行所在的当前路径。因此我们一般将可执行文件放在一个干净的目录下。
-
新建文件夹并复制可执行文件
我们需要打包,所以先创建一个文件夹(位置和名称无所谓,最好是英文路径),我这里文件夹名为demopkg
,一般命名成与项目相关的名字。
位置为D:\Project\QtProj\demopkg
。
然后将刚才编译release的可执行文件MyApp.exe
拷贝到这个文件夹下,至此,这个文件夹仅有这个可执行文件。 -
打开 Qt 命令行工具(开始菜单 → Qt → Qt 5.15.2 MinGW 8.1.0 64-bit)
注意这里的命令行工具,要选择对应之前构建用到的编译器类型以及版本号,位数。我这里是MinGW 8.1.0 64-bit
。 -
在打开了的 Qt 命令行 中,切换到创建文件夹的目录(如果非C盘,需先切换盘符):
cd D:\Project\QtProj\demopkg
-
执行部署命令(
windeployqt
空格
可执行文件名
):windeployqt MyApp.exe
windeployqt 工具会自动完成以下工作:
- 复制 Qt 核心库(
Qt5Core.dll
、Qt5Gui.dll
等) - 安装平台插件(
platforms\qwindows.dll
等) - 复制图像格式插件(
imageformats\
目录) - 处理 QML 依赖(若使用了 QML 开发)
- 复制 Qt 核心库(
步骤 3:补充非 Qt 依赖
windeployqt
仅处理 Qt 相关依赖,此外,还需手动添加:
- 第三方库:
- 如果应用使用了
libcurl
,需复制对应的libcurl.dll
- 如果应用使用了
openssl
,需复制libcrypto-1_1-x64.dll
,libssl-1_1-x64.dll
到待打包目录。 - 等等等。。。。
- 如果应用使用了
缺少这些库,或许也可以运行,但是可能某些功能会达不到想要的效果。
步骤 4:测试与打包
- 在干净的 Windows 虚拟机中测试运行,或者用其他没装环境的电脑运行(模拟用户电脑测试)
- 如果提示缺乏某某
dll
文件,找到复制过来。 - 如果想部署成安装包,可以用 7-Zip 或 Inno Setup 制作安装包(可选)
2. 高级技巧:定制部署内容
通过命令行参数控制 windeployqt
行为:
# 仅部署 Release 版本依赖,排除调试文件
windeployqt --release MyApp.exe# 不复制翻译文件(减小体积)
windeployqt --no-translations MyApp.exe# 处理 QML 应用(指定 QML 源文件目录)
windeployqt --qmldir C:\path\to\qml\sources MyApp.exe# 排除不需要的插件(如不支持打印功能)
windeployqt --no-plugins=printsupport MyApp.exe
三、Linux 平台打包部署
Linux 发行版众多,推荐使用 AppImage 格式实现 “一次打包,到处运行”。
1. 使用 linuxdeployqt 快速部署
linuxdeployqt
是第三方工具(GitHub 地址),功能类似 windeployqt
:
步骤 1:下载并安装工具
# 下载 64 位版本
wget https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage
chmod +x linuxdeployqt-continuous-x86_64.AppImage
sudo mv linuxdeployqt-continuous-x86_64.AppImage /usr/local/bin/linuxdeployqt
步骤 2:编译并部署应用
# 编译 Release 版本
qmake -config release
make -j4# 部署到临时目录
mkdir -p deploy
cp ./MyApp deploy/
cd deploy# 运行部署工具
linuxdeployqt MyApp -appimage
步骤 3:生成 AppImage 包
工具会自动生成 .AppImage
文件,可直接在 Ubuntu、Fedora、Debian 等主流发行版运行。
2. 手动部署(适合特定发行版)
-
用
ldd
分析依赖:ldd MyApp | grep -v "not found" # 列出所有依赖库
-
复制非系统库到应用目录:
mkdir -p libs for lib in $(ldd MyApp | grep -oP '/.*?\s' | grep -vE '/lib/|/usr/lib/'); docp $lib libs/ done
-
创建启动脚本(
run.sh
):#!/bin/bash export LD_LIBRARY_PATH=$PWD/libs:$LD_LIBRARY_PATH ./MyApp
四、常见问题与解决方案
1. 运行时提示 “缺少 XXX.dll”
一般解决方法:直接找到对应的dll
文件复制过来即可。
补充:程序运行时,调用依赖顺序是先找所在目录的
dll
,再找系统目录的dll
若找不到依赖,或者复制后问题仍然存在,或者功能有缺陷,考虑以下几点:
- 用 Dependency Walker 、dumpbin 等工具检查缺失的库。
有的dll
文件系统目录自带,但是可能版本与开发需要的不一致,所以没出现报错,但是功能有缺陷,可以使用这种工具 检查所依赖的dll
文件路径。 - 确认是否混合使用了不同编译器的库(如 MinGW 与 MSVC 库冲突)
- 对于系统库(如
api-ms-win-*.dll
),通常是因为目标系统 Windows 版本过低。
2. QML 应用启动黑屏
- 部署时添加
--qmldir
参数指定 QML 源目录 - 检查是否遗漏 QML 模块(如
QtQuick.Controls
)
3. Linux 下 “error while loading shared libraries”
- 用
ldd MyApp
确认库路径是否正确 - 确保 AppImage 有执行权限(
chmod +x MyApp.AppImage
)
六、自动化部署脚本示例
为提高效率,可使用脚本自动化部署流程(以 Windows 为例):
# deploy_windows.ps1
$APP_NAME = "MyApp"
$RELEASE_DIR = "C:\path\to\release"
$DEPLOY_DIR = "C:\deploy\$APP_NAME"# 创建部署目录
New-Item -ItemType Directory -Path $DEPLOY_DIR -Force | Out-Null# 复制主程序
Copy-Item "$RELEASE_DIR\$APP_NAME.exe" $DEPLOY_DIR# 运行 windeployqt
& "C:\Qt\5.15.2\mingw81_64\bin\windeployqt.exe" "$DEPLOY_DIR\$APP_NAME.exe" --release --no-translations# 复制 MinGW 运行时
Copy-Item "C:\Qt\5.15.2\mingw81_64\bin\libgcc_s_seh-1.dll" $DEPLOY_DIR
Copy-Item "C:\Qt\5.15.2\mingw81_64\bin\libstdc++-6.dll" $DEPLOY_DIR
Copy-Item "C:\Qt\5.15.2\mingw81_64\bin\libwinpthread-1.dll" $DEPLOY_DIR# 压缩为 zip 包
Compress-Archive -Path "$DEPLOY_DIR\*" -DestinationPath "$DEPLOY_DIR.zip"Write-Host "部署完成:$DEPLOY_DIR.zip"
总结
Qt 应用打包部署的核心是确保所有依赖项正确包含并被程序找到。建议遵循以下几个原则:
- 部署时,始终使用 Release 模式编译
- 优先使用官方或成熟的第三方部署工具
- 在干净的目标环境中测试
- 自动化重复步骤以避免人为错误
持续更新中。。。。