使用 Ubuntu x86_64 平台交叉编译适用于 Linux aarch64(arm64) 平台的 QT5(包含OpenGL/WebEngine支持) 库

news2024/7/2 2:20:35

使用 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 库的庞大,整个编译过程可谓是相当的曲折,本文为我通过各种渠道查找资料解决问题最终实现编译的经验整理,如有错误请在评论区指出。

本文适用以下情况:

  1. 编译平台为 Ubuntu AMD64(也称 x86_64 其他 Linux 系统应该也行)
  2. 目标平台为 Linux ARM64
  3. QT 库版本为 5.12.11(其他版本没有测试过)
  4. 使用交叉编译工具进行跨平台编译

前期准备

一. 编译平台搭建
我使用的是 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: 待完善

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1877544.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

信息就像糖,让人上瘾

今天阅读阮一峰的科技爱好者周刊&#xff0c;其中提到一个观点「信息就像糖&#xff0c;让人上瘾」&#xff0c;让人印象深&#xff0c;糖之所以上瘾&#xff0c;是因为会让人增加多巴胺的分泌&#xff0c;让人成瘾。而研究表明&#xff0c;信息上瘾跟糖上瘾一样&#xff0c;信…

Golang | Leetcode Golang题解之第198题打家劫舍

题目&#xff1a; 题解&#xff1a; func rob(nums []int) int {if len(nums) 0 {return 0}if len(nums) 1 {return nums[0]}first : nums[0]second : max(nums[0], nums[1])for i : 2; i < len(nums); i {first, second second, max(first nums[i], second)}return se…

保姆教程教你如何使用数据集运行ORB-SLAM3

链接: 自学SLAM&#xff08;2&#xff09;—保姆教程教你如何使用自己的视频运行ORB-SLAM2 这篇文章是详细教怎么运行ORB-SLAM2的&#xff0c;那么下来我们就看看怎么运行ORB-SLAM3 理论上ORB-SLAM2的环境也是可以跑ORB-SLAM3的&#xff0c;因为我之前试过&#xff0c;编译成功…

力扣300. 最长递增子序列(动态规划)

Problem: 300. 最长递增子序列 文章目录 题目描述思路及解法复杂度Code 题目描述 思路及解法 明确题目涉及到求取最值问题因此我们可以考虑使用动态规划来解决问题 1.定义状态&#xff1a;定义int类型的dp数组表示以nums[i]结尾的序列的最长长度&#xff0c;初始化均为1即表示…

spring mvc实现自定义验证器Validator

使用场景 在接口开发的日常实践中&#xff0c;确保数据准确性是保障业务稳定性的关键一环。面对诸如登录时验证用户名密码非空、创建用户时检查邮箱和手机号格式的正确性等需求&#xff0c;手动编写校验逻辑不仅耗时费力&#xff0c;还会显著降低代码的可读性和维护性。鉴于网…

[OtterCTF 2018]Graphic‘s For The Weak

恶意软件的图形中有些可疑之处。 软件图形 &#xff1f;&#xff1f;&#xff1f;这里的恶意文件都是 vmware-tray.ex使用procdump转存进程的可执行文件 &#xff08;可执行的&#xff09;导出了 &#xff0c;看文件里面是否存在 图片 volatility.exe -f .\OtterCTF.vmem --pro…

springboot+vue+mybatis奶茶管理系统+PPT+论文+讲解+售后

由于科学技术的快速发展&#xff0c;人们的生活也与信息时代的发展相关。同时&#xff0c;随着市场化和经济化的发展&#xff0c;国内很多行业已经意识到了这一点&#xff0c;为了提升行业的竞争力&#xff0c;就应当率先把握机会。于是在互联网的默化潜移影响下&#xff0c;餐…

QT4-QT5(6)-const char* QString 乱码转换

我简单粗暴的给出个结论&#xff1a; QString GBK编码正常&#xff0c;可以转UTF-8编码&#xff0c;但会有少量乱码。 const char* 编码就不要转编码&#xff0c;转哪个都是乱码。 UTF-8.cpp 下 1.QString GBK->UTF-8 2.const char * GBK->UTF-8 const char *…

了解WPF控件:OpenFileDialog常用属性与用法(十六)

掌握WPF控件&#xff1a;熟练OpenFileDialog常用属性&#xff08;十六&#xff09; OpenFileDialog控件在WPF中用于需要用户指定文件路径&#xff0c;为用户提供了一个直观且易用的界面来浏览和选择本地文件系统中的文件。例如&#xff0c;当用户需要打开一个已存在的文本文件…

【python012】Python根据页码处理PDF文件的内容

在日常工作和学习中&#xff0c;需要从PDF文件中提取特定页面的内容&#xff0c;以便进行知识、材料压缩等。 2.欢迎点赞、关注、批评、指正&#xff0c;互三走起来&#xff0c;小手动起来&#xff01; 3.欢迎点赞、关注、批评、指正&#xff0c;互三走起来&#xff0c;小手动起…

phpstorm2024代码总是提示“no usages”或者“无用法”解决办法

问题&#xff1a;phpstorm2024使用时&#xff0c;总是会提示无用法&#xff0c;如果没有安装中文语言包的情况下会提示&#xff1a;no usages&#xff0c;如果想关闭怎么办&#xff1f; 编译器右上角点击齿轮进入设置&#xff0c;按照下图的方法点击即可关闭。或者在编译器的“…

GaussDB关键技术原理:高性能(二)

GaussDB关键技术原理&#xff1a;高性能&#xff08;一&#xff09;从数据库性能优化系统概述对GaussDB的高性能技术进行了解读&#xff0c;本篇将从查询处理综述方面继续分享GaussDB的高性能技术的精彩内容。 2 查询处理综述 内容概要&#xff1a;本章节介绍查询端到端处理的…

24/06/24(12.1117)指针进阶 ,冒泡和快排 习题为依托巩固概念(strlen,sizeof,字符串,数组,指针大小的区别)

回调函数 回过头来调用的函数 #include <stdio.h> #include <stdlib.h> int Find_Max(int arr[], int n){ int max_value arr[0]; for (int i 1; i < n; i){ if (max_value < arr[i]) max_value arr[i]; } return…

工业自动化控制中心

目录 一 设计原型 二 后台源码 一 设计原型 二 后台源码 using System; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms;namespace 工业自动化控制中心 {public partial class Form1 : Form{public Form1(){InitializeComponent();}pri…

2SK241 LTSpice模型及仿真

2SK241是东芝生产的一款NMOS&#xff0c;早已停产&#xff0c;但是在收音机圈子里还是有很多死忠粉&#xff0c;所以在淘宝上也是一堆打磨改标的假货。 言归正传&#xff0c;在矿坛上找到了2SK241的模型&#xff1a; .model M2SK241bottom NMOS(Level1 Rd1 Rs10 Rg50 Kp8mV…

Linux源码-进程描述符

Linux操作系统引入了PCB(Process Control Block,进程控制块)结构。PCB是Linux操作系统识别进程的通道。 创建进程时&#xff0c;首先会创建PCB&#xff0c;根据PCB中的信息对进程实施有效管理。当进程终止后&#xff0c;Linux操作系统会释放对应的PCB资源。 PCB的数据结构是s…

IP定位技术中的网络拓扑分析

IP地址物理位置的高精度定位对于众多应用至关重要&#xff0c;从网络安全监控到个性化内容推荐&#xff0c;从地理定位服务、流量优化策略以及广告分布推广等。IP定位技术作为实现这一目标的关键手段&#xff0c;不断演进和创新&#xff0c;今天就IP定位技术中的网络拓扑分析来…

【面试系列】数据科学家 高频面试题及详细解答

欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;欢迎订阅相关专栏&#xff1a; ⭐️ 全网最全IT互联网公司面试宝典&#xff1a;收集整理全网各大IT互联网公司技术、项目、HR面试真题. ⭐️ AIGC时代的创新与未来&#xff1a;详细讲解AIGC的概念、核心技术、…

HTML5+JavaScript单词游戏

HTML5 JavaScript单词游戏 数据字典格式&#xff1a;每行一个 单词 &#xff0c;单词和解释用空格分隔&#xff0c;如 a art.一(个)&#xff1b;每一(个) ability n.能力&#xff1b;能耐&#xff0c;本领 able a.有能力的&#xff1b;出色的 baby n.婴儿&#xff1b;孩子…

深入浅出:npm 常用命令详解与实践

在现代的前端开发流程中&#xff0c;npm&#xff08;Node Package Manager&#xff09;已经成为了不可或缺的一部分。它不仅帮助我们有效地管理项目中的依赖包&#xff0c;还提供了一系列强大的命令来优化开发体验。在这篇博客中&#xff0c;我们将深入探讨 npm 的常用命令&…