前言
本文主要介绍gcc编译器的主要组成部分以及gcc编译器的命名规则。
API && ABI
应用二进制接口(英语:application binary interface,缩写为ABI),是指两程序模块间的接口;通常其中一个程序模块会是库或操作系统所提供的服务,而另一边的模块则是用户所运行的程序。
一个ABI定义了机器代码如何访问数据结构与运算程序,此处所定义的界面相当低端并且相依于硬件。而类似概念的API则在源代码定义这些,则较为高端,并不直接相依于硬件,通常会是人类可阅读的代码。理解ABI时可以参考API。
决定要不要采取既定的ABI(不论是否由官方提供),通常由编译器,操作系统或库的开发者来决定;然而,如果撰写一个混和多个编程语言的应用程序,就必须直接处理ABI,采用外部函数调用来达成此目的。主要和目标平台的架构有关。例如gcc最终编译成功的HelloWorld
,遵从x86的调用约定即是一个ABI的例子。
ABI涵盖了各种细节:
- 数据类型的大小、布局和对齐;
- 调用约定(控制着函数的参数如何传送以及如何接受返回值),例如,是-所有的参数都通过栈传递,还是部分参数通过寄存器传递;哪个寄存器用于哪个函数参数;通过栈传递的第一个函数参数是最先push到栈上还是最后;
- 系统调用的编码和一个应用如何向操作系统进行系统调用;
- 以及在一个完整的操作系统ABI中,目标文件的二进制格式、程序库等等。
EABI
嵌入式应用二进制接口指定了文件格式、数据类型、寄存器使用、堆积组织优化和在一个嵌入式软件中的参数的标准约定。开发者使用自己的汇编语言也可以使用EABI作为与兼容的编译器生成的汇编语言的接口。 支持EABI的编译器创建的目标文件可以和使用类似编译器产生的代码兼容,这样允许开发者链接一个由不同编译器产生的库。比如 eabi,gnueabihf。
GCC结构组成
GCC 内部结构主要由 Binutils、gcc-core、Glibc 等软件包组成。
GNU Binutils是二进制工具的集合。 主要的是:
- ld -GNU链接器
- as - GNU汇编器
当然还包含很多重要的工具
- objcopy - 文件格式转换
- objdump - 反汇编
- readelf - 读取.elf参数信息
- …
gcc-core:GCC 的核心部分,这部分包含 c 的编译器及公共部分,而对其他语言(C++、Ada 等)的支持包需要另外安装,这也是 GCC 为何如此强大的重要原因 。gcc-core依赖于 Binutils。
Glibc:GNU C库(英语:GNU C Library,常简称为glibc)是一种C函数库,是程序运行时使用到的一些API集合,它们一般是已预先编译好,以二进制代码形式存在Linux类系统中。当然并不是所有的都依赖Glibc,还有其他的C库如: uClibc、dietlibc 、newlib。
所以很多厂家修改gcc编译器的组成模块,使编译器可以编译不同架构或者不同C库依赖的代码。
GCC交叉编译器的命名规则
谷歌了很久没有找到相对官方的说明文档,浏览了很多网页,发现了很多标准,个人觉得比较靠谱结构大体如下,当然也不是适合所有的编译器命名,仅供参考。
arch - vendor - (os- )abi
架构 - 厂商 - 操作系统 - 二进制应用接口
- arch: 目标的架构;例如x86,amd64,arm…
- vendor: 制作工具链的厂商;
- os: 依赖的操作系统;例如win32,win64,linux
- abi: 对应的二进制应用接口;例如:eabi,gnueabihf,gnueabi
根据对操作系统的支持与否,ARM GCC可分为支持和不支持操作系统,如
arm-none-eabi:这个是没有操作系统的,自然不可能支持那些跟操作系统关系密切的函数,比如fork(2)。他使用的是newlib这个专用于嵌入式系统的C库。
arm-none-linux-eabi:用于Linux的,使用Glibc
示例:
arm-none-linux-gnueabi
项目 | Value |
---|---|
arch | ARM |
vendor | no vendor |
os | linux |
abi | gnueabi ABI |
主要用于基于ARM架构的Linux系统,可用于编译 ARM 架构的 u-boot、Linux内核、linux应用等。arm-none-linux-gnueabi基于GCC,使用Glibc库,经过 Codesourcery 公司优化过推出的编译器。arm-none-linux-gnueabi-xxx 交叉编译工具的浮点运算非常优秀。一般ARM9、ARM11、Cortex-A 内核,带有 Linux 操作系统的会用到。
arm-none-eabi
项目 | Value |
---|---|
arch | ARM |
vendor | no vendor |
os | no os |
abi | gnueabi ABI |
用于编译 ARM 架构的裸机系统(包括 ARM Linux 的 boot、kernel,不适用编译 Linux 应用 Application),一般适合 ARM7、Cortex-M 和 Cortex-R 内核的芯片使用,所以不支持那些跟操作系统关系密切的函数,比如fork(2),它使用的是 newlib 这个专用于嵌入式系统的C库。
参考以及引用链接:
https://zh.wikipedia.org/wiki/%E5%BA%94%E7%94%A8%E4%BA%8C%E8%BF%9B%E5%88%B6%E6%8E%A5%E5%8F%A3
https://tungsys.wordpress.com/2011/07/05/cross-compiler-naming-convention/
https://www.cnblogs.com/wxishang1991/p/5322499.html
https://zhuanlan.zhihu.com/p/42102350
https://www.gnu.org/software/binutils/
https://blog.csdn.net/LEON1741/article/details/81537529
https://blog.csdn.net/eagle11235/article/details/54620203