一、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 等软件包组成。

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

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

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

举例描述下上面 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 是如何工作的。

三、交叉编译

交叉编译(或交叉建立)是这样一种过程,它在一种机器结构下编译的软件将在另一种完全不同的机器结构下执行。一个常见的例子是在 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等能使得系统程序更加小巧快捷。


http://www.taodudu.cc/news/show-1060225.html

相关文章:

  • Linux应用编程之共享内存实例
  • void 型指针的高阶用法,你掌握了吗?
  • 电子美图更新36张!
  • STM32F0单片机快速入门八 聊聊 Coolie DMA
  • 操作系统中抢占式和非抢占式内核的区别
  • 劝你要看一些有门槛的机会
  • ESP32,使用gitee搭建 ESP-IDF 开发框架
  • Linux kernel之SMP初始化
  • MTK笔试1题~
  • 从单片机步入Linux之运行地址与加载地址
  • 不要错过秋招
  • 工作后和在学校最大的区别是什么?
  • Kernel中如何操作CPU及外设寄存器
  • 帮一个读者解锁手机
  • 由c语言转向c++,我们需要做什么?
  • Cmake确实应该用到的时候再学
  • vscode 使用 ssh 登录
  • Linux内核工程师是怎么步入内核殿堂的?
  • 时间同步绝对是一个大问题
  • 嵌入式真的没前途?
  • 前凸后翘的步进电机调速算法~
  • 我是在这里学到的Linux知识的
  • 最近的生活
  • 学习 Linux/C/C++ 必备资料
  • 用GPIO口模拟串口通信,它真的来了
  • 现在的年轻人,正在努力的改变着一些东西
  • 我们是怎样发出声音的?
  • 运行地址与加载地址估计大部分人没弄明白~
  • 我妈在深圳的这些日子
  • 分享一个剪切板的小软件CopyQ

gcc、arm-linux-gcc和arm-elf-gcc的关系?相关推荐

  1. arm linux cpu优化,ARM CPU与Intel x86 CPU性能比较

    原标题:ARM CPU与Intel x86 CPU性能比较 随着移动互联网时代的到来,Qualcomm(高通).Texas Instruments(德州仪器)等基于 架构的 受到越来越多人的关注,而昔 ...

  2. arm linux php,在ARM Linux系统上面安装Apache+sqlite+PHP的详细讲解 - Apache - 数安时代(GDCA)SSL证书官网...

    经过几天的努力终于在arm-linux平台上搭建了apache+sqlite+php平台. apche与sqlite网上有不少资料,而php for arm-linux很少.为了在arm平台上安装ph ...

  3. arm linux建站,arm服务器做虚拟机(arm平台虚拟机)

    arm开发板用网络文件系统nfs连接到虚拟机上 出现了如图的问题 主机 虚拟机. 检查下你的linux虚拟机得ip配置,nfs要求ip在一个段.在检查下linux虚拟机得nfs服务打开没有,开发板手册 ...

  4. opengl arm linux,开源头条 | ARM v9架构发布

    ARM v9架构发布 Arm昨日发布ARMv9架构,专注于高性能计算.机器学习.数字信号处理和安全 性. ARMv9引入了Arm的Confidential Compute Architecture(C ...

  5. 嵌入式arm linux产品,基于ARM——Linux的嵌入式产品平台构建

    摘要: 随着计算机技术的发展,嵌入式系统已成为计算机领域一个重要组成部分,并成为近年来新兴的研究热点.ARM7TDMI是一种高效,低功耗的RISC处理器,以该内核为核心的 LPC2210 是一款基于以 ...

  6. arm linux sms,基于arm处理器的手机短消息加密系统 encryption system for sms based on arm.pdf...

    基于arm处理器的手机短消息加密系统 encryption system for sms based on arm 第 22卷 第 期 电子测量与仪器学报 Vol.22 No.2 2 4 - - 20 ...

  7. arm linux 加密锁,ET ARM 标准锁(包含网络锁功能)

    ET ARM高端加密锁采用高强度32位ARM智能卡芯片,彻底杜绝硬件复制.通过最先进的锁内编程技术(C语言语法),同时锁内代码本地运行(即在智能卡芯片上直接执行,而非虚拟机内执行,锁内程序执行速度最快 ...

  8. arm linux考勤,基于ARM与Linux员工刷卡考勤系统毕业论文.doc

    PAGE 北华航天工业学院毕业论文 毕业设计报告(论文) 报 告 题 目 : 基于ARM与Linux的 员工刷卡考勤系统 作者所在系部: 计算机科学与工程系 作者所在专业: 计算机科学与技术 作者所在 ...

  9. arm -linux开发产品,arm是什么意思_arm的翻译_音标_读音_用法_例句_爱词霸在线词典...

    全部 四级 六级 高考 考研 Familiar consumer products are being adopted by businesses, government and the armed ...

  10. arm linux 俄罗斯方块,基于ARM的俄罗斯方块游戏的开发教材.doc

    学号: 常 州 大 学 毕业设计(论文) (2012届) 题 目 学 生 学 院 专业班级 校内指导教师 专业技术职务 校外指导老师 专业技术职务 二○ 基于ARM的俄罗斯方块游戏的开发 摘 要:随着 ...

最新文章

  1. R 包 pathview 代谢通路可视化
  2. 基于jquery的无刷新表格分页
  3. php用switch编写车费的输出,PHP Switch语句在实际代码中的应用
  4. 跟我学AI建模:分子动力学仿真模拟之DeepMD-kit框架
  5. 从JSP WEB页面往数据库写入出现乱码的一种解决方法
  6. 抑郁症是不可告人的病吗?
  7. 男性玩家占78.8%、90后玩家占近50%、最多人选择中国风链游……《2019链游玩家需求调研报告》重磅发布!...
  8. Cinder组件解析
  9. 数据挖掘技术的来源 历史 研究内容及常用技术
  10. 贪心算法适用条件_贪心算法
  11. 小米笔记本android,小米笔记本同步助手下载
  12. SSRF漏洞理解进阶SSRF+gopher打内网(redis、mysql、fastcgi) SSRF相关基础概念
  13. Java连接wincc_WinCC中访问SQL SERVER数据库
  14. 最简行阶梯矩阵生成器
  15. 马克飞象怎么转成html,马克飞象教程
  16. 深度好文!多年架构师经验,详解阿里内部大数据平台架构
  17. CSP201609-3炉石传说
  18. 为什么小样本不建议用深度学习?
  19. java实现网上招标系统
  20. Java使用Jsoup爬虫获取网站内容(三)获取元素内容属性的方法

热门文章

  1. Bossie Awards 2015: The best open source applicati
  2. 经验:Windows To Go准备工作
  3. java样式是什么_java css样式 css样式的种类 选择器 文本相关样式 背景相关样式 边框 盒子模式...
  4. r语言做断轴_R语言用nls做非线性回归以及函数模型的参数估计
  5. processing动态代码大全_做一张动态海报需要多少步?
  6. 445端口 mysql_关于如何关闭window端口445的详细介绍
  7. CNN的发展历史(LeNet,Alexnet,VGGNet,GoogleNet,ReSNet)
  8. 立体匹配十大概念综述---立体匹配算法介绍
  9. 面试题:找出公司员工最喜欢的k种水果
  10. uboot将命令结构体单独存放在某个代码段的方法