gcc、arm-Linux-gcc和arm-elf-gcc的组成及区别

发布者:EtherealHeart最新更新时间:2020-02-22 来源: eefocus关键字:GCC  ARM-LINUX-GCC  ARM-ELF-GCC 手机看文章 扫描二维码
随时随地手机看文章

一、GCC简介

The GNU Compiler Collection,通常简称 GCC,是一套由 GNU 开发的编译器集,为什么是编辑器集而不是编译器呢?


那是因为它不仅支持 C 语言编译,还支持 C++, Ada,Objective C 等许多语言。另外 GCC 对硬件平台的支持,可以所无所不在,它不仅支持 X86处理器架构, 还支持 ARM, Motorola 68000, Motorola 8800,AtmelAVR,MIPS 等处理器架构。


二、GCC的组成结构

GCC 内部结构主要由 Binutils、gcc-core、Glibc 等软件包组成。


1. Binutils:它是一组开发工具,包括连接器,汇编器和其他用于目标文件和档案的工具。关于 Binutils 的介绍可以参考 Binutils 简单介绍。这个软件包依赖于不同的目标机的平台。因为不同目标机的指令集是不一样的,比如 arm 跟 x86 就不一样。


2. gcc-core:顾明之意是 GCC 的核心部分,这部分是只包含 c 的编译器及公共部分,而对其他语言(C++、Ada 等)的支持包需要另外安装,这也是 GCC 为何如此强大的重要原因 。gcc-core依赖于 Binutils。


3. Glibc:包含了主要的 c 库,这个库提供了基本的例程,用于分配内存,搜索目录,读写文件,字符串处理等等。kernel 和 bootloader不需要这个库的支持。


举例描述下上面 3 个包是如何进行运作的。有一个 c 源文件 test.c 源码如下:

1. #include  


2. int main(int argc, char *argv[])  


3. {  


4.     printf("Hello Linux!!n");  


5.     return 0;  


6. }  


编译命令为: gcc -o test test.c 编译生成 test 可执行文件。gcc 编译流程分为四个步骤:预处理、编译 、汇编、链接。预处理和编译主要由 gcc-core 来完成,汇编和链接主要由 Binutils 来完成。那么何时用到 glibc 呢?看到源码中的 printf 函数没有,这个函数在 GCC 中是以库函数的形式存在,这个库函数在 glibc 库中,在 stdio.h 头文件中被声明。


总的来说,如果真正了解了上面 3 个软件包的作用,自然就明白 GCC 是如何工作的。


三、交叉编译

交叉编译(或交叉建立)是这样一种过程,它在一种机器结构下编译的软件将在另一种完全不同的机器结构下执行。一个常见的例子是在 PC 机上为运行在基于 ARM、PowerPC或 MIPS 的目标机的编译软件。幸运的是,GCC 使得这一过程所面临的困难要比听起来小得多。


GCC 中的一般工具通常都是通过在命令行上调用命令(如 gcc)来执行的。在使用交叉编译的情况下,这些工具将根据它编译的目标而命名。例如,要使用交叉工具链为 ARM 机器编译简单的 Hello World 程序,你可以运行如下所示的命令:使用如下命令编译并测试这个代码: arm-linux-gcc -o hello hello.c。


四、arm-linux-gcc

arm-linux-gcc 是基于 ARM 目标机的交叉编译软件, arm-linux-gcc 跟 GCC 所需的安装包不同,但仅仅是名字不同而已,这是为什么呢?


x86 跟 ARM 所使用的指令集是不一样的,所以所需要的 binutils 肯定不一样;上面提到过 gcc-core 是依赖于 binutils 的,自然 ARM 跟 x86 所使用的 gcc-core 包也不一样;glibc 一个 c 库,最终是以库的形式存在于编译器中,自然 ARM 所使用的 glibc 库跟 x86 同样也不一样,其它的依此类推。


五、arm-elf-gcc

arm-elf-gcc 跟 arm-linux-gcc 一样,也是是基于 ARM 目标机的交叉编译软件。但是它们不是同一个交叉编译软件,两者是有区别的,两者区别主要在于使用不同的 C 库文件。arm-linux-gcc使用 GNU 的 Glibc,而 arm-elf-gcc 一般使用 uClibc/uC-libc 或者使用 RedHat专门为嵌入式系统的开发的C库newlib。只是所应用的领域不同而已,Glibc是针对PC开发的,uClibc/uC-libc是与Glibc API兼容的小型化C语言库,实现了Glibc部分功能。


六、uClibc/uC-libc 

uClinux有两个经常使用的libc库:uC-libc和uClibc。虽然两者名字很相似,其实有差别,下面就简单的介绍一下二者的不同之处。


uC -libc是最早为uClinux开发的库,是Jeff Dionne和Kenneth Albanowski为在EKLs项目中支持m68000在Linux-8086 C库源码上移植的。uC-libc是一个完全的libc实现,但其中有一些api是非标准的,有些libc的标准也没有实现。uC-libc稳定地支持 m68000,ColdFire和没有MMU的ARM。其主要设计目标是“小”、“轻”,并尽量与标准一致,虽然它的API和很多libc兼容,但是似乎并不像它期望的那样和所有标准一致。


uClibc就是为了解决这个问题从uC-libc中发展出来的。它的所有API都是标准的(正确的返回类型,参数等等),它弥补了uC-libc中没有实现的libc标准,现在已经被移植到多种架构中。一般来讲,它尽量兼容glibc以便使应用程序用uClibc改写变的容易。uClibc能够在标准的 VM linux和uClinux上面使用。为了应用程序的简洁,它甚至可以在许多支持MMU的平台上被编译成共享库。


Erik Anderson在uClibc背后做了很多的工作。


uClibc支持许多系列的处理器:m68000,Coldfire,ARM,MIPS,v850, x86,i960,Sparc,SuperH,Alpha,PowerPC和Hitachi 8。不断增加的平台支持显示uClibc能够很容易的适应新的架构。uClinux发行版提供了环境能够让你选择使用uC-libc或是uClibc编译。对于m68000和Coldfire平台来说,选择uC-libc还是稍微好一点,因为它支持共享库,而共享库是这些cpu经常使用的 libc。uClibc也几乎和所有的平台都能很好的工作。


newlib 是一个用于嵌入式系统的开放源代码的C语言程序库,由libc和libm两个库组成,特点是轻量级,速度快,可移植到很多CPU结构上。


newlib实现了许多复杂的功能,包括字符串支持,浮点运算,内存分配(如malloc)和I/O流函数(printf,fprinf()等等)。其中libc提供了c 语言库的实现,而libm提供了浮点运算支持。


七、C语言库的选择


在为ARM交叉编译gcc编译器时,对gcc指定不同的配置选项时,使用的C语言库就不同,gcc编译器默认使用Glibc,也可以使用 uClibc/uC-libc(基本兼容Glibc API),当使用--with-newlib时,gcc编译器不使用Glibc。


当没有交叉编译Glibc时,可以使用--with-newlib禁止连接Glibc而编译bootstrap gcc编译器。


从gcc源目录下的config/arm中的t-linux和t-arm-elf中可以看出,不同的--target也影响gcc连接C语言库,t-linux(--target=arm-linux)默认使用Glibc,-arm-elf(--target=arm-elf)使用- Dinhibit_libc禁止连接Glibc,这时我们就可以使用newlib等其他C语言库编译GCC工具链。


虽然GCC工具链配置了不同的的C语言库,但由于这些C语言库都可以用来支持GCC,它们对核心数据的处理上不存在较大出入。因而arm-linux-* 和 arm-elf-*区别主要表现在C语言库的实现上,例如不同系统调用,不同的函数集实现,不同的ABI/启动代码以及不同系统特性等微小的差别。


arm-linux-*和 arm-elf-*的使用没有一个绝对的标准,排除不同库实现的差异,gcc可以编译任何系统。arm-linux-*和 arm-elf-*都可以用来编译裸机程序和操作系统,只是在遵循下面的描述时系统程序显得更加协调:


arm-linux-*针对运行linux的ARM机器,其依赖于指定的C语言库Glibc,因为同样使用Glibc的linux而使得arm-linux-*在运行linux的ARM机器上编译显得更加和谐。


arm-elf-*则是一个独立的编译体系,不依赖于指定的C语言库Glibc,可以使用newlib等其他C语言库,不要求操作系统支持,当其使用为嵌入式系统而设计的一些轻巧的C语言库时编译裸机程序(没有linux等大型操作系统的程序),如监控程序,bootloader等能使得系统程序更加小巧快捷。

关键字:GCC  ARM-LINUX-GCC  ARM-ELF-GCC 引用地址:gcc、arm-Linux-gcc和arm-elf-gcc的组成及区别

上一篇:JZ2440开发笔记(1)——arm-linux-gcc环境搭建
下一篇:4G通信模块在ARM平台下的应用

推荐阅读最新更新时间:2024-11-06 09:30

Ubuntu安装arm-linux-gcc 详细步骤
gcc编译的只能在Linux中使用,要在ARM中使用,还要使用交叉编译工具: arm-linux-gcc 1.获取压缩包 首先尝试使用命令行安装,结果如下: 但是此方法需要翻墙获取(我听别人说的…),一般情况不会成功的。 所以在主机上下载 arm-linux-gcc的安装包,通过FTP传输工具发送压缩包到Ubuntu中: 发送到 /tmp 路径下,如图: 2.解压 压缩包到指定路径 然后解压压缩包到根目录,注意这里使用tar命令,根据压缩包的后缀信息看出使用bzip2压缩然后tar命令分包: sudo tar -xjvf arm-linux-gcc-4.6.4-arm-x86_64.tar.bz2 -C /
[单片机]
Ubuntu安装<font color='red'>arm-linux-gcc</font> 详细步骤
关于arm-linux-gcc的安装与配置
在嵌入式开发中我们经常会用到arm-linux-gcc来编译我们的应用程序。作为arm-linux-gcc的入门,我们先看看如何安装arm-linux-gcc。 安装arm-linux-gcc还是比较简单的,我们看看Redhat9.0下的安装步骤吧。 1、将arm-linux-gcc的压缩包arm-linux-gcc-2.95.3.tar.gz解压缩; 2、将路径usr/local下的arm目录拷贝到你自己系统的/usr/local下; 3、 1 方法一: vi /etc/profile;在出现pathmunge 的语句段后添加pathmunge /usr/local/arm/2.95.3(版本号)/bin; 保存对p
[单片机]
GCC编译器原理(三)------编译原理三:编译过程(3)---编译之汇编以及静态链接【2】
4.1.2 符号解析与重定位 (1)重定位 在完成空间和地址的分配步骤之后,链接器就进入了符号解析和重定位的步骤,这是静态链接的核心部分。 先看看 a.o 的反汇编文件: objdump -d a.o: 程序代码里面都是使用的虚地址,main 起始地址为 0 ,这是因为在未进行空间分配之前,目标文件代码段中的起始地址以 0x00000000 开始,等到空间分配完成之后,各个函数才会确定自己在虚拟地址空间中的位置。 从反汇编来看,a.o 中定义了一个函数 main,这个函数占 0x55 个字节,共 21 条指令。冒号前的代表每条指令的偏移量。 上面的 eax,esi 等为寄存器,在参数很少的情况下编译器会选择让寄存器来传递参数,
[单片机]
<font color='red'>GCC</font>编译器原理(三)------编译原理三:编译过程(3)---编译之汇编以及静态链接【2】
gcc基本常用选项
//====================================================== gcc和Linux gcc 的常用选项 gcc的使用方法 gcc 【选项】 文件名 gcc常用选项 gcc -v: 查看gcc编译器的版本,显示gcc执行时的详细过程 -o file please the output into file 指定文件名为file,这个名称不能和源文件名相同 -E preprocess only :do not compile ,assemble or link 只预处理 ,不会编译,汇编,链接
[单片机]
GCC常用参数大全
1. 头文件 象conio.h应该变成curses.h 2. 没有itoa函数 itoa?不对吧,标准C/C++里根本没有这个函数。即使在Windows平台下某些编译器提供了该函数 ,没有任何移植性不说,还只能解决int类型(也许其他函数还可以解决long、unsigned long等类型),浮点类型又怎么办?当然,办法还是有,那就是:sprintf。 char s ; sprintf(s, "%f", 123.123456); 3. 关于sqrt,sin和cos函数 就算是引入math.h头文件,也不会找到sqrt,sin和cos函数。应该用链接库来解决。 有时候我们使用了某个函数,但是我们不知道库的名字,这个时候怎么办呢
[嵌入式]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved