GNU工具链,gcc,binutils,glibc,libstdc++

GNU工具链,gcc,binutils,glibc,libstdc++
20121224 Chenxin
20140608 update Chenxin
Linux下GNU工具链相关的问题
GNU工具链GNU toolchain是一个包含了由GNU项目所产生的各种编程工具的集合.
这些工具形成了一条工具链(串行使用的一组工具),用于开发应用程序和操作系统.

GNU工具链中包含的项目:
GNU make:用于编译和构建的自动工具;
GNU 编译器集合GCC:一组多种编程语言的编译器;
GNU Binutils:包含链接器、汇编器和其它工具的工具集;
GNU Debugger(GDB):代码调试工具;
GNU构建系统(autotools):Autoconf Autoheader Automake Libtool
由于工具很多,所以不一一说明.注意:GNU toolchain并不只是指gcc,g++,ld这些.

GCC(GNU C Compiler 编译链接器)
gcc(gnu collect compiler)是一组编译工具的总称
gcc-3.4.3.tar.gz 包含了对几种语言的支持(c,c++,java,...)
gcc-ada-3.4.3.tar.gz 应该是ada编译器
gcc-core-3.4.3.tar.gz 在本论坛的某个地方说了,只是一个C编译器
gcc-g++-3.4.3.tar.gz C++编译器
当我们使用gcc时候,gcc将根据后缀来调用相应的编译器c、c++或ada等。如果加上 -x c 选项时,强制调用c编译器,-x c++调用c++编译器。
在gcc中不包含glibc和stdc++,如果使用了c或c++中的东东,在link的时候,就要加上相应的库glibc or stdc++。如果没有,就要自己编译。
建议,在特定的Linux版本下,不要重新编译gcc,因为多数情况下,系统依赖于glibc库.如果你改变了他们,你的系统将有crash的危险。
gcc 是编译器,基本上 Linux 下所有的程序(包括内核)都是 gcc 编译的,libc 也是。

GCC主要完成的工作任务是“预处理”和“编译”,以及 提供了与编译器紧密相关的运行库的支持, 如libgcc_s.so、libstdc++.so等。

Gcc 编译器能将C、C++语言源程序、汇程式化序和目标程序编译、连接成可执行文件.
gcc通过后缀来区别输入文件的类别.
.c为后缀的文件,C语言源代码文件;
.a为后缀的文件,是由目标文件构成的档案库文件;
.C,.cc或.cxx 为后缀的文件,是C++源代码文件;
.h为后缀的文件,是程序所包含的头文件;
.i 为后缀的文件,是已经预处理过的C源代码文件;
.ii为后缀的文件,是已经预处理过的C++源代码文件;
.m为后缀的文件,是Objective-C源代码文件;
.o为后缀的文件,是编译后的目标文件;
.s为后缀的文件,是汇编语言源代码文件;
.S为后缀的文件,是经过预编译的汇编语言源代码文件。

Gcc的执行过程
虽然我们称Gcc是C语言的编译器,但使用gcc由C语言源代码文件生成可执行文件的过程不仅仅是编译的过程,而是要经历四个相互关联的步骤∶
预处理(也称 预编译,Preprocessing)、
编译(Compilation)、
汇编(Assembly)和
连接(Linking)。
命令gcc首先 调用cpp进行预处理,在预处理过程中,对源代码文件中的文件包含(include)、预编译语句(如宏定义define等)进行分析。
接着调用cc1进行编译,这个阶段根据输入文件生成以.o为后缀的目标文件。汇编过程是针对汇编语言的步骤,调用as进行工作,一般来讲,.S为后缀的汇编语言源代码文件 和汇编、.s为后缀的汇编语言文件经过预编译和汇编之后都生成以.o为后缀的目标文件。当所有的目标文件都生成之后,gcc就调用ld来完成最后的关键性 工作,这个阶段就是连接。在连接阶段,所有的目标文件被安排在可执行程序中的恰当的位置,同时,该程序所调用到的库函数也从各自所在的档案库中连到合适的 地方。

binutils(是GCC编译工具内的一部分)
binutils提供了一系列用来创建、管理和维护二进制目标文件的工具程序.
如汇编as,连接ld,静态库归档ar,反汇编objdump,elf结构分析工具readelf,无效调试信息和符号的工具strip等.
通常,binutils与gcc是紧密相集成的,没有binutils的话,gcc是不能正常工作的.
在编译glibc新版本的时候,经常会碰到binutils too old的报错,而且无法解决,只能通过省级操作系统的方式.

libc,glibc(是标准库文件)(glibc可以理解为libc的升级或补充)
libc是c语言库(动态链接库),除了内核,基本上所有的程序都会直接或间接地调用到它.
gcc 也不例外,也要调用libc的库(linux下的所有命令几乎都要用到glibc库)。
glibc是gnu发布的libc库,也即c运行库。
glibc是linux系统中最底层的api(应用程序开发接口),几乎其它任何的运行库都会倚赖于glibc。
glibc除了封装linux操作系统所提供的系统服务(系统指令)外,它本身也提供了许多其它一些必要功能服务的实现.
主要的如下(glibc):
(1)string,字符串处理
(2)signal,信号处理
(3)dlfcn,管理共享库的动态加载
(4)direct,文件目录操作
(5)elf,共享库的动态加载器,也即interpreter
(6)iconv,不同字符集的编码转换
(7)inet,socket接口的实现
(8)intl,国际化,也即gettext的实现
(9)io
(10)linuxthreads
(11)locale,本地化
(12)login,虚拟终端设备的管理,及系统的安全访问
(13)malloc,动态内存的分配与管理
(14)nis
(15)stdlib,其它基本功能

glibc和libc都是Linux下的C函数库,那么到底有什么区别呢?
libc是Linux下的ANSI C的函数库;
glibc是Linux下的GUN C函数库;
ANSI C和GNU C有什么区别呢?
ANSI C是基本的C语言函数库,包含了C语言最基本的库函数。 这个库可以根据 头文件划分为 15 个部分,其中包括:
字符类型 (<ctype.h>)、
错误码 (<errno.h>)、
浮点常数 (<float.h>)、
数学常数 (<math.h>)、
标准定义 (<stddef.h>)、
标准 I/O (<stdio.h>)、
工具函数 (<stdlib.h>)、
字符串操作 (<string.h>)、
时间和日期 (<time.h>)、
可变参数表 (<stdarg.h>)、
信号 (<signal.h>)、
非局部跳转 (<setjmp.h>)、
本地信息 (<local.h>)、
程序断言 (<assert.h>) 等等。这在其他的C语言的IDE中都是有的。
而GNU C函数库(glibc)是一种类似于第三方插件的东西.
由于Linux是用C语言写的,所以Linux的一些操作是用C语言实现的,所以GNU组织开发了一个C语言的库用于我们更好的利用C语言开发基于Linux操作系统的程序.
其实我们可以把glibc理解为类似于Qt是一个C++的第三方函数库一样.

GCC和libc或glibc的关系
gcc和libc是互相依赖的,它们合作的方式类似Linux系统的 "自举".
先在一个可以运行的带有老libc和 gcc的系统上,用老gcc 编译出一个新版本的gcc+老libc.
再用这个新gcc 编译出一个新gcc+新libc,再用这套东东编译整个新系统(操作系统都要重新编译了...).

posted @ 2020-04-21 13:07  ChanixChen  阅读(1301)  评论(0)    收藏  举报