当前位置: 首页 > news >正文

常见的交叉编译工具链

常见的交叉编译工具链

我们日常开发使用最多的就是gcc编译器,gcc来源于GNU C Compiler,起初支持一个C语言的编译器,而后发展成了为了GNU Compiler Collection,工具链中包括了编译器、链接器、binutils、glibc、头文件等。同时也支持了多种语言(C、C++、Java、Go等)与多种硬件平台(X86、ARM、MIPS、RISV-V等)。

而arm-none-eabi-gcc就是gcc的针对ARM平台的一个分支,全称是GNU C Compiler for ARM Architecture。

免费版目前有三大主流工具商:GNU、Codesourcery(已被西门子收购)、Linora。接下来我们列举一下你可能在开发中见到过的ARM交叉编译工具链。

  • arm-none-linux-gnueabi-gcc:是Codesourcery公司基于GCC推出的ARM交叉编译工具。可用于交叉编译ARM(32位)系统中所有环节的代码,包括裸机程序、u-boot、Linux kernel、filesystem和App应用程序。

  • arm-linux-gnueabihf-gcc:是由Linaro公司基于GCC推出的的ARM交叉编译工具。可用于交叉编译ARM(32位)系统中所有环节的代码,包括裸机程序、u-boot、Linux kerrnel、filesystem和App应用程序。与上一个的主要区别在于hf,表示对于浮点数编译使用的规则不同,后面详细说明。

  • aarch64-none-linux-gnu-gcc:是由Linaro公司基于GCC推出的的ARM交叉编译工具。可用于交叉编译ARMV8 64位CPU的裸机程序、u-boot、Linux kernel、filesystem和App应用用程序。

  • arm-none-eabi-gcc:是GNU推出的ARM交叉编译工具。可用于交叉编译ARMMCU(32位)芯片,如ARM7、ARM9、Cortex-M/R芯片程序。不支持操作系统,所以如果程序中有依赖系统调用等API接口则无法成功编译。

02

编译命名规则

arm编译工具链的命名规则如下:

<arch>-<vendor>-<os>-<abi>

  • arch(架构):描述目标处理器架构,如arm、aarch64。

  • vendor(供应商):一般填写none或者不填,表示没有特定供应商,常用于开源工具链。也可能是特定的公司名称(如apple或者特定平台的名字)。

  • os(操作系统):描述目标操作系统或者平台环境。

    • linux:表示目标系统是 Linux。

    • none:表示不依赖任何操作系统,常用于裸机编程。

    • elf:通常用于不依赖特定操作系统,但需要支持 ELF 格式。

  • abi(应用二进制接口):描述生成代码时使用的 ABI。

    • eabi:嵌入式应用二进制接口,适用于无操作系统环境。

    • eabihf: 嵌入式应用二进制接口,启用硬件浮点运算。

03

abi/eabi/eabihf

要完全搞懂几种编译工具链,还要再了解一下什么是工具链中经常出现的eabi?

  1. 什么是ABI?

ABI(Application Binary Interface),ABI 是对应用程序在运行时如何与操作系统或其他程序模块交互的详细定义。这包括函数调用约定、系统调用接口、二进制格式、库的链接方法、内存布局和寄存器使用等。

ABI是系统与应用之间的协议。一个BINARY(EXEC, LIB)必须符合ABI才能在相应的系统上运行。比如我在PC上用不管什么样的COMPILER, 只要产生符合LINUX的ELF文件, 用相应的指令集(比如INTEL, PPC, SPARC). 就可以在一个LINUX机器上运行,调用系统或别人的LIB。

简单来说ABI就是机器代码的一层封装接口,有点类似于系统调用的API接口,只不过ABI比API更接近硬件的一层接口,规定的是二进制代码之间的调用规则。

2. 什么是EABI?

EABI(Embedded Application Binary Interface),EABI 是专门为嵌入式系统设计的 ABI,在资源受限的环境中(如微控制器和嵌入式处理器)使用。它是常规 ABI 的一个子集,优化为嵌入式系统的需求。与通用计算机的ABI的主要区别是应用程序中允许使用特权指令,不需要动态链接和更紧凑的堆栈,广泛应用在ARM和Power PC中。

3. 什么是EABIHF?

HF代表hard float,它是在 EABI 基础上,进一步为支持硬件浮点运算进行优化的版本。与eabi的最大区别在于eabihf使用硬件浮点寄存器和浮点协处理器来进行浮点运算。这能显著提高涉及浮点运算的程序性能。

在早期嵌入式CPU(ARM7以前)中不包含FPU(浮点运算单元),会使用软件模拟实现,通过逻辑运算单元来处理浮点数。后来在CPU(Cortex-A系列)中逐渐支持了FPU,这时候编译器分为两种:软浮点(softfp)与硬浮点(hf)。

两种编译器都会使用FPU来计算浮点数,但是softfp使用普通寄存器来传参,而hf寄存器也是用FPU专用寄存器。所以sotffp一般用来兼容没有FPU的CPU,使用的较多。

然而最重要的来了,到了arm64时代,也就是ARMv8之后,ARM64引入了统一的ABI接口,不再区分ABI与EABI。并且所有的ARM V8架构都支持硬浮点运算,所以也不再区分hf。因此arm64的工具链就命名相对统一使用aarch64-none-linux-gnu-gcc

04

总结

最后做一个总结,我在这里给大家花了一个简单的示意图作为选择编译工具链的选择方法。

对于arm64架构统一使用aarch64-none-linux-gnu-gcc即可,即使是裸机程序或者ATF等,也是可以用这个工具进行编译的,区别可能就是最后编译出来的产物稍大一些,对于空间没有那么敏感的时候可以不必作区分。

对于arm32架构,如果是裸机程序可以使用arm-none-eabi-gcc,而对于uboot,linux使用arm-none-linux-eabi-gcc

http://www.lryc.cn/news/622768.html

相关文章:

  • 第四章:大模型(LLM)】06.langchain原理-(5)LangChain Prompt 用法
  • 【Vibe Coding 工程之 StockAnalyzerPro 记录】- EP3.Phase 2股票列表管理功能
  • Camx-Tuning参数加载流程分析
  • 力扣(LeetCode) ——622. 设计循环队列(C语言)
  • 类的生命周期与加载过程
  • LintCode第116题-跳跃游戏
  • java项目怎么实现用户行为分析、漏斗转化、数据可视化报表。
  • 【Linux系统】进程间通信:System V IPC——共享内存
  • FPGA实现I2C通信方案
  • 创建maven module中的override
  • 库的制作与原理
  • Navicat 为 SQLite 数据库设置密码指南
  • 如何使用 Git 修改已推送 Commit 的用户名和邮箱
  • 从废弃到珍宝——旧物二手回收小程序系统的价值发现之旅
  • 配置 Docker 镜像加速,解决 docker pull 拉取镜像失败、docker search 查询镜像失败等问题
  • 外出业务员手机自动添加报价单​——仙盟创梦IDE
  • PostgreSQL——事务处理与并发控制
  • 关于casdoor重定向问题
  • 力扣(最小覆盖子串)
  • Java设计模式之《工厂模式》
  • 【Java web】HTTP 协议详解
  • PO BO VO DTO POJO DAO DO概念
  • Linux第十四讲:网络基础概念
  • Jenkins Pipeline中参数化构建
  • Android 移动端 UI 设计:前端常用设计原则总结
  • 后台管理系统-3-vue3之左侧菜单栏和头部导航栏的静态搭建
  • flowable汇总查询方式
  • SAP-FI配置与业务解析之内部交易核算
  • 双向SSL认证之Apache实战配置
  • 3 种方式玩转网络继电器!W55MH32 实现网页 + 阿里云 + 本地控制互通