参考文档
- Qt5.9.6源代码下载地址
- Qt5.9.6源代码百度云下载链接
- Qt官方编译指南
- Qt for Embedded Linux
开发环境介绍
- 主机操作系统:Ubuntu16.04 64位
- 目标平台:IMX.6
- 交叉工具链:arm-poky-linux-gnueabi,gcc4.8.2
- Qt版本:5.9.6
- 编译时间:2018.7.7
提示:较新版本的Qt使用了C++11语法,所以必须使用gcc4.8.0及以上版本
配置交叉编译工具链
# 在/etc/bash.bashrc的最后增加如下指令
# Native Compiler
export AR_host="ar"
export CC_host="gcc"
export CXX_host="g++"
export LINK_host="g++"
# freescale imx.6 cross compiler, BoxV1
export ARCH=arm
export PATH=/opt/zhaozhongxiang/hwzt_yc_3.10.53/build-x11/tmp/sysroots/x86_64-linux/usr/bin/cortexa9hf-vfp-neon-poky-linux-gnueabi/:$PATH
# 修改完成之后需要重启命令行才能生效
配置编译环境
将sysroot拷贝到 /opt/zhaozhongxiang/hwzt_yc_3.10.53/build-x11/tmp/sysroots
,因为Qt的依赖库比较多,所以建议针对目标器件建立sysroot目录,这里imx.6使用Ycoto生成的sysroot。如果sysroot过于精简,在执行配置脚本可能会出现依赖库缺失的情况,需要自己单独编译依赖库然后拷贝到sysroot目录,本文档将不单独介绍这部分内容。
另外需要着重注意sysroot对应的imx6qsabresd目录下存在之前编译的旧Qt版本的动态库,必须进行清除操作,否则将会影响新版本Qt的编译。
cd /opt/zhaozhongxiang/hwzt_yc_3.10.53/build-x11/tmp/sysroots/imx6qsabresd
sudo rm ./usr/lib/libQt* -rf
sudo rm ./usr/lib/qt5 -rf
安装系统依赖软件
因为编译环境涉及到使用64位Ubuntu操作系统交叉编译32位应用程序,所以需要另外安装一些依赖库。
sudo apt-get install gperf bison
sudo apt-get install ninja-build
sudo apt-get install libc6-dev-i386
针对Ubuntu16.04 64位操作系统:
sudo apt-get install gcc-multilib g++-multilib
针对Ubuntu14.04 64位操作系统:
sudo apt-get install gcc-4.8-multilib g++-4.8-multilib
创建配置脚本
在Qt源代码根目录创建build_configure.sh,内容如下:
#!/bin/bash
# configure bash for qt5.9.6
./configure -v \
-opensource -confirm-license \
-sysroot /opt/zhaozhongxiang/hwzt_yc_3.10.53/build-x11/tmp/sysroots/imx6qsabresd \
-no-gcc-sysroot \
-prefix /usr/local/Qt-5.9.6 \
-device linux-imx6-g++ \
-device-option CROSS_COMPILE=/opt/zhaozhongxiang/hwzt_yc_3.10.53/build-x11/tmp/sysroots/x86_64-linux/usr/bin/cortexa9hf-vfp-neon-poky-linux-gnueabi/arm-poky-linux-gnueabi- \
-release -shared -make libs -verbose \
-no-pch \
-no-rpath -pkg-config -accessibility -no-alsa -icu -dbus -no-glib \
-no-directfb -eglfs -no-kms -linuxfb -xcb -xcb-xlib \
-evdev -no-libinput -xinput2 -no-tslib -libudev -no-mtdev \
-nomake examples -nomake tests \
-fontconfig \
-no-opengl -opengl es2 -egl -no-openvg \
-system-zlib -system-libjpeg -system-libpng -system-xcb \
-openssl-linked -qt-pcre -pulseaudio -no-sm \
-no-sql-db2 -no-sql-ibase -no-sql-mysql -no-sql-oci -no-sql-odbc -no-sql-psql -no-sql-sqlite2 -no-sql-tds \
-widgets -xkb
上述备注主要涉及到(按顺序):
- -sysroot:目标文件系统,编译器会从这个目录寻找依赖库的头文件和库文件
- -device:根据实际目标器件来填写,Qt支持的器件从
qtbase/mkspecs/devices
目录寻找 - -device-option:配置编译器选项,这里配置了CROSS_COMPILE变量
- -release:编译类型,支持-release、-debug,可以根据实际情况填写
- -shared:库类型,将决定最终的Qt库的类型,支持-shared、-static
- -verbose:显示编译时的打印信息
- -eglfs:QPA平台编译开启,可以通过-no-eglfs关闭这个QPA,对于嵌入式设备的Qt webEngine必须使用eglfs平台渲染,否则会出现Web页面黑屏
- -linuxfb:QPA平台编译开启,可以通过-no-linuxfb关闭这个QPA
- -xcb:QPA平台编译开启,可以通过-no-xcb关闭这个QPA
- -libudev:使用输入设备自动发现库
- -nomake examples:建议关闭示例程序的编译
- -nomake tests:建议关闭单元测试程序的编译
- -opengl es2:开启opengl es2,对于嵌入式设备一定要开启这个设置
- -egl:对于eglfs平台,一定要开启这个设置
提示:QPA:即QT平台抽象层,具体解释见参考文档4
通过configure脚本只是开启对各个QPA平台的校验,不意味成已经开启相应平台的支持,具体是否校验成功需要查看configure脚本最终打印的输出列表信息,如下图所示:
从上图可以看到EGLFS i.Mx6的支持并没有开启,原因为sysroot中的EGL依赖库不是GPU版本,必须使用官方提供的GPU版本,将如下依赖库进行替换:
另外在重新配置之前需要再替换一些动态库:
提示:上述动态库可以通过这里下载(下载地址)
重新执行build_configure.sh
rm config.cache
./build_configure.sh
提示:这里必须先清除config.cache才能重新进行一次配置检测,否则配置不会更新,更新之后的QPA信息如下图:
修复Qt WebEngine Bug
在进行原始版本的Qt-5.9.6实际Webengine页面测试时发现html中的select
元素(即下拉菜单)的位置会偏移到屏幕的左上角。如果应用程序需要使用Webengine模块建议按照下面的步骤修复这个Bug。
修改 qtbase/src/widgets/kernel/qwidgetbackingstore.cpp
文件中的 findTextureWidgetsRecursively
函数:
// 修改
if (wd->renderToTexture) {
QPlatformTextureList::Flags flags = 0;
if (widget->testAttribute(Qt::WA_AlwaysStackOnTop))
flags |= QPlatformTextureList::StacksOnTop;
const QRect rect(widget->mapTo(tlw, QPoint()), widget->size());
widgetTextures->appendTexture(widget, wd->textureId(), rect, wd->clipRect(), flags);
}
// 为
if (wd->renderToTexture) {
QPlatformTextureList::Flags flags = 0;
if (widget->testAttribute(Qt::WA_AlwaysStackOnTop))
flags |= QPlatformTextureList::StacksOnTop;
if ((widget->windowFlags() & Qt::WindowType_Mask) == Qt::ToolTip) {
const QRect rect(widget->pos(), widget->size());
widgetTextures->appendTexture(widget, wd->textureId(), rect, wd->clipRect(), flags);
} else {
const QRect rect(widget->mapTo(tlw, QPoint()), widget->size());
widgetTextures->appendTexture(widget, wd->textureId(), rect, wd->clipRect(), flags);
}
}
编译&安装
make -j8
make install
编译和安装正常完成之后会生成sysroot
下的usr/local/Qt-5.9.6
目录