找回密码
 立即注册
Qt开源社区 门户 查看内容

构建 Qt 安装程序

2019-10-1 09:36| 发布者: admin| 查看: 1911| 评论: 0

摘要: 当软件开发完成之后,还有一项很关键的任务要做- 打包发布。换句话说,我们的软件最终要交付给用户,并且能够让他们很容易地安装在自己的系统上。那么,该如何制作这样的安装程序(软件包)呢?我们一步一步道来。1 ...


当软件开发完成之后,还有一项很关键的任务要做 - 打包发布。换句话说,我们的软件最终要交付给用户,并且能够让他们很容易地安装在自己的系统上。



那么,该如何制作这样的安装程序(软件包)呢?我们一步一步道来。

1

静态库与动态库

在介绍打包之前,有必要分享一下静态库与动态库的区别,因为最终安装包中的文件组成与之息息相关。

静态库动态库
对于静态库来说,它总是与应用程序编译在一起的,在任何情况下都能运行,不依赖于外部情况(即:不会遇到兼容性问题)。而动态库是动态连接的,顾名思义,就是在程序真正运行时才会链接。所以当系统中没有该动态库时,应用程序就会运行失败。
使用静态连接的应用程序比较大,如果多个应用程序使用了相同的静态库,依然需要多次装载到内存中,这会造成一定程度的浪费。多个应用程序可以共享同一个动态库,当启动多个使用相同动态库的应用程序时,只需要将动态库加载到内存一次就 OK 了。
一般情况下,静态连接的应用程序执行速度较快,因为所有需要的代码都已经放在可执行文件之中了。而对于动态连接的应用程序,却需要在运行过程中动态调用动态库,因此速度也略慢。

(在某种程度上,这取决于程序的大小和复杂性、以及操作系统的加载策略)。
对于静态连接的应用程序,如果静态库发生了变化,那么整个程序都需要重新编译。而动态连接没有这个问题,在保持接口不变的情况下,升级动态库不会影响应用程序(前提要有足够的兼容性),所以在这一点上动态库相当的方便。


Tips:对于使用 Qt 的应用程序,如果要静态编译,则需要构建一个静态版的 Qt。这意味着,无法关闭源代码并在 LGPL 上回复(要么开放源代码,要么获得商业版 Qt 许可证)。

在 Windows 中,要解决可执行文件过大的问题,可以使用像 UPX 这样的加壳工具。在对可执行文件压缩之后,会在启动时将其解压缩到 RAM 中。

而在 Linux 中,可以通过 strip 命令来去除目标文件中的调试信息、符号信息,以减小程序的大小。但要注意一点,strip 只能用于可执行文件和动态库(.so),不能用于静态库(.a)。

2

应用程序的组成

对于 Qt 应用程序来说,它们一般由下述文件组成,这些文件可分为三部分:




  • 可执行文件(例如:.exe):最终由用户运行的程序。

  • 动态库(.dll 或 .so):通常是一些 Qt 模块(QtCore、QtGui 等)和插件,以及第三方库。

  • 支持文件:如图片、翻译文件、帮助文档等。


支持文件可以被集成到可执行文件中,最简单的方法是使用 Qt 资源系统,它允许将任何文件嵌入到可执行文件中。这是大多数仅由可执行文件(而非用户)使用的文件的逻辑位置,像上面说的图片、翻译文件、帮助文档等,千万不要将示例文档、或者用户希望能够在文件系统中找到的其他文件放在这里面。

在创建安装程序时,则需要用到这些资源并从中构建软件包。该包不仅包含了所需的文件,还可能会包含一些说明(例如:ReadMe),以及用户需要遵循的许可协议(License),等等。

3

构建安装程序


从某种程度上来讲,构建安装程序是平台特定的任务,而且将来可能会一直都是。这不仅因为平台不同,而且因为分发机制不同。

Windows


在 Windows 平台上,当构建完 Qt 程序之后,需要找到其所依赖的动态库(dll)。为此,可以使用工具 Dependency Walker,它展示了一个图形树,包含了程序所依赖的 dll,以及每个 dll 依赖的其他 dll。



使用 Dependency Walker 有个诀窍 - 分类查找:判断哪些 dll 是 Windows 自带的(即:预装在用户计算机上的)、哪些是属于 Qt 的(即:需要打包的)。另外,还要考虑用到的一些第三方库,这可能会增加更多的依赖关系。最后,还有一个需要注意的问题:Qt dll 可以依赖于其他 Qt dll(例如,Qt3Support 模块依赖于大多数其他 Qt 模块)。

在使用 Dependency Walker 将所需文件列表放在一起后,下一步是从这些文件中构建一个安装程序,有许多工具都可以完成此任务:


  • NSIS

    https://nsis.sourceforge.io/Main_Page

    如果你喜欢开源软件,则一定知道 NSIS(全称:Nullsoft Scriptable Install System)。它是一个专业的工具,可用于创建从非常简单到非常复杂的安装程序。虽然它很小,但功能却很丰富,非常适合 Internet 分发。

    正如其名,NSIS 是基于脚本的,它能够让我们创建处理任何情况所需的复杂逻辑。幸运的是,它包含了许多插件和预定义脚本,以帮助初学者入门。


  • Inno Setup

    http://www.jrsoftware.org/isinfo.php

    是一个免费的安装制作软件,小巧、简便、精美是其最大特点,支持 pascal 脚本,能快速制作出标准 Windows 2000 风格的安装界面,足以完成一般安装任务。

    该软件用 Delphi 写成,其官网同时也提供源程序免费下载。它虽不能与 Installshield 这类“恐龙级”的安装制作软件相比,但也算是当之无愧的后起之秀。


  • Advanced Installer

    https://www.advancedinstaller.com/

    有一个免费版本,但也有其他几个版本,这些版本的价格取决于安装程序的复杂程度。如果你正在寻找更专业的东西,其中还包括一些支持选项,那么 Advanced Installer 是一个不错的选择。

    用它创建 MSI 文件包非常方便,只需添加文件、修改名称、添加按钮即可,无需任何脚本方面的知识,并且生成的安装文件保证符合 Windows 最佳操作建议。


  • InstallShield

    https://www.flexerasoftware.com/install/products/installshield.html

    是一款“恐龙级”的安装包制作工具,是 Flexera Software 的当家产品。这不仅是因为它拥有 20 多年的研发历史,而且它也是全球著名软件公司的“皇家御用”打包软件,比如 Adobe、Corel、Autodesk 等公司。

    然而这款软件过于专业,并不像 NSIS、Inno Setup 等那样容易入门,所以想学习必须下很大功夫。这也是全球领先的 Windows 安装开发解决方案,现在已经成为 Windows Installer 和 InstallScript 安装方面的行业标准。


  • WIX Toolset

    https://wixtoolset.org/

    是一个免费的打包工具,通常要与 Visual Studio(2012 或更高版本)一起使用。之所以最后提到它,是因为它需要经过大量的学习。虽然可用它创建一些非常复杂的安装程序,但要编写大量的代码并经常使用命令行。


Tips:在测试安装程序时,建议使用一台没有安装任何 Qt 版本的机器(最好是全新安装的 Windows)。如果安装程序缺少 dll,将无法运行并显示相应的错误信息,指出缺少哪个 dll。但是,在启动时不会检查插件,因此需要确保测试插件提供的所有功能都存在。

Linux


对于 Linux 系统来说,要查看可执行文件依赖的库以及缺少的函数符号,可以使用 ldd -r 指令。

如果要部署 Qt 应用程序,可以选择以下方式:


  • 构建源码包

    对于开源项目来说,这是最简单的方法。

    但一定要记得,在使用 tar 命令对目录树进行压缩之前,需要先运行 make distclean 来清理构建环境。


  • 创建本地分发包

    这要考虑系统的发行版,而主流的包管理系统有两个:rpm 和 deb。rpm 格式起源于 RedHat,但也被其他发行版使用,例如:CentOS、SuSE 和 Fedora。deb 格式是由 Debian 项目开发的,适用于 Debian/Ubuntu 及其衍生版。

    rpm 可参考 RPM HOWTO(http://www.tldp.org/HOWTO/RPM-HOWTO/),尤其是关于构建的部分 - Building RPMs。

    deb 可参考Debian 新维护者手册(https://www.debian.org/doc/manuals/maint-guide/)。


  • 创建独立的应用程序包

    若要将 Qt 程序作为一个独立的包部署到 Linux 中,需要将其以及所需的组件捆绑在一起,像 Qt 库、Qt 插件(尤其是 platforms 插件)。

    推荐一个 Linux 部署工具 -  linuxdeployqt(https://github.com/probonopd/linuxdeployqt),它能够自动执行上述的流程,并提供 AppImage(https://appimage.org/)。


Tips:和 Windows 不同的是,Linux 下可执行文件及其依赖库放在同一目录一般是无法正常运行的。常用方式是写一个 Shell 脚本,并用 LD_LIBRARY_PATH 指定依赖库所在目录,然后通过运行这个脚本来间接地启动程序。

OS X


买不起... 买不起... 买不起... 贫穷限制了我,So 暂不涵盖!

多平台 GUI 安装程序


除了上述特定平台的打包方式之外,还有一些支持跨平台的工具:


  • Qt Installer Framework

    https://doc.qt.io/qtinstallerframework/

    简称 Qt IFW,由 Qt 官方提供,以前仅用于 Qt 本身,但现在已经发布了,用于创建通用的安装程序。


  • InstallBuilder

    http://installbuilder.bitrock.com/

    是一个功能强大、易于使用的跨平台安装程序创建工具。它一直都在积极维护,但仅供商业使用。


  • InstallJammer

    https://sourceforge.net/projects/installjammer/

    是一个跨平台 GUI 安装程序和生成器,虽然是开源的,但 2011 年之后就不再维护了,比较遗憾!


  • ......


以上介绍的都是一些比较知名、并且相对稳定的工具,可以很好地帮助我们构建 Qt 安装程序,我相信类似的工具还有很多,不知道你用的是哪一款呢?Enjoy



·END·

高效程序员
谈天 · 说地 · 侃代码 · 开车



长按识别二维码,解锁更多精彩内容

----------------------------------------------------------------------------------------------------------------------
我们尊重原创,也注重分享,文章来源于微信公众号:高效程序员,建议关注公众号查看原文。如若侵权请联系qter@qter.org。
----------------------------------------------------------------------------------------------------------------------

鲜花

握手

雷人

路过

鸡蛋

公告
可以关注我们的微信公众号yafeilinux_friends获取最新动态,或者加入QQ会员群进行交流:190741849、186601429(已满) 我知道了