关于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开发打包就应该问题不大了。

<think> 首先,用户在询问Qt打包命令。 用户提供了几个引用,我应该参考它们来回答。 引用[1]提到Qt自带的打包命令和工具,手动打包需要包含Qt核心库、插件、编译器运行时和应用程序资源文件。 引用[2]详细描述了如何打包为文件夹和可执行文件,使用了windeployqt命令。 引用[3]也提到了使用windeployqt命令来复制必要的组件。 关键点是:Qt打包命令主要是基于windeployqt,这是一个Qt自带的工具,用于部署Qt应用程序。 用户上一次的问题和我的回答:回顾上下文。 在系统指令中,用户说“参考站内引用”,但引用是给定的文本,不是实际的引用来源。 我应该基于这些引用内容来回答。 用户的问题是:“我想查找Qt打包命令 请问Qt打包命令” 所以,我需要提供一个清晰的回答,包括Qt打包命令的步骤。 从引用中提取关键信息: - 使用windeployqt命令来打包Qt应用程序。 - 步骤包括: 1. 将调试模式改为Release模式。 2. 构建应用程序以生成.exe文件。 3. 使用windeployqt命令来复制所有依赖项到文件夹中。 4. 可选地,使用像Enigma Virtual Box这样的工具打包为单个.exe文件。 根据引用[2]和[3],windeployqt是核心命令。 我的回答结构: - 介绍Qt打包命令:windeployqt。 - 解释基本用法:windeployqt [filename.exe] - 必要时提供更详细的步骤。 - 引用相关内容:引用[2]描述了详细过程。 - 生成相关问题,如系统指令所示。 系统指令要求: - 所有行内数学表达式必须使用$...$格式。(但在Qt打包上下文中,可能不涉及数学,所以可能不使用。) - 独立公式必须使用$$...$$单独成段。(同样,可能不适用。) - LaTeX语法正确。(这里不涉及LaTeX。) - 使用中文回答。 - 生成相关问题。 - 在回答中引用的段落末尾自然地添加引用标识。 所以,在回答中,我需要添加引用标识,如[^1], [^2]等。 引用的来源: - 引用[1]: 关于Qt打包的内容。 - 引用[2]: 详细打包步骤。 - 引用[3]: 使用windeployqt。 我应该引用这些在回答中点。 最后,生成相关问题。 完整回答结构: 1. 直接回答用户问题:Qt打包命令主要是windeployqt。 2. 解释基本使用方法。 3. 提供步骤概述。 4. 添加引用。 5. 生成相关问题。 </think> ### Qt打包命令详解 Qt打包命令主要是基于其自带的部署工具 `windeployqt`,该工具用于自动收集和复制Qt应用程序运行所需的所有依赖项(如DLL文件、插件和资源文件)。以下是核心命令和详细使用方法,基于您提供的引用内容,我将逐步解释。 #### 核心打包命令:`windeployqt` - **基本语法**: ``` windeployqt [应用程序文件名.exe] ``` 此命令会自动扫描您的.exe文件,识别所需的Qt库(如Qt5Core.dll或Qt6Core.dll)、插件(如`platforms/`和`imageformats/`目录)、编译器运行时文件(如msvcp*.dll和vcruntime*.dll),并将它们复制到.exe文件所在的目录中。这使得整个文件夹成为一个可运行的应用程序包[^2][^3]。 - **关键步骤示例**: 1. **构建Release版本**:首先,在Qt Creator中将构建模式设置为Release,并生成.exe文件(例如`myapp.exe`)。 2. **创建独立文件夹**:将生成的.exe文件复制到一个新文件夹(如`C:\MyApp`)。 3. **运行打包命令**:打开Qt安装目录中的命令行工具(如MinGW提供的命令提示符),导航到该文件夹并执行: ```bash cd C:\MyApp windeployqt myapp.exe ``` 执行完成后,文件夹内会自动添加所有必要的依赖文件,形成一个可运行的应用程序包[^2][^3]。 4. **验证打包**:运行文件夹内的.exe文件即可启动应用程序。 - **常见参数**: - `--compiler-runtime`:确保包含Visual Studio运行时文件(适用于Windows)。 - `--qmldir`:如果应用程序使用QML,指定QML文件目录以确保相关资源被复制。 - `--no-translations`:跳过翻译文件以减少包大小。 示例:`windeployqt --compiler-runtime myapp.exe`。 #### 注意事项 - **兼容性问题**:`windeployqt` 需要与您的Qt版本匹配(如Qt5或Qt6)。如果不指定路径,它通常在Qt安装目录的`bin`文件夹中(例如`C:\Qt\6.5.0\mingw_64\bin\windeployqt.exe`)。 - **手动补充依赖**:如果命令后仍有缺失的DLL,您可以从Qt安装目录搜索并手动复制到目标文件夹[^3]。 - **打包为单文件.exe**:引用[^2]提到,可以使用第三方工具如Enigma Virtual Box将文件夹封装为单个可执行文件(例如`myapp_boxed.exe`),但这不属于Qt原生命令范畴。 通过以上方法,`windeployqt` 简化了Qt应用程序打包过程,避免了手动收集依赖项的繁琐[^1][^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值