红联Linux门户
Linux帮助

利用ubuntu-app-platform提供的platform接口来减小Qt应用大小

发布时间:2016-11-24 15:07:23来源:Ubuntu手机作者:Ubuntu手机
不知道大家是否先前试过我的一个Qt的应用"如何把一个qmake的Ubuntu手机应用打包为一个snap应用"(http://www.linuxdiyf.com/linux/22344.html).在那个教程中,我们尝试把所有的Ubuntu SDK库包ubuntu-sdk-libs 都打入到我们的应用中,结果是我们的snap包的文件非常大.几乎达到800M-900M.显然这样的应用不具有实用性.我也尝试只把我们最需要的Qt库打入到我们的snap包中.你们可以发现我更新后的代码.即使是这样的,我们最终形成的包的大小也达到120M左右.显然,这也不是一个小的文件.那么我们有什么办法可以使得我们的Qt应用的包变得更小呢?
答案是我们使用canonical公司所提供的ubuntu-app-platform snap应用.这个应用把我们最需要的Qt库打入到我们的snap应用中,并通过content sharing的方法把ubuntu-app-platform中的Qt库文件mount到我们的应用中,从而使得我们的Qt应用能够使用ubuntu-app-platform所提供的所有Qt库.这样我们的所有的在一个Ubuntu Core系统的所有的snap应用都可以共享同一份Qt库,从而达到减少我们snap应用大小的目的.
在下面,我们来详细介绍如何利用content interface来实现这个目的.
 
1)安装
首先,对于英文比较好的开发者来说,我们可以在如下的地址找到我们所需要的信息:
https://developer.ubuntu.com/en/blog/2016/11/16/snapping-qt-apps/
就像在那篇文章中介绍的那样,我们在我们的Ubuntu 16.04 Desktop中,必须安装stabe-phone-overlay以确保我们的Qt版本是Qt 5.6.1的.否则我们有些Qt应用的打包会有文件.我们可以通过如下的方式来检查我们的Qt版本:
liuxg@liuxg:~$ qmake --version  
QMake version 3.0  
Using Qt version 5.6.1 in /usr/lib/x86_64-linux-gnu
 
为什么需要把我们的Qt版本安装为5.6.1版本呢?细心的开发者,可以发现在ubuntu-app-platform的链接中,它表明该snap是基于Qt 5.6.1的版本的.先前在我的电脑上安装的Qt 版本为Qt 5.5.1.当我用该版本打包我的Qt应用时,在运行时会出现一个错误
我们按照如下的步骤来安装我们的Qt 5.6.1版本:
$ sudo add-apt-repository ppa:ci-train-ppa-service/stable-phone-overlay  
$ sudo apt-get update  
$ sudo apt-get upgrade  
$ sudo apt-get dist-upgrade 
在执行完上面的命令后,我们再次确认我们的Qt版本信息是否为5.6.1.这一步的安装非常中,不正确的Qt版本可能使得有些Qt应用运行正常,但有些可能会出错.
 
2)利用ubuntu-app-platform来重构Qt应用
我们先前的rssreader Ubuntu Phone应用的源码可以在地址找到:
 
snapcraft.yaml
name: rssreader-app  
version: "1.0"  
summary: A snap app from Ubuntu phone app  
description: This is an exmaple showing how to convert a Ubuntu phone app to a desktop snap app  
confinement: strict # devmode  
apps:  
rssreader:  
command: desktop-launch $SNAP/lib/x86_64-linux-gnu/bin/rssreader  
plugs: [network,network-bind,network-manager,home,unity7,opengl]  
parts:  
rssreader:  
source: src/  
plugin: qmake  
qt-version: qt5  
build-packages:  
- cmake  
- gettext  
- intltool  
- ubuntu-touch-sounds  
- suru-icon-theme  
- qml-module-qttest  
- qml-module-qtsysteminfo  
- qml-module-qt-labs-settings  
- qtdeclarative5-u1db1.0  
- qtdeclarative5-qtmultimedia-plugin  
- qtdeclarative5-qtpositioning-plugin  
- qtdeclarative5-ubuntu-content1  
- qt5-default  
- qtbase5-dev  
- qtdeclarative5-dev  
- qtdeclarative5-dev-tools  
- qtdeclarative5-folderlistmodel-plugin  
- qtdeclarative5-ubuntu-ui-toolkit-plugin  
- xvfb  
stage-packages:  
- libsdl2-2.0-0  
- libqt5gui5  
- libqt5qml5  
- libqt5quick5  
- libqt5widgets5  
- libqt5network5  
- libqt5multimedia5  
- libqt5declarative5  
- qml-module-qtquick2  
- qml-module-qtquick-window2  
- qml-module-qtquick-layouts  
- qml-module-qtquick-controls  
- qml-module-qt-labs-settings  
- qml-module-ubuntu-components  
- qml-module-qtquick-xmllistmodel  
- ubuntu-ui-toolkit-theme  
- qml-module-ubuntu-connectivity  
- qml-module-ubuntu-layouts  
- qml-module-ubuntu-performancemetrics  
- fonts-wqy-zenhei  
- fcitx-frontend-qt5  
snap:  
- -usr/share/doc  
- -usr/include  
after: [desktop/qt5]
 
显然在上面的snapcraft.yaml中,我们把太多的Qt库打入到我们的snap包中.其结果就是大大增加了我们的snap包的大小.为了能够利用ubuntu-app-platform所提供的platform interface,我们把我们的应用的snapcraft.yaml修改为:
 
snapcraft.yaml
name: rssreader-app  
version: "1.0"  
summary: A snap app from Ubuntu phone app  
description: This is an exmaple showing how to convert a Ubuntu phone app to a desktop snap app  
confinement: strict # devmode  
apps:  
rssreader:  
command: desktop-launch $SNAP/lib/x86_64-linux-gnu/bin/rssreader  
plugs: [network,network-bind,network-manager,home,unity7,opengl,platform]  
parts:  
rssreader:  
source: src/  
plugin: qmake  
qt-version: qt5  
snap:  
- -usr/share/doc  
- -usr/include  
after: [desktop-ubuntu-app-platform]  
plat:  
plugin: dump  
source: .  
snap: [ubuntu-app-platform]  
plugs:  
platform: # plug name, to be used later  
interface: content  
content: ubuntu-app-platform1 # content being mounted and the version, currently 1  
target: ubuntu-app-platform # the mount directory created  
default-provider: ubuntu-app-platform # default content source snap, currently the only provider too
 
从上面的新的snapcraft.yaml文件中,我们可以看出来:我们把stage-packages里所有的相关的debian包都已经删除了,取而代之的是在我们的应用中加入了platform这个plug.在我们的应用中,我们也定义了我们的platform plug interface.另外,我们值得指出的是,我们在我们的应用的根目录下创建了一个空的ubuntu-app-platform目录.这个目录的作用是被platform interface作为mount点从而把Qt库分享给我们的应用.如果没有这个空的文件目录,在运行我们的Qt应用时会出错.整个项目的文件结果如下:
liuxg@liuxg:~/snappy/desktop/rssreader_platform$ tree -L 2  
.  
├── setup  
│   └── gui  
├── snapcraft.yaml  
├── src  
│   ├── manifest.json.in  
│   ├── po  
│   ├── rssreader  
│   └── rssreader.pro  
└── ubuntu-app-platform
在确保我们的项目完成后,我们在项目的根目录下打入如下的命令:
$ snapcraft  
这样就会在当前的目录下生产我们想要的.snap文件包.我们来重新查看一下我们所生产的snap包的大小:
利用ubuntu-app-platform提供的platform接口来减小Qt应用大小
 
显然我们的snap包的文件大小只有18M,比我们先前的120M要小好多.细心的开发者可能已经发现所有的Qt库文件.它包含了我们运行一个Qt应用最基本的库:
liuxg@liuxg:~/snappy/desktop/rssreader_platform/prime/usr/lib/x86_64-linux-gnu$ l
libdouble-conversion.so.1  libpcre16.so.3  libX11-xcb.so.1  libXdamage.so.1
libdrm.so.2  libproxy.so.1  libXau.so.6  libXdmcp.so.6
libglapi.so.0  libQt5Core.so.5  libxcb-dri2.so.0  libXext.so.6
libgraphite2.so.3  libQt5Gui.so.5  libxcb-dri3.so.0  libXfixes.so.3
libharfbuzz.so.0  libQt5Network.so.5  libxcb-glx.so.0  libxshmfence.so.1
libicudata.so.55  libQt5Qml.so.5  libxcb-present.so.0  libXxf86vm.so.1
libicui18n.so.55  libQt5Quick.so.5  libxcb.so.1  mesa/
libicuuc.so.55  libX11.so.6  libxcb-sync.so.1  
 
我们可以按照如下的方式进行安装:
liuxg@liuxg:~/snappy/desktop/rssreader_platform$ sudo snap install rssreader-app_1.0_amd64.snap --dangerous  
rssreader-app 1.0 installed  
 
当我们尝试第一次运行我们的应用时,我们可以看到如下的信息:
liuxg@liuxg:~/snappy/desktop/rssreader_platform$ rssreader-app.rssreader   
You need to connect the ubuntu-app-platform package with your application   
to reuse shared assets, please run:  
snap install ubuntu-app-platform  
snap connect rssreader-app:platform ubuntu-app-platform:platform  
 
显然,它是提示我们需要安装相应的ubuntu-app-platform snap应用:
liuxg@liuxg:~$ sudo snap install ubuntu-app-platform  
ubuntu-app-platform (stable) 1 from 'canonical' installed  
liuxg@liuxg:~$ sudo snap connect rssreader-app:platform ubuntu-app-platform:platform  
 
至此,我们已经把我们的应用的platform plug和ubuntu-app-platform的platform slot进行了手动连接.我们可以通过如下的命令来查看:
利用ubuntu-app-platform提供的platform接口来减小Qt应用大小
 
在我们的命令行中执行如下的命令:
liuxg@liuxg:~/snappy/desktop/rssreader_platform$ rssreader-app.rssreader   
You need to connect the ubuntu-app-platform package with your application   
to reuse shared assets, please run:  
snap install ubuntu-app-platform  
snap connect rssreader-app:platform ubuntu-app-platform:platform  
 
显然我们的应用在执行时遇到了问题.它并没有启动我们的应用,而是显示和我们上面同样的信息.这是由于一个我们在目前snapd版本中设计的bug所致.我们目前可以通过如下的方法来消除这个问题.
$ sudo /usr/lib/snapd/snap-discard-ns rssreader-app  
 
我们可以再重新安装我们的应用.在没有connect之前,不要运行我们的应用!如果你已经运行了,那么请执行上面的命令来删除name space,然后再重新安装,connect,再最后运行我们的应用:
$ rssreader-app.rssreader  
利用ubuntu-app-platform提供的platform接口来减小Qt应用大小
 
整个应用的源码可以在地址找到:https://github.com/liu-xiao-guo/rssreader_platform
更多例程:https://code.launchpad.net/~tpeeters/+junk/blog-snapping-qt-apps
 
本文永久更新地址:http://www.linuxdiyf.com/linux/26295.html