关于qt打包

最近做了一个在库里随机抽签的程序,对方要单机版,于是就用qt给他写了一个。开发完程序打包的时候遇到了问题,打完包的程序在本机能正常运行,拷贝到其他机器上就不能工作了,频繁报错。捣鼓了有两天终于捣鼓通了,现在把过程记录下来。好记性不如烂笔头,以备今后再遇到类似问题好参考。

一开始问度娘qt打包,看到可以用qt自带的windeployqt工具自动打包,自己也没多想就在qt安装目录搜索windeployqt,搜索到了程序目录直接加到了windows的环境变量path里,然后建了个文件夹,将编译好的exe文件拷贝到里面,运行 windeployqt XXX.exe (xxx.exe为你拷贝到文件夹的exe文件) ,于是就在新建的文件夹下看到了打包的依赖文件拷贝,还有一些插件的扩展文件夹也都一并拷贝到该文件夹下。点击exe文件却发现运行不了了,报错类似于

无法定位程序输入点 _Z11qt_assert_xPKcS0_S0_i 于动态链接库

这种内容。后来将打包目录下拷贝过来的所有dll文件,重新从qt安装目录查找并拷贝了一遍后 ,程序可以运行了,我就认为问题解决了,于是找个U盘将,打包后的文件夹一起拷贝到U盘上,拿到其他计算机上测试运行情况,发现只有本机能运行,其他任何计算机上都报错,并且报错的缺少的dll文件还不一样,win7系统、win10系统、win11系统中报错缺少的dll文件不太一样。起初我认为是打包时系统缺少了一些第三方库,因为我程序里用了sm3、sm4加密用到了openssl第三方库,可能这些依赖库windeployqt没给打进去,于是又从原机器上将缺少的dll文件一个个拷贝到测试机器上,最后拷贝完不报缺少dll文件了,开始报错这个

应用程序无法正常启动(0xc000007b)

在网上查了半天,告诉我缺“Microsoft Visual C++ Redistributable”,于是我又在测试机器上安装了各个版本的“Microsoft Visual C++ Redistributable”,安装完还是没用,依旧报错0xc000007b。于是我想是不是我应该安装msys2,配置相关环境变量呢?因为我的yaml操作组件和加解密组件都是通过vcpkg安装关联到cmake里的,于是又安装msys2,捣鼓了一通,还是徒劳。

不过在一篇博客中偶然看到了qt打包发布最好选用release版本,于是自己照着操作了一下,却在编译目录下我注意到了CMakeCache.txt这个文件。这是编译过程的缓存文件,它上面记录了编译过程用到的程序以及依赖包的目录,在其中我看到了windeployqt的路径,突然醒悟:我之前搜索的windeployqt工具和CMakeCache.txt这个文件中记录的windeployqt的路径不是一个路径!原来我之前还在D:\msys64\mingw64中也安装了qt,我的d盘下不只一个windeployqt工具,可能本身qt针对32位和64位打包也有多个版本的windeployqt工具,我意识到之前在path环境变量里设置的windeployqt工具路径不对。认识到问题原因后,我将环境变量改为了CMakeCache.txt这个文件中记录的windeployqt工具的路径,重新打包,发现之前“无法定位程序输入点 _Z11qt_assert_xPKcS0_S0_i 于动态链接库”这个错误没有了,并且拷贝到打包目录的dll文件和之前也有了一些不同,现在再在本机上运行exe文件可直接打开,不用重新拷贝dll文件了。我以为问题解决,可是现实继续打脸。在其他机器上运行依旧报错0xc000007b。

我又开始在网上找原因,说可能是依赖包没有拷贝全,可现在不报缺少dll的错了,怎么看缺什么组件呢?找了半天,AI推荐使用Dependency Walker或 dumpbin工具分析程序依赖。这两个程序都测试后发现Microsoft Visual Studio下的dumpbin工具比较好用,前者是有操作界面的,后者是命令行方式,具体命令如下

D:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.32.31326\bin\Hostx64\x86>dumpbin.exe /DEPENDENTS D:\workspace\Qt\build-zfzjcq-Desktop_Qt_6_3_1_MinGW_64_bit-Release\bin\zfzjcq.exe

//结果
Dump of file D:\workspace\Qt\build-zfzjcq-Desktop_Qt_6_3_1_MinGW_64_bit-Release\bin\zfzjcq.exe

File Type: EXECUTABLE IMAGE

  Image has the following dependencies:

    libcrypto-1_1-x64.dll
    yaml-cpp.dll
    Qt6Core.dll
    Qt6Gui.dll
    Qt6Widgets.dll
    libgcc_s_seh-1.dll
    KERNEL32.dll
    msvcrt.dll
    SHELL32.dll
    libstdc++-6.dll

  Summary

        1000 .CRT
        1000 .bss
        1000 .data
        1000 .debug_abbrev
        1000 .debug_aranges
        1000 .debug_frame
        2000 .debug_info
        1000 .debug_line
        1000 .debug_loclists
        1000 .debug_rnglists
        1000 .debug_str
        5000 .idata
        1000 .pdata
        3000 .rdata
        1000 .reloc
        7000 .rsrc
       26000 .text
        1000 .tls
        3000 .xdata

对比打包目录查看缺少的dll文件,在原机器上查找相关dll文件拷贝到打包目录。查找过程中,会发现同名的dll文件会搜索出来多个,参考CMakeCache.txt这个文件里相关的dll目录,选择拷贝,如果CMakeCache.txt这个文件里没有记录的,比如KERNEL32.dll、msvcrt.dll、SHELL32.dll 这是在c盘下搜索到的系统核心动态链接库文件,也是能搜索重名的文件有多个,我选择了时间最近,并且文件大小最大的,进行拷贝。将分析工具列出的所有依赖库都拷贝到打包目录后,再拿到多个测试计算机上测试,运行成功!!!

总结,qt打包使用windeployqt工具以及拷贝dll文件时,一定要参考编译目录下的CMakeCache.txt这个文件的记录内容;查找程序依赖库时最好使用Microsoft Visual Studio下的dumpbin工具;对于系统核心依赖库文件,选择文件大小最大,更新或安装时间最新的文件拷贝。按照这些步骤操作,再用qt开发打包就应该问题不大了。

  • 17
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值