近几天,又有小伙伴问我程序发布的事,这个问题本不复杂,但对一个新手来说,还是有点难度的。为此,笔者简单介绍下Qt在windows下,发布程序的一般方法
本次以Qt6.2.2+MinGW11.2.0+win10为例,其他版本的方法类似,请读者自行尝试。
process explorer
下载地址:Process Explorer - Windows Sysinternals | Microsoft Docs
第三方下载也很多,笔者只是用它来查看使用的动态库
传统的C++桌面程序,发布较简单,动态库也相对较少,笔者以一个自带的示例,演示下如何打包。
开始前,先理解下,控制台程序和非控制台程序。可能有的教程里,控制台程序是指没有图形界面的程序;非控制台程序是有图形界面的程序。这种理解是不合理的。在Qt中,控制台程序是可以有图形界面的。笔者换一种方式解释下,在运行时,若程序会自己弹出控制台,则可称为控制台程序。但本质上,两种程序使用起来,没什么区别。笔者过会演示下
注:
在Debug模式下,也可以发布程序,但这种模式下,程序带有很多调试信息,发布的库也会异常大。
若运行成功,可以到编译目录找到生成的exe文件,笔者的文件在D:/Qt/Examples/Qt-6.2.2/network/build-http-Desktop_Qt_6_2_2_MinGW_64_bit-Release/release
若读者自定义编译输出目录,可以到目标目录找下
笔者的文件名是http.exe
注:
若不指定,exe文件名默认就是项目文件的名字;
若在项目文件添加
TARGET = httpclient
则生成的文件就是 httpclient.exe
小技巧:
若目标目录中有大量的文件,不方便找exe文件时,可以执行编译->清理
此时再去目标目录,会发现,只剩下exe文件了
将生成的exe文件复制到一个单独的目录中,注意,目录不要有中文或空格
windeployqt.exe是Qt自带的打包工具,但这个工具不完美,经常会多库或少库,需要我们手工调整下。
打开cmd,并切换到exe文件的目录,执行如下使用
D:\Qt\6.2.2\mingw_64\bin\windeployqt.exe http.exe
#请读者按照自己的实际目录修改
注:
使用的windeployqt.exe一定要是程序编译时,选择的套件里的
执行完成后,需要的动态库或插件,就会复制到目标目录中
若是运气好,直接运行exe可执行文件,就可以正常运行了
但很遗憾,笔者运行时报错了
必要运行库,运行时不能少,若是缺少会直接弹窗提示
笔者提示如上,只要找到对应的动态库,直接复制到打包目录
若是Qt自带的库,基本都是套件的bin目录中,笔者的是D:\Qt\6.2.2\mingw_64\bin
同样的方法,找到libgcc_s_seh-1.dll、libstdc++-6.dll、libwinpthread-1.dll,复制到打包目录
此时就可以正常运行程序了
非必要的运行库,非必要是相对的。若是不使用时,可以不添加,这可以减少打包后的程序大小;若是需要用动,则必要放入打包程序中。这种动态库以插件居多,即便缺少,一般也不会报错,但在控制台上会打印出信息。根据提示复制相关的动态库就可以了。
本次http示例,可以正常下载http的文件,但可能无法下载https的文件(若可以正常下载,说明你已经安装过openssl了),这时需要将openssl的库放入打包目录
可能有小伙伴发现了,运行程序时,没有控制台,即使直接在cmd中执行,也没任何输出。有时程序没图形界面,或想输出了下信息到控制台上,这时就需要控制台了。
调用方法也很多简单,在项目文件中,添加如下
CONFIG += console
CONFIG -= app_bundle
然后重新编译一次,再次运行程序,控制台就会自己弹出了
笔者建议,确定已打包的程序没问题后,关闭控制台,并删除未使用的库
若读者和笔者一样操作,一般的应用程序发布就没问题的。但有时,发布的程序仍然缺少动态库,特别是插件。遇到这样情况,就需要使用process explorer
注意,一定要在release模式下编译并运行,运行后注意不要关闭程序
注:
(1)一定要注意操作系统是多少位的,否则可能无法检测出使用哪些库
(2)部分杀毒软件可能会阻止process explorer运行,请注意放行
可能会有小伙伴说,你这不是多此一举吗?其实不然,process explorer只能检测使用的动态库,若是插件,需要加载一下才能检测到,所以这一步是很有必须要的
在process explorer中,可以直接看到特定exe程序使用了哪些库,
找到运行的exe, 笔者的显示如下
若未显示动态库,设置如下
一般只要复制非C:\Windows\System32\的动态库就可以了
注:若在64位系统是编译或运行32位程序,对应目录是C:\Windows\SysWOW64,这个目录下放置的是32位程序所需的动态库
复制时,要注意,Qt开发套件插件目录的动态库,放入打包目录时,要去除plugins目录
如D:\Qt\6.2.2\mingw_64\plugins\platforms\qwindows.dll,
放入打包目录是 :打包目录\platforms\qwindows.dll
无需添加plugins目录,直接放入即可
既然知道要需要哪些库,就可以删除多余的库的,但要注意,不要随便删除非动态库文件,如配置文件
Qt Quick程序与Qt Widgets程序发布方法类似,区别是在执行windeployqt.exe时,需要添加--qmldir参数
以particles3d示例来说,笔者执行如下
D:\Qt\6.2.2\mingw_64\bin\windeployqt.exe http.exe --qmldir D:\Qt\6.2.2\mingw_64\qml
#请读者按照自己的实际目录修改
-qmldir参数后面是套件时的qml目录,用于添加qml相关动态库
注:以笔者的经验,Qt Quick程序打包工具,一般会复制很多用不到的库,建议读者打包时,自己删除用不到的库
很多小伙伴不重视这一步,记住,一定要找一台未安装Qt环境的目标机测试下
有小伙伴也注意到了,只要有process explorer,可以做到更完美的发布。但这样要浪费很多时间,具体就看小伙伴们怎么想的了
关于操作系统,笔者根据经验提下,方便小伙伴们处理
若目标系统是xp,需要使用Qt5.7及以下版本
若目标系统是win7,需要使用Qt5.15及以下版本(听说Qt5.15的后续补丁版本已不支持win7,笔者未测试)
Qt6中,官方预编译库只有64位,没有32位
年底了,加上项目较多,笔者未能出更多文档
有小伙伴问我编译的问题,需要等一下了
今天是平安夜,除了餐厅送的小苹果,小伙伴们都不在了。但还是说声吧,Merry Christmas!