使用 Ubuntu AMD64 平台交叉编译适用于 Linux ARM64 平台的 QT5(包含 OpenGL/WebEngine 支持) 库
目录
- 使用 Ubuntu AMD64 平台交叉编译适用于 Linux ARM64 平台的 QT5(包含 OpenGL/WebEngine 支持) 库
- 写在前面
- 前期准备
- 编译全流程
- 1. 环境搭建
- 2. 复制源码包并解压,创建文件目录
- 3. 编辑配置
- 4. 开始编译,安装
- 常见问题及解决办法
- 附录
- Ubuntu 系统中使用 QEMU 安装 ARM 虚拟机的方法
写在前面
如果你的项目目标平台为 ARM 指令集的 Linux 系统且需要用到 QT 库,可惜 QT 官方并未提供对应已编译完成的二进制版本库文件,这时我们只能自己下载 QT 源码自行编译。如果你手上没有 ARM 平台的设备,而 ARM 虚拟机的创建也不是很方便,这时需要使用交叉编译工具进行跨平台编译。由于 QT 库的庞大,整个编译过程可谓是相当的曲折,本文为我通过各种渠道查找资料解决问题最终实现编译的经验整理,如有错误请在评论区指出。
本文适用以下情况:
- 编译平台为 Ubuntu AMD64(也称 x86_64 其他 Linux 系统应该也行)
- 目标平台为 Linux ARM64
- QT 库版本为 5.12.11(其他版本没有测试过)
- 使用交叉编译工具进行跨平台编译
前期准备
一. 编译平台搭建
我使用的是 Ubuntu VMWare 虚拟机,版本为 Ubuntu 22.04.4 LTS,搭建过程本文不赘述。
二. 下载 QT 源码包
官网下载地址:https://download.qt.io/archive/qt/ (可能需要梯子)
【选择版本】 >> 【进入 single/ 目录】 >> 【点击 qt-everywhere-src-5.12.11.tar.xz 开始下载】
三. 准备目标平台的 OpenGL 支持库
注意这里需要的是目标平台的 OpenGL 库,而不是编译平台的,可以在网上下载别人编译好的,或者搭建目标平台的虚拟机安装后复制出来,步骤参考本文附录。
编译全流程
1. 环境搭建
安装编译所需的依赖环境 参考链接:
基础环境:
sudo apt-get install libxcb-xinerama0-dev build-essential perl git python2
交叉工具链:
sudo apt-get install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
Libxcb:
sudo apt-get install '^libxcb.*-dev' libx11-xcb-dev libxrender-dev libxi-dev libxkbcommon-dev libxkbcommon-x11-dev
OpenGL:
sudo apt-get install libgl1-mesa-dev libglu1-mesa-dev libegl1-mesa-dev libgles2-mesa-dev freeglut3-dev
以下环境根据需求安装:
Qt WebKit 依赖
sudo apt-get install flex bison gperf libicu-dev libxslt-dev ruby
Qt WebEngine 依赖
sudo apt-get install libssl-dev libxcursor-dev libxcomposite-dev libxdamage-dev libxrandr-dev libdbus-1-dev libfontconfig1-dev libcap-dev libxtst-dev libpulse-dev libudev-dev libpci-dev libnss3-dev libasound2-dev libxss-dev libegl1-mesa-dev gperf bison
Qt Multimedia 依赖
sudo apt-get install libasound2-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
QDoc Documentation Generator Tool 依赖
sudo apt-get install clang libclang-dev llvm
安装好的 Python2 其控制台指令为 python2,QT 需要识别的指令为 python,所以需要创建一个指向 python2 的软链接
sudo ln -s /usr/bin/python2 /usr/bin/python
2. 复制源码包并解压,创建文件目录
复制下载好的 QT 源码包到编译平台,新建两个文件夹,src
用于存放解压后的 QT 源码,qt_5.12.11
用于存放最终生成的库文件。
将源码包解压到 src
目录
将 Linux ARM64 版本的 OpenGL 库添加到本地路径备用。我这里选择 ~/env/opengl_arm64
,内含两个文件夹,include
用于放头文件 lib
用于放库文件。这里的 ~
表示用户主目录,也就是 /home/<username>
对应的目录,后续在配置中涉及到填写该目录的情况一律采用 /home/<username>
的形式,不要使用 ~
否则会出错。
经过我的测试,直接解压出的源码包在编译时会报错 error:'numeric_limits' is not a member of 'std'
原因是缺少一个头文件包含,找到以下几个头文件,在其中添加 #include <limits>
即可。
src/qtbase/src/corelib/global/qendian.h
src/qtbase/src/corelib/tools/qbytearraymatcher.h
src/qtbase/src/tools/moc/generator.h
src/qtdeclarative/src/qml/jsruntime/qv4propertykey_p.h
src/qtdeclarative/src/qmldebug/qqmlprofilerevent_p.h
3. 编辑配置
进入源码目录下的 qtbase/mkspecs/linux-aarch64-gnu-g++
,编辑 qmake.conf
文件。这里 linux-aarch64-gnu-g++
文件夹对应 Linux ARM64 平台的编译配置。在图示位置新增以下内容(由于头文件不分平台且本机也安装了 OpenGL 环境,所以可以直接 /usr/include/xxx
作为头文件路径):
QMAKE_INCDIR_OPENGL_ES2 = /usr/include/GLES2
QMAKE_LIBDIR_OPENGL_ES2 = /home/neko/env/opengl_arm64/lib
QMAKE_INCDIR_EGL = /usr/include/GEL
QMAKE_LIBDIR_EGL = /home/neko/env/opengl_arm64/lib
QMAKE_LIBS_EGL += -lEGL -lGLESv2
QMAKE_LIBS_OPENGL_ES2 += -lGLESv2 -lEGL
回到源码目录,使用 touch autoconfig.sh
命令新建自动配置脚本。编辑脚本写入如下内容:
./configure -prefix ~/workspace/compile/qt_5.12.11 \
-opensource \
-confirm-license \
-release \
-strip \
-shared \
-xplatform linux-aarch64-gnu-g++ \
-optimized-qmake \
-c++std c++11 \
-pch \
-linuxfb \
-make libs \
-nomake examples \
-nomake tests \
-gui \
-widgets \
-dbus-runtime \
--rpath=no \
--glib=no \
--xcb=no \
-iconv \
--pcre=qt \
--zlib=qt \
--freetype=qt \
--harfbuzz=qt \
--libpng=qt \
--libjpeg=qt \
--sqlite=qt \
-opengl es2 \
-plugin-sql-sqlite \
-recheck-all
脚本内容说明:
./configure -prefix ~/workspace/compile/qt_5.12.11 \ # 指定最终生成目录,就是前面创建的 qt_5.12.11
-opensource \ # 指定编译开源版本
-confirm-license \ # 确认许可证,同意使用条款
-release \ # 指定编译 Release 版本
-strip \ # 去掉生成的二进制文件中的符号表,以减小文件大小
-shared \ # 生成共享库(动态链接库)
-xplatform linux-aarch64-gnu-g++ \ # 使用 Linux ARM64 对应的平台配置
-optimized-qmake \ # 生成优化过的 qmake 工具
-c++std c++11 \ # 使用 C++11 标准进行编译
-pch \ # 使用预编译头,提高编译速度
-linuxfb \ # 启用 Linux framebuffer 支持,用于在没有 X11 的环境中直接在 framebuffer 上绘制图形
-make libs \ # 编译库文件
-nomake examples \ # 不编译示例程序
-nomake tests \ # 不编译测试程序
-gui \ # 包含 GUI 模块
-widgets \ # 包含 Widgets 模块
-dbus-runtime \ # 启用 D-Bus 支持,使用运行时检测
--rpath=no \ # 禁用 RPATH,支持通过手动设置 LD_LIBRARY_PATH 解决库查找问题
--glib=no \ # 禁用 GLib 支持
--xcb=no \ # 禁用 XCB(X C Binding)支持
-iconv \ # 启用 iconv 库支持,iconv 用于字符编码转换
--pcre=qt \ # 使用 Qt 自带的 PCRE 库
--zlib=qt \ # 使用 Qt 自带的 Zlib 库
--freetype=qt \ # 使用 Qt 自带的 FreeType 库
--harfbuzz=qt \ # 使用 Qt 自带的 HarfBuzz 库
--libpng=qt \ # 使用 Qt 自带的 libpng 库
--libjpeg=qt \ # 使用 Qt 自带的 libjpeg 库
--sqlite=qt \ # 使用 Qt 自带的 SQLite 库
-opengl es2 \ # 使用 OpenGL ES 2.0 进行图形渲染
-plugin-sql-sqlite \ # 启用 SQLite SQL 插件支持
-recheck-all # 重新检查所有配置选项,确保其正确无误
使用 chmod +x ./autoconfig.sh
赋予该脚本文件执行权限,使用 ./autoconfig.sh
运行该文件,等待构建结束。
该过程会检查环境支持情况以及配置是否正确等,结束时正常情况应该和下图显示的一致,没有 Error,如有问题请参照下面的常见问题解决办法处理,若遇到新的其他问题请在评论区指出。
4. 开始编译,安装
控制台当前目录处于源码目录,输入 gmake
开始编译,编译过程很漫长,受限于机器性能,可能长达数小时。可以使用 gmake -j4
使用4线程或更多线程进行编译以提升速度,但是出错后不好定位。
前面建立了 Python 软链接并且修改了缺少 #include <limits>
的头文件,编译过程应该不会出问题了,我这里是这样。
等待编译结束后,输入 gmake install
在指定的 qt_5.12.11
文件夹里生成库文件和其他工具等。
常见问题及解决办法
① WARNING: Python version 2 (2.7.5 or later) is required to build QtWebEngine.
sudo apt-get install python2
② ERROR: Feature ‘opengles2’ was enabled, but the pre-condition ‘config.win32 || (!config.watchos && !features.opengl-desktop && libs.opengl_es2)’ failed.
ERROR: The OpenGL functionality tests failed!
查看步骤【3. 编辑配置】
检查是否修改了对应目标平台的 qmake.conf 文件;文件设置的路径是否正确;路径中的库文件是否为目标平台的库文件
可使用 readelf -h filename 查看文件架构信息
③ 编译报错:error:‘numeric_limits’ is not a member of ‘std’
参照步骤【2. 复制源码包并解压,创建文件目录】,在报错的头文件中添加 #include <limits> 包含命令
附录
Ubuntu 系统中使用 QEMU 安装 ARM 虚拟机的方法
// TODO: 待完善