zoukankan      html  css  js  c++  java
  • Qt 程序发布指南

    Qt 程序发布指南

    威武的涛哥 的博客文章地址 https://jaredtao.github.io/2019/09/02/Qt%E5%AE%9E%E7%94%A8%E6%8A%80%E8%83%BD6-%E7%A8%8B%E5%BA%8F%E5%8F%91%E5%B8%83%E6%8C%87%E5%8D%97/

    知乎文章地址 https://zhuanlan.zhihu.com/p/80919147

    简介

    本文是《Qt实用技能》系列文章的第六篇,涛哥在这里讨论发布Qt应用程序的知识点。

    (第五篇《Qt实用技能5-掌握信号槽使用细节》还在整理中,过几天会发)

    背景

    有很多人向涛哥询问,Qt程序发布的相关问题,网络上虽然可以搜到一大堆教程,但是可靠的比较少。

    所以这次尽我所能,全面、详细地整理一些Qt程序发布的知识点,希望能帮助到更多人。

    对老手来说,很多坑都踩过了,无非就是把正确的dll放在正确的路径。

    对新手来说,细节上能多说几句,都将是莫大的帮助,少走弯路,节省几个小时、甚至几天都是有可能的。

    如果有疏漏、错误,也欢迎大家补充、指正。

    Qt的安装

    Qt官网下载地址在这: http://download.qt.io/official_releases

    离线安装包 或者 在线安装包 都行。

    关于Qt版本的选择,涛哥建议:

    体验新特性,就用最新版本;项目开发,用长期支持版(LTS)的最后一个修正版本,稳定、bug最少。

    可以在Qt官方wiki上查看相关信息 https://wiki.qt.io/Main

    目前为止(2019/9/2),最新版为5.13.0,LTS版本有5.9 和 5.12, 而5.9最后一个修正版本是5.9.8, 5.12则是到5.12.4

    例如上图是5.9.8的离线安装包,提供了windows、mac以及linux三种系统的可执行程序。

    其中windows的安装程序”qt-opensource-windoiws-x86-5.9.8.exe”, 大小有2.4G,里面

    包含了msvc_x86、msvc_x64、mingw、Android等多个版本的Qt工具链。在下载完成,安装

    过程中可以分别勾选。其它版本也是类似的。

    如何安装Qt,就不细说了,搞不定的去参考入门级教程吧…

    Qt的目录结构

    这里假设大家都装好了Qt,先来了解一下Qt的安装路径都有哪些东西。

    涛哥用的是Windows 10系统,安装的Qt版本是5.12.4,以此为例来说明,其它系统和版本以实际为准。

    Qt安装路径

    涛哥安装在了D:QtOnline 路径下, 如图:

    其中“vcredist”文件夹包含了msvc2015 和 msvc2017的运行时库安装程序(后面会说怎么用,不是msvc编译器不需要)

    “Tools”文件夹,包括QtCreator、OpenSSL库(可选)以及两种版本MinGW(可选)。

    (图中还有Qt3DStudio,可忽略)

    “5.12.4”文件夹,是Qt的核心路径, 里面包含多个版本的Qt工具链、头文件、动态链接库等

    这里涛哥安装了msvc2017、msvc2017_64、mingw73_64以及android_x86.

    注意msvc2017是x86架构的Qt库,msvc2017_64则是x64架构的。

    如果有msvc2013、msvc2015也同理。

    Qt核心路径

    接下来看一下重点,Qt的核心路径, 以msvc2017_64文件夹为例

    bin文件夹包含了Qt提供的各种工具exe程序,以及动态链接库的dll

    其中工具包括qmake.exe 和 windeployqt.exe,windeployqt.exe是我们今天主要讨论的工具。

    动态链接库全部是两份dll,比如Qt5Cored.dll和Qt5Core.dll,文件名末尾带’d’表示debug版本的,另一个不带’d’的是release版本。

    debug版本和release版本的主要区别:debug没有开编译器优化、携带了调试信息,release开了编译器优化O2,去掉了多余的信息

    (图中还有pdb文件,是涛哥单独安装的,用来调试Qt源码,可以忽略)

    和bin同级的,还有plugins文件夹,包含一些Qt用到的插件

    比如imageformats文件夹中提供了jepg、gif、webp等图片格式的功能支持的插件,platforms文件夹则提供了平台插件,特别是

    qwindows.dll这一个,在windows平台是必不可少的。

    和bin同级的,另外一个文件夹是’qml’文件夹,包含Qml的各种功能模块。

    和bin同级的其它文件夹,resources是WebEngine模块专用的,translations提供了

    Qt内置的翻译文件,剩下的和发布无关,就不多说了。

    HelloDeploy

    这里新建一个简单的Hello World程序,名字就叫”HelloDeploy”。

    同时为了说明问题,涛哥添加一些常用的模块。

    在pro文件中,QT += 那一行该写的都写上:

    在main.cpp中包含一下各个模块的头文件,再分别创建一个对象实例,调用一些简单的函数:

    这样一个多模块依赖的程序就写好了。

    Window编译和发布

    Window 编译

    这里要特别注意,编译器的选择, 以及编译用的是debug模式还是release模式。

    涛哥这里是msvc2017_x64版本

    一般发布用release模式。

    编译完成后,默认在build-xxxx-release/release/文件夹中会生成我们的exe程序。

    我们将这个exe复制出来,新建一个release文件夹,放进去

    这时候可以尝试双击运行它,会提示缺少dll

    Window 发布

    发布程序,其实就是把exe程序依赖的dll和相关资源都放在一起,保证双击运行即可。

    我们前面提过的windeployqt.exe,是Qt提供的命令行工具,能帮助我们自动把需要的dll或资源复制过来。

    1. 我们先打开一个命令行

    可以从开始菜单找到Qt提供的命令行

    注意选对版本。这种命令行在启动时已经设置好了QT的环境变量,可以直接输入windeployqt.exe

    也可以用普通的命令行,使用windeployqt.exe时带上绝对路径即可。

    涛哥一般用普通的命令行,因为绝对路径不易出错。

    1. cd到release目录

    这里说一个windows启动命令行的小技巧:在release文件夹中,按住键盘shift键,然后按鼠标右键,弹出的右键菜单,

    会比普通的右键菜单多一个“在此处打开命令窗口”,点击就能在release文件夹打开命令行窗口。

    如果没有这个功能,就得手动输入cd指令,进入release路径。

    1. 执行windeployqt命令

    这里通过绝对路径来使用windeployqt:

    d:qtOnline5.12.4msvc2017_64inwindeployqt.exe HelloDeploy.exe

    HelloDeploy这个程序还用到了Qml,用到Qml的程序,要给windeployqt加上qmldir参数,写上相应的msvc2017_64qml文件夹

    (没用到qml的程序,不要加这一步)

    d:qtOnline5.12.4msvc2017_64inwindeployqt.exe HelloDeploy.exe –qmldir d:qtOnline5.12.4msvc2017_64qml

    写好windeployqt命令后按回车执行

    正确执行后,release文件夹下,多了很多dll,以及一些文件夹。

    这时候我们双击运行HelloDeploy.exe, 就可以正常启动了。

    将整个文件夹压缩或拷贝到其它没有Qt环境的电脑上,也是可以启动的。

    只要dll齐备了,制作安装包也不是问题。(后续有时间,我再写安装包制作的教程)

    VS运行时库

    如果是VS编译的程序,需要将QT路径下对应的vcredist_xxx.exe带上。

    如果其它电脑上有vs运行时则可以直接运行,如果没有,就需要运行一下vs运行时安装包。

    经常玩一些单机游戏的同学应该都知道这个问题。

    有的电脑环境特殊,可能运行时库无法安装上去,这时候需要一些变通的方法,

    直接将运行时库安装包里面的dll复制出来即可。

    怎么取出来?在能安装的电脑上装一遍,然后就有dll了,名字是vcruntime140.dll、

    msvcp140.dll之类的,这里就不展开说了。

    常见的错误处理

    一般使用windeployqt,大部分库都能自动拷贝,不需要手动处理,

    只有极少数情况下,windeployqt跑完,会缺失一些库,还要手动处理一下。

    遇到这种情况,用依赖检查工具Dependencies即可快速定位问题。

    Dependencies下载链接: https://github.com/lucasg/Dependencies

    下面列举一些常见的错误信息

    应用程序无法正常启动

    最容易出现这种错误的情况是,程序是64位编译出来的,而同级目录下的dll是32位的,

    或者同级目录下没有dll,但是环境变量中指向了32位的dll。(所以涛哥没有设置环境变量)

    32位和64位倒过来也是。

    如果dll版本是匹配的,还有可能出现的情况是缺少第三方库。

    这里说一个检查依赖的方法:

    将HelloDeploy.exe重命名为HelloDeploy.dll,然后用Dependencies打开,就可以查看少哪些库

    如上图,红色问号的表示缺少的库。

    找齐了依赖的库,再把程序的扩展名改回exe即可。

    启动失败 - no Qt platform plugin

    这种情况,是QT路径下的 plugins/platforms/qwindows.dll文件没有复制过来。

    注意这个dll文件直接复制到exe同级是不起作用的,要放在exe程序同级的platforms文件夹里,或者同级

    的plugins/platforms文件夹里

    OpenGL Context 创建失败

    这种情况,一般是OpenGL相关的库没有复制过来,补上就好了

    整理

    我们看到,exe同级目录下,windeployqt将一堆的文件夹放在了那里,有些混乱。

    涛哥观察并验证了一下,其实可以做个简单的整理。

    Qt开头的文件夹都是qml的模块,剩下的文件夹除了translations都是Qt的插件,

    所以新建两个文件夹qml和plugins, 分别把qml模块和插件归入其中。

    这样的结构,和QT安装路径下的结构是相似的。

    这也正是Qt支持的插件加载路径、qml模块加载路径。

    同级的dll则是windows系统默认的动态库加载规则,不方便修改

    可以参考msdn:

    https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order

    简单裁剪

    如果你熟悉Qt的各个模块,可以进行一些裁剪。以下都是些个人经验。

    不熟悉请慎重!

    不熟悉请慎重!

    不熟悉请慎重!

    (当然静态编译也是一种裁剪的途径)

    删减dll

    首先可以把单元测试的dll去掉

    Qt5Test.dll

    Qt5QuickTest.dll

    如果没用到windows扩展,Qt5WinExtras.dll也可以去掉

    其次,如果你不需要内置的翻译文件,translations文件夹也可以删掉

    删减plugins

    再来看一下plugins:

    其中platforms是必不可少的,剩下的HelloDeploy都没用到,可以去掉。

    常见程序会用的包括:

    imageformats 图片格式支持

    iconengines 小图标功能

    sqldrivers 数据库驱动,这个保留用到的数据库足够了

    其他的看情况删减。

    删减qml

    最后看一下Qml文件夹,如果程序完全没用qml,直接删掉就好了。

    按windeployqt给HelloDeploy提供的这些,逐个文件夹来说:

    • Qt/labs 一般不推荐Qml中引入labs中的实验品,但是有些情况下功能缺失,只能引入。

    如果Qml中使用了Quick.Dialog(不是labs.Dialog),它本身还是依赖的labs中的东西,一般是folderlistmodel和settings,

    这时候还是不要动labs了,就按照windeployqt给的放着。

    • Qt/WebSockets Qml的Websocket功能,用了就放着,没用可以删掉。

    • QtGraphicalEffects Qml的一些ShaderEffect特效,用了就放着,没用到可以删掉

    • QtMultimedia Qml的多媒体模块,用了就放着,没用到可以删掉

    • QtQml/Models.2 数据Model, 经常用。

    • QtQuick 这里面大部分都是Qml中常用的,QtQuick/Extras可以按情况删掉

    • QtQuick.2 常用的

    • QtTest 单元测试,删掉吧

    • QtWinExtras Windows扩展,没用到可以去掉

    =========================================

    来源 https://blog.csdn.net/liyuanbhu/article/details/60147904

    参考 http://hgoldfish.com/blogs/article/103/

    Qt4.4 引入了 Webkit 方便程序员往自己的程序里面嵌入 HTML 页面。刚开始倒也没事,反正不主动包含到项目里面的话,程序安装包并不会变大。那会儿,Qt 程序只要 8M(压缩到3M)就搞定了。到了 Qt5 的时候 Webkit 换成了 Chromium 内核 Blink,名字改成了 QtWebEngine. Qt 开发者发现 Blink 使用的 ICU,提供了比旧版本 Qt 更完整的国际化能力。于是,据说是因为一个误会,Qt 开发者就在 Qt 5.0 里面强制依赖于 ICU 了。这个 ICU 包含了大量的国际化元信息,一下子增长了近 30M 的容量。。

    导致 Qt 容易增长还有另外一个重要原因,也就是 Qt 自从 4.7 以后引入的 QML。这是一个基于 ECMAScript 改造的语言。从此以后,Qt 开发就有两种流派,一者使用原来的 C++ 语言进行开发,另外一种使用 QML 语言进行开发。两者共享一样的底层设施,比如各种数据结构与事件循环 QtCore 和 带有 OpenGL 支持的 QtGui。但在上层,Qt 为 C++ 开发者们提供了 QtWidgets,又为 QML 开发者提供了独立的 QtQuick.

    QtQuick 本身只有简单的布局语言,Qt 又在这个基础上提供了 QtControls 模拟 Android,iOS 和 Windows 程序的外观。早期的 Qt5 没有设计好,导致使用 QML 时要引入一大堆程序可能用到的组件。所以一个 helloworld 下来,相当巨大。而且很奇怪的事,以 QtWidgets/C++ 的方式使用了 QtWebEngine 的话,也会引入几乎所有的 QML 模块,那会儿一个简单的程序会达到一百多兆的大小!

    Windows 平台还有一个特殊的问题。现在 Qt 的图形架构调用 OpenGL ES 2.0 进行底层的渲染,但刚安装完的 Windows 只支持到 OpenGL 1.1,针对这个问题,早期的 Qt 在 configure 阶段提供了两种选项,一是使用与 Chromium 一样的 ANGLE,把 OpenGL 调用翻译成 DirectX 调用,二者假定用户的系统安装了显卡驱动,能够支持 OpenGL 2.0。前者需要包含几个 ANGLE 的 DLL,直接又增加了 17M 的容量!

    所幸这些事情现在都解决了。

    首先,Qt 5 的早期版本已经提供了一个 configure 选项,可以不把 ICU 编译到 Qt 里面,但是官方下载版本仍然默认包含 ICU,后来 Qt 直接去掉了对 ICU 的依赖。现在的 Qt 在运行时找到 ICU 的 DLL 就会使用 ICU,否则调用系统的 API,如果都没有,就凑合着用 Qt 内置的算法处理国际化。

    其次,QML 一些奇怪的依赖现在也去掉了。所以现在无论使用 QtWidgets 还是使用 QML,未压缩时都只有 20M 左右的容量。

    最后一个,现在有多少用户的电脑是没有安装显卡驱动的呢?好吧,好像还真有,vmware 的虚拟机。但我觉得正常直接用系统自带的 OpenGL 驱动足矣。Qt 现在会在运行的时候自动探测 ANGLE 是否存在,如果存在,就使用 ANGLE,如果不存在,就使用系统自带的 OpenGL,不必像以前那样在 configure 阶段就配置好。另外,QtWidgets 没有使用 OpenGL,所以使用 QtWidgets/C++ 的程序也可以把 ANGLE 的 DLL 都去掉。

    用 Qt 5.7 来说,现在提供了一个名为 windeployqt.exe 的程序,位于 Qt 的 bin 目录里面。运行这个程序,后面带程序名称就行了:

    1. 创建一个 dist 目录
    2. 把编译好的 qttest.exe 复制到 dist 目录。
    3. 打开 cmd.exe,cd 到 dist 目录
      4.1 运行 c:qt5inwindeployqt.exe qttest.exe
      4.2 对于 QML 程序,需要指定 QML 目录: c:qt5inwindeployqt.exe –qmldir d:qttest qttest.exe

    这时候就会看到 qt 已经把需要用到的 DLL 都复制过来了。我会在这个基础上再根据需要去掉一些东东:

    1. libEGL.dll, libGLESV2.dll 这两个文件是 ANGLE 的文件,可以去掉。opengl32sw.dll 是软件模拟 OpenGL,除非用户的系统连 DirectX 支持都不完整——虚拟机环境就是这样——不然这个文件也完全没有用。 QtWidgets/C++ 程序都不用 OpenGL,所以直接去掉即可。可在调用 windeployqt.exe 时加”–no-angle” 和 “–no-opengl-sw” 这两个参数。
    2. 如果没有使用 svg 的话,iconenginesqsvgicon.dll, imageformatsqsvg.dll, Qt5Svg.dll 这三个文件也可以删掉
    3. 如果没有国际化用户的话,translations 里面的翻译文件也可以删掉。
    4. QML 程序没有使用 QtWidgets/C++ 可以删掉 Qt5Widgets.dll
    5. 如果 imageformats 目录里面有几种图像格式没用上,也可以删掉。我自己通常把整个目录都删掉,Qt已经编译了 png 的支持,能读写程序包含的图标就够,其它格式不重要。
    6. qmltooling 和 Qt5Network.dll 是用于 QML 调试用的,可以删掉。

    经过以上裁剪,使用 7zip 压缩完以后,一个 QtWidgets/C++ helloworld 程序最终只剩下 5.64M,一个 QtControls 程序是 5.86M, QtQuick 程序还会更小一些。

    附注:

    截止本文写作时,Qt 5.8 已经发布了。在这个版本里面,不再依赖于 OpenGL ES 2.0,而是绕过 ANGLE,直接调用 DirectX 渲染,到 Qt 5.10 还要直接支持 Vulkan API。不过目前仍然是试验性的,有兴趣的话可以看看 configure 的说明。

    新的 Qt 5.8 重写了 configure 系统,能够更深入地裁剪 Qt。最小未压缩 5M 即可布署一个 QML 程序。

    参考资料:

    Qt 5 ICU
    https://wiki.qt.io/Qt_5_ICU
    http://wiki.qt.io/Qt-5-QLocale

    Dynamically Loading Graphics Drivers
    http://doc.qt.io/qt-5/windows-requirements.html

    Qt Lite
    http://blog.qt.io/blog/2017/01/23/qt-5-8-released/

    ============== End

  • 相关阅读:
    二、推导式/自省
    一、Python编码规范(PEP 8)/工程结构化
    十、持续集成(Jenkins+Ant+Jmeter)
    九、Jmeter之逻辑控制器
    八、Jmeter分布式测试
    七、ServerAgent监控服务器资源
    六、场景设计/报告分析
    五、集合点/断言/关联
    .html页面引入vue并使用公共组件
    vue.js页面刷新出现闪烁问题的解决
  • 原文地址:https://www.cnblogs.com/lsgxeva/p/12298087.html
Copyright © 2011-2022 走看看