在Qt 5.9.1通过qt.conf指定共享库路径部署应用程序

版本更新日志

Ver 17.0822

首次创建。

Ver 17.0824

1、增加FAQ:Debug模式下无法启动应用;
2、增加示例文件及相关文件的百度云盘链接路径。

1 背景介绍

无论是使用Qt静态链接,或者使用Enigma Virtual Box将exe及其依赖的库进行打包均存在如下问题:

  • 发布程序非常大;
  • 不具备灵活性(如果程序或Qt更新,需要重新部署过程);
  • 不能部署插件(dll);
  • 使用Enigma Virtual Box打包后程序启动速度较慢(本人测试启动时间约为静态链接方式的4倍)。

如果应用程序中具有多个exe,或者多个exe共同插件(Qt提供插件或自己写的插件),上述方式均不能任胜,即通过静态链接或打包的方式不适合开发大型的企业级应用。

如果使用Qt提供的部署工具windeployqt,则exe所依赖的Qt库位于相同的文件夹,给应用程序的版本管理带来极大的困难。

本文提供了一种方法,用以解决上述两个问题。将exe应用依赖的Qt库放于固定的文件夹,可将exe放于任意位置,实现应用启动。当开发模式成熟后,企业应用依赖的Qt库已基本上不会变动时,可将该依赖库打包成一个exe,在用户计算机上安装,如同在用户计算机上安装.NET Framework/.NET Core(安装.NET应用运行所需的托管运行库CLR Runtime)。

2 使用windoployqt打包exe依赖的库

启动“Qt 5.9.1 for Desktop (MinGW 5.3.0 32 bit)”,如下图所示。

在Qt 5.9.1通过qt.conf指定共享库路径部署应用程序_第1张图片

按下面命令格式执行命令:

windeployqt --force --qmldir {path-to-qml} --dir {path-to-store-qt-libraries} {path-to-app-binary}

命令参数解释:

  • –force:强制更新目标路径exe所依赖的Qt库;
  • {path-to-qml}:qml路径,如:D:\Qt\Qt5.9.1\5.9.1\mingw53_32\qml;
  • {path-to-store-qt-libraries}:exe所依赖Qt库的生成路径,如:D:\company_program\qtlibs
  • {path-to-app-binary}:exe路径,如:E:\test_program\TestProject.exe。

完整的示例代码如下:

windeployqt --force --qmldir D:\Qt\Qt5.9.1\5.9.1\mingw53_32\qml --dir D:\company_program\qtlibs E:\test_program\TestProject.exe

3 创建环境变量

将下面内容粘贴至记事本中,保存名为“qtlibs.cmd”的文件,以管理员身份运行。

SETX _COMPANYDIR "D:\company_program" /m
SETX PATH "%PATH%;%%_COMPANYDIR%%\qtlibs" /m

PAUSE

注:
1)路径“D:\company_program”要与第2步存放Qt依赖库的路径一致;
2)为后续方便管理,可将“qtlibs.cmd”文件放于“D:\company_program”文件夹下。

4 qt.conf文件的创建

4.1 在应用程序目录下创建“qt.conf”文件

在应用程序目录,如“E:\test_program\”建立名为“qt.conf”(注:名字一定不能错误),输入如下内容,关闭保存:

[Paths]
Prefix = D:/company_program/qtlibs
ArchData = .
Data = .
Libraries = .
LibraryExecutables = .
Binaries = .
Plugins = .
Imports = .
Qml2Imports = .
Translations = translations

4.2 使用资源系统

按下图所示的路径添加“qt.conf”文件。

在Qt 5.9.1通过qt.conf指定共享库路径部署应用程序_第2张图片

注:
对于企业级应用推荐使用该方法。
优点:可在应用程序中使用硬代码写死路径,减少用户使用过程中因误删“qt.conf”文件而无法启动。
**缺点:**Qt依赖库的路径必须按约定的路径进行配置,用户无法配置Qt库依赖路径。

企业级应用一个非常好的原则——“约定优于配置”,这种固定路径的做法,在企业级应用中就变成了优点,因为你的开发人员、技术支持人员、甚至是售后维护人员都形成了固定的做法,想出错都难。

对于企业的大部分非开发的普通员工,根本无需知道为什么这样做(你根本无法向一个二进制都不知道的人解释整型),只要知道怎么做,所做的步骤越少、约简单,才能最大程度上降低出错的概率,这也极大程度上降低了企业的管理成本。

5 程序启动测试

经过2~4三个步骤后,可以将exe拷贝至任意位置,双击执行,如下图所示。
1)在应用程序目录下创建“qt.conf”文件

在Qt 5.9.1通过qt.conf指定共享库路径部署应用程序_第3张图片
注:“qt.conf”文件一定要与exe在相同的目录下。

2)使用资源系统

在Qt 5.9.1通过qt.conf指定共享库路径部署应用程序_第4张图片

双击执行效果如下图所示:

在Qt 5.9.1通过qt.conf指定共享库路径部署应用程序_第5张图片

6 FAQ

6.1 Debug模式下无法启动应用

6.1.1 故障描述

在Debug模式下,按Ctrl+R或F5键启动应用程序,出现以下错误。

在Qt 5.9.1通过qt.conf指定共享库路径部署应用程序_第6张图片

6.1.2 原因分析

若使用本文第4节提供的两种方法,在程序调试阶段添加了qt.conf文件,则Qt Creator将加载插件(plugin)的路径指向发布版本所依赖的库的路径。由于发布版本依赖的Qt库属于Release版本,与Debug所需的Qt库不同,所以出现上述错误。

6.1.3 解决办法

仅在程序的发布阶段使用本文提供的方法添加qt.conf文件。

附录A 解决方案灵感来源

将Qt应用程序所依赖的Qt库放于目标计算机指定的文件夹(自定义)路径,通过某种方式指定Qt应用程序所依赖库的路径,则应用程序可以放于目标计算机的任意位置,进而实现应用程序的灵活、方便管理。即预先在目标计算机上安装一个Qt应用程序所需的运行环境,可称为Qt Application Runtime(Qt应用运行库或运行时),这类似于使用.NET应用时需要在目标计算机上安装.NET Framework/.NET Core。

本文所给的解决方案的灵感来自于以下几个方面:

A.1 windeployqt –help提示

使用windeployqt最简单的方式是将Qt的bin的安装路径(如”QT_DIR\bin”)添加到PATH路径中…(The simplest way to use windeployqt is to add the bin directory of your Qt installation (e.g. “QT_DIR\bin”) to the PATH variable…)
同时添加该路径后,可通过双击exe的方式启动应用,而非通过Qt Creator的Ctrl+R快捷键启动应用。

上述操作的启示:

a) 通过安装Qt 5.9.1能够提供exe依赖的库,那么使用windeployqt打包后依赖的库也应可以实现相同的功能;

b) 通过在PATH中添加指向安装Qt 5.9.1后的路径,如“D:\Qt\Qt5.9.1\5.9.1\mingw53_32\bin“后,可以双击的方式(而非在Qt Creator使用Ctrl+R快捷键的方式)启动应用。那么若在PATH中添加指向”步骤a)“中打包依赖库的路径,也应该可以通过双击方式启动应用。

A.2 使用qt.conf

你可以通过使用qt.conf文件覆盖路径或定义传递给平台插件的参数(You can use the qt.conf file to override paths or to specify arguments to be passed to the platform plugins.)。英文翻译的不好,读懂意思即可,总之要表达的大概意思是“使用qt.conf可以重新配置exe依赖的插件路径”。

A.3 qmake -query

通过该命令可以查看Qt默认安装后所依赖库的路径:

在Qt 5.9.1通过qt.conf指定共享库路径部署应用程序_第7张图片

虽然都是宏定义,但是和Qt的官方文档比较,不难得知其含义:

在Qt 5.9.1通过qt.conf指定共享库路径部署应用程序_第8张图片

注:在qt.conf文件中使用了绝对路径,其他所有路径都是Prefix的相对路径(Absolute paths are used as specified in the qt.conf file. All paths are relative to the Prefix. )

参考资料

http://doc.qt.io/qt-5/deployment.html
http://doc.qt.io/qt-5/windows-deployment.html
http://doc.qt.io/qt-5/qt-conf.html
http://www.cnblogs.com/findumars/p/6388583.html

示例代码的云盘路径:

链接: http://pan.baidu.com/s/1i502Us1 密码: 37vm

你可能感兴趣的:(开发工具,qt)