分享

转:GCC、ARM-LINUX-GCC、ARM-ELF-GCC浅析

 yangshiquan 2011-05-03

转:GCC、ARM-LINUX-GCC、ARM-ELF-GCC浅析

(2011-01-05 20:55:26)
标签:

杂谈

分类: ARM

一、GCC简介:

The GNU Compiler Collection,通常简称GCC,是一套由GNU开发的编译器集,为什么是编辑器集而不是编译器呢?那是因为它不仅支持C语言编译,还支持C++, Ada, Objective C等许多语言。另外GCC对硬件平台的支持,可以所无所不在,它不仅支持X86处理器架构还支持ARM, Motorola 68000, Motorola 8800, Atmel AVR, MIPS等处理器架构。

 

二、GCC内部结构:

GCC内部结构主要由Binutilsgcc-coreGlibc等软件包组成。

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

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

3. Glibc:包含了主要的c库,这个库提供了基本的例程,用于分配内存,搜索目录,读写文件,字符串处理等等。【这个包GCC编译生成的库,前辈们为了方便大家开发,就把Glibc放到GCC中】

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

#include<stdio.h>

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

{

printf("Hello Linux!!\n");

 

return 0;

}

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

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

 

三、GCC的安装:

既然GCC本身就是一个软件集合,那么这些软件集合又怎么安装呢,因为这个过程很复杂,我也没有安装过,但这个不是本文的重点,就不讲了。不过网上的Linux彻底定制指南》讲得非常详细,感兴趣的可以看一看。

 

 

四、交叉编译:

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

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

使用如下命令编译并测试这个代码:

 arm-linux-gcc -o hello hello.c

 

五、arm-linux-gcc

arm-linux-gcc是基于ARM目标机的交叉编译软件,前面几年安装arm-linux-gcc交叉编译软件对与一个初级嵌入式工程师来说特别棘手,因为它需要安装多个软件包,而且安装过程中不能有半点差错,因为每个软件包都有它的依赖关系【换句话就是说安装某个软件包时,如果它的依赖软件版本太低或者没有安装都将导致该软件包安装失败】;嗯,废话不说了,入正题,下面是我摘自创建ARMlinux交叉编译环境的实践的一部分,详细的安装过程请参考原文或GOOGLE搜索之。

......

 1、源文件准备 
         binutils-2.14.tar.gz  
         ftp://ftp.gnu.org/gnu/binutils/binutils-2.14.tar.gz 
         gcc-core-2.95.3.tar.gz  
         ftp://ftp.gnu.org/gnu/gcc/gcc-2.95.3/gcc-core-2.95.3.tar.gz 
         gcc-g++2.95.3.tar.gz  
         ftp://ftp.gnu.org/gnu/gcc/gcc-2.95.3/gcc-g++-2.95.3.tar.gz 
         glibc-2.2.4.tar.gz  
         ftp://ftp.gnu.org/gnu/glibc/glibc-2.2.4.tar.gz 
         glibc-linuxthreads-2.2.4.tar.gz  
         ftp://ftp.gnu.org/gnu/glibc/glibc-linuxthreads-2.2.4.tar.gz 
         linux-2.4.21.tar.gz 
         ftp://ftp.kernle.org/pub/linux/kernel/v2.4/linux-2.4.21.tar.gz 
         patch-2.4.21-rmk1.gz linux kernel patch for arm 
         ftp://ftp.arm.linux.org.uk/pub/l ... atch-2.4.21-rmk1.gz 
      
    binutils-2.14.tar.gz这个压缩包包含有ld,ar,as等一些产生或者处理二进制文件的工具。 
    gcc-core-2.95.3.tar.gz这个压缩包是GCC的主体部分,GCC是GNU Compiler Collection的简称,顾名思义,它能够编译很多种高级语言,例如C、C++,Java等,而这个压缩包中含有C编译器,及公共部分,而对其他语言的支持,采用另外的压缩包单独发布。 
    gcc-g++2.95.3.tar.gz,这个压缩包就是为使GCC能够编译C++程序而单独发布的。 
    glibc-2.2.4.tar.gz,libc是很多用户层应用都要用到的库,kernel和bootloader不需要这个库的支持,这个库主体部分封装在这个压缩包内。 
    glibc-linuxthreads-2.2.4.tar.gz,这是Libc用于支持Posix线程而单独发布的一个压缩包。 
    linux-2.4.21.tar.gz,这个压缩包就是Linux的内核。 
    patch-2.4.21-rmk1.gz,这个压缩包是用来给Linux内核打补丁,以使其可以支持ARM的硬件平台。  

......

可以看出arm-linux-gccGCC所需的安装包的名字大同小易,可这是为什么呢?不知道网友没有想到过这个问题,可能网友知道这些包跟GCC所用的包是不相同的,仅仅名字不一样而已,但是知道为什么不一样恐怕还是有相当多的人不清楚。个人认为要了解arm-linux-gccGCC的关系和区别,这个问题才是关键所在。好了,不卖关子了,入正题,因为我们知道X86ARM所使用的指令集是不一样的,所以所需要的binutils肯定不一样咯;上面提到过gcc-core是依赖于binutils的,自然ARM跟X86所使用的gcc-core包也不一样;glibc一个c库,最终是以库的形式存在于编译器中,自然ARM所使用的glibc库跟X86同样也是不一样的咯,其它的依此类推。

 

六、arm-linux-gccarm-elf-gcc:

arm-elf-gccarm-linux-gcc一样,也是是基于ARM目标机的交叉编译软件。但是它们不是同一个交叉编译软件,两者是有区别的,两者区别主要在于使用不同的C库文件。arm-linux-gcc使用GNUGlibc,而arm-elf-gcc一般使用 uClibc/uC-libc或者使用REDHAT专门为嵌入式系统的开发的Cnewlib关于两者的区别,请参考arm-linux-gcc  arm-elf-gcc区别

 

七、参考资料

 工具链技术说明

 Gcc编译流程解析

 Linux高级程序设计》中的交叉编译

 创建ARMlinux交叉编译环境的实践

 arm-linux-gcc  arm-elf-gcc区别

 

 

 

在基于ARM的嵌入式系统开发中,常常用到交叉编译的GCC工具链有两种:arm-linux-*和 arm-elf-*,两者区别主要在于使用不同的C库文件。

arm-linux-*使用GNU的Glibc,而arm-elf-*一般使用 uClibc/uC-libc或者使用REDHAT专门为嵌入式系统的开发的C库newlib.Glibc。
uClibc/uC-libc以及 newlib都是C语言库文件,只是所应用的领域不同而已

Glibc是针对PC开发的,uClibc/uC-libc是与Glibc API兼容的小型化C语言库,实现了Glibc部分功能。

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也几乎和所有的平台都能很好的工作。选择哪种libc取决于你的需求。

newlib 是一个用于嵌入式系统的开放源代码的C语言程序库,由libc和libm两个库组成,特点是轻量级,速度快,可移植到很多CPU结构上。newlib实现了许多复杂的功能,包括字符串支持,浮点运算,内存分配(如malloc)和I/O流函数(printf,fprinf()等等)。其中libc提供了c 语言库的实现,而libm提供了浮点运算支持。

在为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
t-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等能使得系统程序更加小巧快捷。

zz:http://hi.baidu.com/zybuaa/blog/item/2817f1faac4f25dcb48f3146.html

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多