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

news2024/11/25 7:07:18

使用 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/1852661.html

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

相关文章

论文《Universal Graph Convolutional Networks》笔记

【UGCN】论文提出一个基本问题&#xff0c;即是否不同的网络结构属性应该采用不同的传播机制。通过实验发现&#xff0c;对于完全同配性、完全异配性和随机性的网络&#xff0c;1-hop、2-hop和k-nearest neighbor&#xff08;kNN&#xff09;邻居分别更适合作为信息传播的邻域。…

stm32学习笔记---GPIO输出(理论部分)

目录 GPIO通用输入输出口 GPIO的基本结构 I/O端口位的基本结构 输入部分 输出部分 推挽模式 开漏模式 GPIO的8种工作模式 STM32手册GPIO和AFIO大致介绍 STM32外部的设备和电路 声明&#xff1a;本专栏是本人跟着B站江科大的视频的学习过程中记录下来的笔记&#xff0…

CISP-PTE综合靶机-WinServer2003

1.收集网站的地址和开放的端口,完成前期信息收集。10分 2.访问站点,找出站点的敏感文件,利用返回数据找到相关敏感信 息,完成网站结构的信息收集。10分 3.利用文件包含漏洞读取敏感文件,找出数据库连接凭证,利用此 凭证连接数据库。10分 4.网站后台提权:找出后台管理员登…

Attention系列总结-粘贴自知乎

1. 梦想做个翟老师&#xff1a;阿里&#xff1a;Behavior Sequence Transformer 解读48 赞同 7 评论文章 优点:捕捉用户行为历史序列中的顺序信息。w2v也是捕捉用户序列信息的,本质差异在于啥&#xff1f; 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff0…

STM32CubeIDE提示找不到头文件(No such file or directory)的解决办法

0 前言 最近在使用STM32CubeIDE时&#xff0c;发现为工程添加了头文件路径&#xff0c;但编译的时候还是报错&#xff0c;提示找不到头文件&#xff1a; 1 解决办法 1.1 为工程添加头文件路径 右键我们的工程&#xff0c;然后添加头文件路径&#xff08;最好是相对路径&am…

Vue3+TypeScript项目实战——打造雨雪交加的智慧城市

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 ⚡开源项目&#xff1a; rich-vue3 &#xff08;基于 Vue3 TS Pinia Element Plus Spring全家桶 MySQL&#xff09; &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1…

C# SerialPort串口通讯

串口通信 在.NET平台下创建C#串口通信程序&#xff0c;.NET 2.0提供了串口通信的功能&#xff0c;其命名空间是System.IO.Ports。这个新的框架不但可以访问计算机上的串口&#xff0c;还可以和串口设备进行通信。 创建C#串口通信程序之命名空间 System.IO.Ports命名空间中最重…

【跟我学RISC-V】(三)openEuler特别篇

写在前面 这篇文章是跟我学RISC-V指令集的第三期&#xff0c;距离我上一次发文已经过去一个多月了&#xff0c;在这个月里我加入了oerv的实习项目组&#xff0c;并且还要准备期末考试&#xff0c;比较忙&#xff0c;所以更新频率不高&#xff0c;不过对于Linux kernel和RISC-V…

vue修改node_modules打补丁步骤和注意事项_node_modules 打补丁

1、vue-pdf问题解决及patch-package简介&#xff1a;https://www.jianshu.com/p/d1887e02f8d6 2、使用“黑魔法”优雅的修改第三方依赖包&#xff1a;https://zhuanlan.zhihu.com/p/412753695 3、使用patch-package定制node_modules中的依赖包&#xff1a;https://blog.csdn.…

macbook配置adb环境和用adb操作安卓手机

&#xff08;参考&#xff1a;ADB工具包的安装与使用_adb工具箱-CSDN博客&#xff09; 第一步&#xff1a;从Android开发者网站下载Android SDK&#xff08;软件开发工具包&#xff09;。下载地址为&#xff1a; 第二步&#xff1a;解压下载的SDK压缩文件到某个目录中。 进入解…

Python 数据可视化 多色散点图

Python 数据可视化 多色散点图 fig, ax plt.subplots() max_line max([max(merged_df[unif_ref_value]), max(merged_df[unif_rust_value])]) min_line min([max(merged_df[unif_ref_value]), max(merged_df[unif_rust_value])]) ax.plot([min_line, max_line], [min_line, …

基于JSP的教学质量评价系统

开头语&#xff1a; 你好&#xff0c;我是计算机学长猫哥。如果您对教学质量评价系统感兴趣或有相关需求&#xff0c;欢迎随时联系我。 开发语言&#xff1a; Java 数据库&#xff1a; MySQL 技术&#xff1a; JSP技术 Java语言 工具&#xff1a; MyEclipse、Tomcat服…

基于JSP的“塞纳河畔左岸”的咖啡馆管理系统

开头语&#xff1a; 塞纳河畔左岸的咖啡&#xff0c;我手一杯品尝的你美~ 哎哟&#xff0c;不错哦&#xff01;我们今天来介绍一下咖啡馆管理系统&#xff01; 你好呀&#xff0c;我是计算机学长猫哥&#xff01;如果你对咖啡馆管理系统感兴趣或有相关需求&#xff0c;欢迎联…

基于 GoLang 编写的 IOT 物联网在线直播抓娃娃企业级项目

大家好&#xff0c;我是码农先森。 引言 前几年&#xff0c;娱乐物联网的热度很高。我当时所在的公司启动了一个将线下娃娃机的玩法&#xff0c;迁移到线上的项目&#xff0c;因此公司决定开发一个在线直播抓娃娃的项目。近来&#xff0c;娱乐物联网的领域已经进入资本的寒冬…

小白学-WEBGL

第一天&#xff1a; 1.canvas和webgl的区别 Canvas 和 WebGL 都是用于在网页上绘制图形的技术&#xff0c;它们通过浏览器提供的 API 使开发者能够创建丰富的视觉内容&#xff0c;但它们的工作原理和用途有所不同。 Canvas Canvas API 提供了一个通过 JavaScript 和 HTML <…

家政预约小程序14权限配置

目录 1 创建用户2 创建角色3 启用登录4 实现退出总结 我们现在小程序端的功能基本开发好了&#xff0c;小程序开发好之后需要给运营人员提供管理后台&#xff0c;要分配账号、配置权限&#xff0c;我们本篇就介绍一下权限如何分配。 1 创建用户 在微搭中&#xff0c;用户分为内…

基于Pico和MicroPython点亮ws2812彩色灯带

基于Pico和MicroPython点亮ws2812彩色灯带 文章目录 基于Pico和MicroPython点亮ws2812彩色灯带IntroductionPracticeConclusion Introduction 点亮发光的LED灯是简单有趣的实验&#xff0c;点亮多个ws2812小灯串联起来的灯带&#xff0c;可对多个彩色小灯进行编程&#xff0c;…

react笔记-03react-router篇

本文章是react的路由笔记 一、react路由&#xff08;v5版本&#xff09; 1. 什么是路由&#xff08;前端&#xff09;&#xff1f; 一个路由就算一个映射关系&#xff08;key: value)key为路径&#xff0c;value为组件 2. 前端路由的工作原理 根据浏览器历史记录&#xff…

Java | Leetcode Java题解之第167题两数之和II-输入有序数组

题目&#xff1a; 题解&#xff1a; class Solution {public int[] twoSum(int[] numbers, int target) {int low 0, high numbers.length - 1;while (low < high) {int sum numbers[low] numbers[high];if (sum target) {return new int[]{low 1, high 1};} else i…

C++ (week9):Git

文章目录 1.git介绍2.git安装3.git配置4.获取自己的SSH公钥5.新建仓库6.邀请开发者7.克隆远程仓库到本地8.在本地进行开发9.本地项目推送到远程仓库10.git的工作原理11.分支管理(1)合作开发的方式(2)分支管理(3)分支合并的原理、冲突管理 12.git 与 svn 的区别13.设置alias别名…