Qt到了5.8版本,终于迎来了一个重要功能,就是QtLite。
此功能可谓是千呼万唤始出来,饱受诟病的体积问题,终于可以在一定程度上得到解决。
在这个回答里,先是介绍QtLite,然后如何使用以及使用效果,最后是我的评价。
那么QtLite到底是什么呢,按照官方原话,是
Configurability (Qt Lite Project) Qt 5.8 comes with a rewritten configuration system that allows for easy customization of Qt builds. The main focus of this feature is for the Device Creation, but it can also be used to tailor a Qt build for mobile or desktop platforms. The new configuration system allows removing individual pieces of functionality and APIs from Qt, creating a more lightweight set of libraries for deployment.
也就是说,QtLite实质上是一个配置系统。
话说我最初以为这是一个单独的工具,可以直接缩减应用的体积。然而并不是。
我这里主要说下后半段,也就是 removing individual pieces of functionality and APIs from Qt ,这句话的意思就是我们可以直接去除Qt模块中的功能和API了,这是缩减体积最重要的部分。
什么叫去除功能和API呢。我举个例子
Qt里有一个类,叫QClipboard,就是剪切板相关的功能。但是很多人出于某些原因,不用这个,或者用了系统的API。那么这样的话,这个QClipboard就没有任何存在的意义了,我们就可以直接去掉它,以缩减库体积,最终缩减应用的体积。
那么如何做到这一点呢。首先我们要重新编译Qt的源码,然后在配置的时候,添加特定的参数,来进行配置,去除掉这个功能。
参数很简单,就是 -no-feature-clipboard
配置好后,重新编译Qt,就可以了。
目前Qt有一个feature列表,里面记录了Qt有哪些feature,有100多个。我的理解就是这里的feature都是可以去掉的,这个列表存放的位置在源码的 qtbasesrccorelibglobalqfeatures.txt
内容如下:
不过呢,在我的实际使用中,我发现这个列表里的并非都可以去掉,我只能说一大半是可以去掉的。要我说怎么区分哪些可以,哪些不可以。首先是看Requires,模块间是相互依赖的,被Requires的模块去掉的话,Requires它的模块就会没法正常编译。在Requires都得到保证的情况下,也不是说所有模块都可以去掉,有时候编译会报错,那么只能把去掉的feature加回去。
比如说,遇到了这个
这里说QSettings不是一个类型。的确,我去掉了settings这个feature。看起来是其他的模块,使用了QSettings。
(貌似是gui那里用了core里的这个feature?那我如果不用gui是不是可以仍然去掉这个feature呢?具体还没尝试)
但是settings这个feature在列表里,没有Requires其他feature,其他feature也没有Requires它,有图为证。
不过,有什么办法呢,无力修改Qt源码,只能再把settings加回去。
我试了N种配置,编译了整整1天,真的好心累,终于调出来一个可以编译过,然后去掉尽可能多的模块配置。如下:
configure.bat -static -release -platform win32-g++ -no-opengl -prefix "C:QtQt5.8.0_MinGW_static" -opensource -confirm-license -make libs -nomake tools -nomake examples -nomake tests -skip qt3d -skip qtandroidextras -skip qtcanvas3d -skip qtcharts -skip qtconnectivity -skip qtdatavis3d -skip qtdeclarative -skip qtdoc -skip qtgamepad -skip qtgraphicaleffects -skip qtimageformats -skip qtlocation -skip qtmacextras -skip qtmultimedia -skip qtnetworkauth -skip qtpurchasing -skip qtquickcontrols -skip qtquickcontrols2 -skip qtscript -skip qtscxml -skip qtsensors -skip qtserialbus -skip qtserialport -skip qtspeech -skip qtsvg -skip qttools -skip qttranslations -skip qtvirtualkeyboard -skip qtwayland -skip qtwebchannel -skip qtwebengine -skip qtwebsockets -skip qtwebview -skip qtwinextras -skip qtx11extras -skip qtxmlpatterns -no-feature-texthtmlparser -no-feature-textodfwriter -no-feature-concurrent -no-feature-effects -no-feature-sharedmemory -no-feature-systemsemaphore -no-feature-im -no-feature-process -no-feature-dom -no-feature-filesystemmodel -no-feature-filesystemwatcher -no-feature-graphicsview -no-feature-graphicseffect -no-feature-sizegrip -no-feature-calendarwidget -no-feature-printpreviewwidget -no-feature-keysequenceedit -no-feature-colordialog -no-feature-filedialog -no-feature-fontdialog -no-feature-printpreviewdialog -no-feature-progressdialog -no-feature-inputdialog -no-feature-errormessage -no-feature-wizard -no-feature-datawidgetmapper -no-feature-imageformat_bmp -no-feature-imageformat_ppm -no-feature-imageformat_xbm -no-feature-imageformat_png -no-feature-imageformat_jpeg -no-feature-image_heuristic_mask -no-feature-image_text -no-feature-colornames -no-feature-cups -no-feature-paint_debug -no-feature-freetype -no-feature-translation -no-feature-codecs -no-feature-big_codecs -no-feature-iconv -no-feature-ftp -no-feature-udpsocket -no-feature-networkproxy -no-feature-socks5 -no-feature-networkdiskcache -no-feature-bearermanagement -no-feature-completer -no-feature-fscompleter -no-feature-desktopservices -no-feature-mimetype -no-feature-systemtrayicon -no-feature-undocommand -no-feature-undostack -no-feature-undogroup -no-feature-undoview -no-feature-statemachine -no-feature-gestures -no-feature-dbus
感觉去掉的东西还不是很多,主要是去掉后各种报错,以后新版本再跟进下。
至于效果,我们主要看core、gui和widgets。
我使用的版本是Windows下,MinGW,5.8.0,开源版
在原版中,静态编译后,分别是
在使用QtLite,静态编译后,分别是
可见体积的确缩小了。
接下来试下QtWidgets工程,我使用QtCreator创建一个默认的工程,然后放进去一个HelloQtLite字样的QLabel。
编译出来的exe:
原版 + 静态编译:
QtLite + 静态编译:
16MB缩减到11MB,体积还是很可观的缩小了
再rar压缩一下:
看来QtLite配合静态编译还有rar压缩,简单的QtWidgets程序可以缩减到4MB以内,很给力。
最后,都丢到一个纯净的Win7,正常运行
对了,因为有人提到过Qt模块划分的问题,我也去看了下,在我使用的源码里,Qt一共有38个大分组,比如说qtbase,qt3d等等。QtLite目前主要优化了qtbase这一个分组,也是最常用的一个。不使用QtLite的情况下,全部编译完成后,一共会得到60个库。这一次我编译后,通过skip(跳过编译),还有QtLite,一共可以去掉42个库,剩下18个。
最后,要我评价QtLite的话,我认为是: 这是一个很好的功能,因为在这个功能上我们可以以很低的使用成本裁剪Qt,甚至不需要直接接触到代码。允许开发者们定制自己想要的模块,抛弃不必要的功能。 这在嵌入式上会有较大的意义,QtLite应该也是主要给嵌入式开发的特性。 在桌面上我觉得意义有限,但是的确很多人会去纠结这个体积问题。 另外,作为第一个拥有QtLite的Qt版本,也就是5.8,固然存在一些问题,希望Qt能在将来的版本中解决。或者允许去除更多模块,进一步缩减体积。 PS:其实官方有一个小工具的,叫Qt Configuration Tool。就是QtLite可视化配置工具。 http://doc.qt.io/QtEnterpriseEmbedded/qt-configuration-tool.html 不过我没找到如何下载的地方,看URL链接,我猜测是只有嵌入式设备授权的的Qt企业版,才有这个工具。残念ing。。。
PS2:知乎你能不能别这么坑,图片怎么动不动就挂掉,我已经重新恢复2次了