创建基于 sysroot 的 linux arm64 交叉编译环境

背景

编译 arm64 架构的程序的方法有两种:

  • 将代码上传到 arm64 架构的机器上编译。
  • 在 x64 架构上进行 arm64 交叉编译。

多数需要交叉编译的场景一般是夸平台多架构支持或是嵌入式开发。使用 sysroot 方法是一个更优的方案,不需要特定架构的编译服务器,支持的架构可以方便扩展。

什么是 sysroot

sysroot 是交叉编译过程中使用的一个概念,指目标系统根文件系统中的一个目录结构。 该目录结构包含编译器和链接器所需的所有目标系统头文件、库文件和其他必要文件。 使用 sysroot 允许编译器和链接器在编译和链接阶段像在目标系统上运行一样进行编译和链接,从而生成可在目标系统上运行的可执行文件和库。

sysroot 在交叉编译设置中非常重要,因为它提供了目标平台的环境,包括但不限于:

  • 头文件:包含目标系统 API 和库的声明。
  • 库文件:包含目标系统上可用的静态和动态链接库。
  • 其他文件:可能包括其他必要的配置文件和资源。

使用 sysroot 的好处包括:

  • 隔离:它提供了一个隔离的环境,避免了本地系统和目标系统之间的冲突。
  • 一致性:确保编译后的程序能在目标系统上正确运行,因为它们链接了目标系统的库。
  • 可移植性:使交叉编译过程更加灵活和可移植,因为只需将 sysroot 目录复制到不同的编译环境中即可重复使用。

创建 sysroot

下面演示在 Ubuntu2204 x64 架构 的主机(host)上创建 arm64 架构(target)的 sysroot 主要步骤.

安装创建 sysroot 的工具

sudo apt update
sudo apt install debootstrap coreutils qemu qemu-user-static

创建 sysroot 目录

mkdir <target_dir>
# The --foreign option is used to split the debootstrap process into two stages.
# This is necessary when setting up a root filesystem for a different architecture because the second stage of the process (configuring the packages) needs to run on the target architecture.
# You'll need to copy the qemu-*-static binary into the new root filesystem and then run the second stage manually.
sudo debootstrap --arch arm64 --foreign bionic <target_dir>
sudo cp /usr/bin/qemu-aarch64-static <target_dir>/usr/bin/# Do the initial unpack phase of bootstrapping only,
# for example if the target architecture does not match the host architecture. 
# A copy of debootstrap sufficient for completing the bootstrap process will be installed as /debootstrap/debootstrap in the target filesystem. 
# You can run it with the --second-stage option to complete the bootstrapping process.
sudo chroot <target_dir> /debootstrap/debootstrap --second-stage

target_dir 就是我们创建 arm64 的 sysroot 的文件夹。至此,arm64 的 sysroot 环境准备就绪。

安装编译 arm64 架构的依赖库

使用 chroot 工具切换到 sysroot 目录下,也就是上面步骤创建的target_dir ,这样我们就可以把 arm64 架构的依赖包安装到sysroot 目录下了。

# change fs from x64 to arm64
sudo chroot <target_dir>
# The following steps as if you were using a machine with the arm64 architecture.
# Install compilation dependencies
apt install packages-you-need.deb
# change fs frome arm64 to x64, prepare to cross build on host.
exit

交叉编译

交叉编译推荐使用 CMake 的 toolchains 工具链。这里引用 CMake 的官方示例稍加修改。

set(CMAKE_SYSTEM_NAME Linux)
# 指定交叉编译的架构为 arm64
set(CMAKE_SYSTEM_PROCESSOR aarch64)# 指定 sysroot 目录,以及 pkg-config 文件的搜索路径,这里我们需要到 sysroot 下查找
set(CMAKE_SYSROOT /home/devel/rasp-pi-rootfs)
set(ENV{PKG_CONFIG_SYSROOT_DIR} ${CMAKE_SYSROOT})
set(ENV{PKG_CONFIG_PATH} ${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu/pkgconfig)# 指定编译器,此处需要注意,我们仍然使用 host 主机上的编译器
# 让 host 主机上的编译器去编译我们的代码,链接的是 sysroot 中的库
set(CMAKE_C_COMPILER /usr/bin/aarch64-linux-gnu-gcc-10)
set(CMAKE_CXX_COMPILER /usr/bin/aarch64-linux-gnu-g++-10)# 指定编译时不使用 sysroot 中的工具,只在 sysroot 中查到头文件和库
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

编译过程中如果预定找不到头文件或是链接不到库,首先要确认头文件或是库的路径在不在 sysroot 目录下,切记不会使用到 host 主机下的头文件或库。

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

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

相关文章

JavaScript(15)——操作表单元素属性和自定义属性

操作表单元素属性 表单很多情况&#xff0c;也需要修改属性&#xff0c;比如点击眼睛可以看到密码&#xff0c;本质是把表单类型转换为文本框正常的有属性有取值的&#xff0c;跟其他的标签属性没有任何区别 获取&#xff1a;DOM对象.属性名 设置&#xff1a;DOM对象.属性名…

Android adb shell ps进程查找以及kill

Android adb shell ps进程查找以及kill 列出当前Android手机上运行的所有进程信息如PID等&#xff1a; adb shell ps 但是这样会列出一大堆进程信息&#xff0c;不便于定向查阅&#xff0c;可以使用关键词查找&#xff1a; adb shell "ps | grep 关键词" 关键词查…

Jenkins详细使用教程

目录 1. 什么是Jenkins&#xff1f; 2. 为什么使用Jenkins&#xff1f; 3. 安装Jenkins 3.1 下载相关文件 3.2 解压Linux版本的JDK 3.3 配置JDK环境 3.4 运行jenkins.war 3.5 安装完成 4. 访问Jenkins 5. 修改密码 6. 集成JDK 7. Jenkins集成Git 7.1 使用Jenkins拉取…

C语言——运算符及表达式

C语言——运算符及表达式 运算符运算符的分类&#xff08;自增运算符&#xff09;、--&#xff08;自减运算符&#xff09;赋值运算符逗号运算符&#xff08;顺序求值运算符&#xff09; 表达式 运算符 运算符的分类 C语言的运算符范围很宽&#xff0c;除了控制语句和输入输出…

分布式缓存获取以及设置

1. 通用代码 public SysUser getCache(String sysUserId) {String cacheKey "litgery:warehouse:" sysUserId;// 尝试从缓存中获取数据CacheData cacheData redisUtils.get(cacheKey);if (null ! cacheData) {if (Boolean.TRUE.equals(cacheData.getExist())) {re…

Internet Download Manager2024免费流行的下载加速器

1. Internet Download Manager&#xff08;IDM&#xff09;是一款流行的下载加速器&#xff0c;多线程下载使速度更快。 2. 用户界面友好&#xff0c;易于操作&#xff0c;支持多种浏览器集成和自动捕获下载。 3. 恢复中断的下载&#xff0c;动态文件分割技术提高效率。 4. 定…

Vue3与Element-plus配合 直接修改表格中的一项数据——控制输入框的显示与隐藏

利用控制与隐藏输入框,直接修改表格中的每一项数据。 <!-- 表格模块 --> <div><el-table :data"tablelist" style"width: 100%"><el-table-column align"center" prop"deposit" label"接单押金">&l…

『 Linux 』信号的写入与保存

文章目录 信号的发送信号的保存sigset_t 类型与信号集操作函数阻塞信号集(信号屏蔽字)操作函数未决信号集操作函数验证阻塞信号集与未决信号集 信号的发送 $ kill -l1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10)…

【音视频】RTSP、RTMP与流式传输

文章目录 前言RTSP与RTMPRTSP&#xff08;Real-Time Streaming Protocol&#xff09;RTMP&#xff08;Real-Time Messaging Protocol&#xff09;主要差异 什么是流式传输&#xff1f;流式传输的特点流式传输与传统下载的区别 使用VLC播放RTSP监控 总结 前言 在现代网络环境中…

一天搞定React(3)——Hoots组件【已完结】

Hello&#xff01;大家好&#xff0c;今天带来的是React前端JS库的学习&#xff0c;课程来自黑马的往期课程&#xff0c;具体连接地址我也没有找到&#xff0c;大家可以广搜巡查一下&#xff0c;但是总体来说&#xff0c;这套课程教学质量非常高&#xff0c;每个知识点都有一个…

Redis#架构师面试题

1、Redis锁存在哪些问题及如何解决&#xff1f; 1、死锁问题 加过期时间设定 2、原子性问题 通过“set…nx...ex…”命令&#xff0c;将加锁、过期命令编排到一起&#xff0c;它们是原子操作了&#xff0c;可以避免死锁。 3、释放其他线程的锁问题 当过期时间设置小于线程…

学习笔记之Java篇(0726)

2、封装 1、封装的使用细节 2、开发中封装的简单规则&#xff1a; 属性一般使用private访问权限。 属性私有后&#xff0c;提供相应的get/set方法来访问相关属性&#xff0c;这些方法通常是public修饰后&#xff0c;以提供属性的赋值与读取操作&#xff08;注意&#xff1a;b…

情绪稳定的人有什么特点?

第一部分&#xff1a;至纯之人&#xff0c;大器晚成 1.1 单纯&#xff0c;不是天真 你知道吗&#xff1f;那些能够成就大事的人&#xff0c;往往在人性上非常单纯。他们对外界的需求很低&#xff0c;更多的是向内寻求。这样的人&#xff0c;他们的内心世界像一片净土&#xff…

二叉树 N0=N2+1

N0 叶子节点&#xff0c;度为 0 的节点&#xff1b; N1 度为 1 的节点&#xff1b; N2 度为 2 的节点 度为 0 的节点为&#xff1a;H、I、J、K、G 度为 1 的节点&#xff1a;E、F 度为 2 的节点&#xff1a;A、B、D、C N0 N2 1&#xff0c;即&#xff1a;度为 0 的叶子节点 …

Jenkins配置weblogic自动发版--示例

Pipeline内容 properties([parameters([[$class: CascadeChoiceParameter, choiceType: PT_CHECKBOX, description: 选择 受管服务器, filterLength: 1, filterable: false, name: WLS_Targets, randomName: choice-parameter-173347495550024, referencedParameters: Action,…

力扣高频SQL 50 题(基础版)第四题

文章目录 力扣高频SQL 50 题&#xff08;基础版&#xff09;第四题584.寻找用户推荐人题目说明思路分析实现过程准备数据实现方式结果截图 力扣高频SQL 50 题&#xff08;基础版&#xff09;第四题 584.寻找用户推荐人 题目说明 表: Customer -------------------- | Colu…

虚拟机配置RabbitMQ集群教程

RabbitMQ是常用的一款消息中间件&#xff0c;那么如何在我们虚拟机中创建其集群呢&#xff1f;跟着博主这篇文章让你一步到位 本篇搭建的是三台机器为一个集群&#xff01;假设大家虚拟机都为初始化状态&#xff0c;从0开始&#xff08;注意集群搭建需要CentOS8以上环境&#x…

【五】MySql8基于m2芯片arm架构Ubuntu24虚拟机安装

文章目录 1. 更新系统包列表2. 安装 MySQL APT Repository3. 更新系统包列表4. 安装 MySQL Server5. 运行安全安装脚本6. 验证 MySQL 安装7. 配置远程连接7.1 首先要确认 MySQL 配置允许远程连接&#xff1a;7.2 重启 MySQL 服务&#xff1a;7.3 检查 MySQL 用户权限&#xff1…

常见的文心一言的指令

文心一言&#xff0c;作为百度研发的预训练语言模型“ERNIE 3.0”的一项功能&#xff0c;能够与人对话互动&#xff0c;回答问题&#xff0c;协助创作&#xff0c;高效便捷地帮助人们获取信息、知识和灵感。以下是一些常见的文心一言指令类型及其具体示例&#xff1a; 1. 查询…

详解数据结构之二叉树(二叉链,使用递归)

详解数据结构之二叉树(二叉链&#xff0c;使用递归实现) 二叉链 二叉链&#xff0c;二叉树的链式结构&#xff0c;其中数据域data存放节点的值&#xff0c;指针域left和right分别存放左孩子节点的地址、右孩子节点的地址。 typedef int BinaryTDataType; typedef struct Bin…