gnu与gcc含义的解释.docx
《gnu与gcc含义的解释.docx》由会员分享,可在线阅读,更多相关《gnu与gcc含义的解释.docx(11页珍藏版)》请在冰豆网上搜索。
gnu与gcc含义的解释
GNU是Gnu'sNotUnix的缩写,那么Gnu'sNotUnix里面的Gnu是什么意思,Gnu'sNotUnix里的Gnu同GNU。
这个是递归。
GNU就是GNU'sNotUnix的缩写,GNU的创始人Stallman认为UNIX虽然不是最好的操作系统,但是至少不会太差,而他自信有能力把UNIX不足的地方加以改进,使它成为一个优良的操作系统,就是名为GNU的一个同UNIX兼容的操作系统,并且开发这个系统的目的就是为了让所有计算机用户都可以自由地获得这个系统。
任何人都可以免费地获得这个系统的源代码,并且可以相互自由拷贝。
因而在使用GNU软件的时候我们可以理直气壮地说我们使用的是正版软件。
当然GNU也是有自己的版权声明(即GPL,见附录A)的,就是它有名的Copyleft(相对于版权的英文Copyright),就是用户获得GNU软件后可以自由使用和修改,但是用户在散布GNU软件时,必须让下一个用户有获得源代码的权利并且必须告知他这一点。
这一条看似古怪的规定是为了防止有些别有用心的人或公司将GNU软件稍加修改就去申请版权,说成是自己的产品。
其目的就是要让GNU永远是免费和公开的。
GNU是谁发起的?
GNU是由自由软件基金会(FreeSoftwareFoundation,FSF)的董事长RichardM.Stallman(RMS)于1984年发起的,如今已经有十几年的历史了。
Stallman本来是在美国麻省理工学院的人工智能实验室从事研究工作的研究员,同时也是世界上可数的几个顶尖程序员之一,他的最著名的作品也是GNU的第一个软件就是GNUEmacs,UNIX平台上的一个编辑器。
这个软件推出后受到广大UNIX用户的热烈欢迎,由于它同时提供源代码,大家都热心地替它排除错误,增加功能,它的功能越来越强大,终于成为UNIX平台上最好的编辑器,上至CRAY超级计算机,下至最普遍的PC机,从DOS到Windows,从VMS到UNIX都可以使用这个Emacs。
受到这个软件成功的鼓励,Stallman成立了自由软件基金会,以推广GNU计划。
基金会成立之后,主要靠一些厂家的捐献和出售GNU程序的使用手册,以及拷贝GNU软件的电脑磁带和光盘来维持,不过许多硬件厂家开始基金会提供高性能的工作站,这其中包括HP和SONY,AT&T这样的国际性大公司。
GNU目前已经推出的软件主要由Emacs──功能强大的编辑环境,GCC──性能优异的多平台的C,C++,Fortran编译器和其他40多种软件。
其中GCC的成功为GNU带来了前所未有的影响。
GCC是一种可以在11种硬件平台上编译出可执行程序的超级编译器,而且其执行效率更是惊人,与一般的编译器相比平均效率要高20%-30%。
这使得很多商业公司也采用GCC来开发软件,其中包括像HP公司这样的专业大公司。
而现在回到苹果公司的前NeXT公司总裁斯蒂夫·乔布斯也对Stallman尊敬有加,因为NeXT公司的软件都是用GCC开发的,在PC游戏中最好的3D射击游戏quake(由IDSoftware公司开发)也是用GCC的DOS移植版本djgpp编写的。
GCC是C,C++,ObjectiveC(由NeXT公司贡献)三者合一的编译器,它的编译原理同大多数编译器不一样,它先有一个前端处理程序将C,C++,OvjectiveC的语句转换成为一个类似于Lisp的内部语言--RTL,再由一个后端处理程序将其优化后产生目的CPU可以执行的机器代码,因而对于每种新语言来说,只要写好一个新的前端处理程序就可以立刻将此语言移植到GCC已经支持的不同硬件平台上去,而且编译出来的就已经是经过优化的二进制代码。
除了C系列以外,GCC还有Fortran77,ada9x,Pascal的前端处理程序。
GCC的多平台的实现方法同JAVA的虚拟机技术不太一样,因而其运行速度远非JAVA能望其项背。
GNU开始的策略就是先开发UNIX已经有的程序(因为计划中GNU将会是一个与UNIX兼容的操作系统,而UNIX下的标准使用界面已经非常完善了,所以先依照这个标准开发应用程序,将来GNU自己的系统核心一出来,就立即可以使用所有先前开发的GNU应用程序),因此会先有emacs,GCC等工具软件开发出来。
其中GCC更是GNU计划自立更生的一个重要步骤(不需要依靠商业软件来产生/编译整个GNU系统),如今这套程序开发工具已经很成熟了。
下一步要做的就是开发GNU的核心--Hurd了,只要Hurd一开发出来,GNU就是一套能够自我开机,真正自给自足,完整的自由操作系统。
Hurd是基于Mach这个微内核(microkernel)上的操作系统核心。
以后会使用尤他大学的Mach4(一个更为方便和快速的微内核),由于Hurd基于Mach,所以只要Mach移植到什么机器上,Hurd也立刻就是这种硬件平台的操作系统,就这一点而言,它是一种很前卫的操作系统。
但是Linux在短短的几年内崛起,也使用GNU的版权声明,大有取代Hurd之势。
在网络上甚至有不少人认为Hurd应该停止开发,因为Linux系统已经十分成熟,GNU实际上可以使用Linux当作核心,也能构成一套完整的操作系统。
甚至连自由软件基金会的技术人员也承认,要是Linux早几年出现,也许就不用发展Hurd了。
但是Linux还是晚了一步,Hurd已经计划很久了,技术上有很多非常领先的地方,能够支持的硬件平台也比Linux多,不完成就太可惜了。
1994年11月,Hurd的第一个雏形已经发表;1995年4月,也发表了第二次snapshot。
Hurd目前的版本是0.2,是1997年6月发布的,已经可以独立安装与稳定运行了,GNU版本的Mach目前的版本是1.1.3。
与此同时,已经开发出一个基于微内核的Linux版本了,目前有一个可以在HP-PARISC机器上运行的Linux系统。
实际上,自由软件基金会目前有一套以Linux为核心的GNU系统计划。
这个计划就是自由软件基金会支持的DebianLinux。
DebianLinux是GNU软件与公共软件(PublicDomainSoftware)最彻底的结合,它是一套完全由GNU和公共软件配置起来的,而且具有商业操作系统水平的操作系统。
注一:
POSIX(PortableOperatingSystemInterface)标准操作系统界面。
注二:
按照编程人员的习惯,一个软件在第一次推出前的所有测试版本都不能称作1.0版,只能叫作0.3,0.7,0.99版,其数目越接近1,就表明其越来越接近正式发布
1、用于linux系统下编程的编译器
概述
GCC(GNUCompilerCollection,GNU编译器套装),是一套由GNU开发的编程语言编译器。
它是一套GNU编译器套装。
以GPL及LGPL许可证所发行的自由软件,也是GNU计划的关键部分,亦是自由的类Unix及苹果电脑MacOSX操作系统的标准编译器。
GCC原名为GNUC语言编译器,因为它原本只能处理C语言。
GCC很快地扩展,变得可处理C++。
之后也变得可处理Fortran、Pascal、Objective-C、Java,以及Ada与其他语言。
历史
GCC是由理查德·马修·斯托曼在1985年开始的。
他首先扩增一个旧有的编译器,使它能编译C,这个编译器一开始是以Pastel语言所写的。
Pastel是一个不可移植的Pascal语言特殊版,这个编译器也只能编译Pastel语言。
为了让自由软件有一个编译器,后来此编译器由斯托曼和LenTower在1987年以C语言重写并成为GNU专案的编译器。
GCC的建立者由自由软件基金会直接管理。
在1997年,一群不满GCC缓慢且封闭的创作环境者,组织了一个名为EGCS〈Experimental/EnhancedGNUCompilerSystem〉的专案,此专案汇整了数项实验性的分支进入某个GCC专案的分支中。
EGCS比起GCC的建构环境更有活力,且EGCS最终也在1999年四月成为GCC的官方版本。
GCC目前由世界各地不同的数个程序设计师小组维护。
它是移植到中央处理器架构以及操作系统最多的编译器。
由于GCC已成为GNU系统的官方编译器(包括GNU/Linux家族),它也成为编译与建立其他操作系统的主要编译器,包括BSD家族、MacOSX、NeXTSTEP与BeOS。
GCC通常是跨平台软件的编译器首选。
有别于一般局限于特定系统与执行环境的编译器,GCC在所有平台上都使用同一个前端处理程序,产生一样的中介码,因此此中介码在各个其他平台上使用GCC编译,有很大的机会可得到正确无误的输出程序。
结构
GCC的外部接口长得像一个标准的Unix编译器。
使用者在命令列下键入gcc之程序名,以及一些命令参数,以便决定每个输入档案使用的个别语言编译器,并为输出程序码使用适合此硬件平台的组合语言编译器,并且选择性地执行连结器以制造可执行的程序。
每个语言编译器都是独立程序,此程序可处理输入的原始码,并输出组合语言码。
全部的语言编译器都拥有共通的中介架构:
一个前端解析符合此语言的原始码,并产生一抽象语法树,以及一翻译此语法树成为GCC的暂存器转换语言〈RTL〉的后端。
编译器最佳化与静态程序码解析技术(例如FORTIFY_SOURCE,一个试图发现缓冲区溢位〈bufferoverflow〉的编译器)在此阶段应用于程序码上。
最后,适用于此硬件架构的组合语言程序码以JackDavidson与ChrisFraser发明的算法产出。
几乎全部的GCC都由C写成,除了Ada前端大部分以Ada写成。
前端接口
前端的功能在于产生一个可让后端处理之语法树。
此语法解析器是手写之递回语法解析器。
直到最近,程序的语法树结构尚无法与欲产出的处理器架构脱钩。
而语法树的规则有时在不同的语言前端也不一样,有些前端会提供它们特别的语法树规则。
在2005年,两种与语言脱钩的新型态语法树纳入GCC中。
它们称为GENERIC与GIMPLE。
语法解析变成产生与语言相关的暂时语法树,再将它们转成GENERIC。
之后再使用"gimplifier"技术降低GENERIC的复杂结构,成为一较简单的静态唯一形式(StaticSingleAssignmentform,SSA)基础的GIMPLE形式。
此形式是一个与语言和处理器架构脱钩的全域最佳化通用语言,适用于大多数的现代编程语言。
中介接口
一般编译器作者会将语法树的最佳化放在前端,但其实此步骤并不看语言的种类而有不同,且不需要用到语法解析器。
因此GCC作者们将此步骤归入通称为中介阶段的部分里。
此类的最佳化包括消解死码、消解重复运算与全域数值重编码等。
许多最佳化技巧也正在实作中。
后端接口
GCC后端的行为因不同的前处理器宏和特定架构的功能而不同,例如不同的字符尺寸、呼叫方式与大小尾序等。
后端接口的前半部利用这些讯息决定其RTL的生成形式,因此虽然GCC的RTL理论上不受处理器影响,但在此阶段其抽象指令已被转换成目标架构的格式。
GCC的最佳化技巧依其释出版本而有很大不同,但都包含了标准的最佳化算法,例如循环最佳化、执行绪跳跃、共通程序子句消减、指令排程等等。
而RTL的最佳化由于可用的情形较少,且缺乏较高阶的资讯,因此比较起近来增加的GIMPLE语法树形式[2],便显得比较不重要。
后端经由一重读取步骤后,利用描述目标处理器的指令集时所取得的资讯,将抽象暂存器替换成处理器的真实暂存器。
此阶段非常复杂,因为它必须关照所有GCC可移植平台的处理器指令集的规格与技术细节。
后端的最后步骤相当公式化,仅仅将前一阶段得到的组合语言码藉由简单的副函式转换其暂存器与内存位置成相对应的机械码。
基本规则
gcc所遵循的部分约定规则:
.c为后缀的文件,C语言源代码文件;
.a为后缀的文件,是由目标文件构成的档案库文件;
.C,.cc或.cxx为后缀的文件,是C++源代码文件;
.h为后缀的文件,是程序所包含的头文件;
.i为后缀的文件,是已经预处理过的C源代码文件;
.ii为后缀的文件,是已经预处理过的C++源代码文件;
.m为后缀的文件,是Objective-C源代码文件;
.o为后缀的文件,是编译后的目标文件;
.s为后缀的文件,是汇编语言源代码文件;
.S为后缀的文件,是经过预编译的汇编语言源代码文件。
执行过程
虽然我们称Gcc是C语言的编译器,但使用gcc由C语言源代码文件生成可执行文件的过程不仅仅是编译的过程,而是要经历四个相互关联的步骤∶预处理(也称预编译,Preprocessing)、编译(Compilation)、汇编(Assembly)和链接(Linking)。
命令gcc首先调用cpp进行预处理,在预处理过程中,对源代码文件中的文件包含(include)、预编译语句(如宏定义define等)进行分析。
接着调用cc1进行编译,这个阶段根据输入文件生成以.o为后缀的目标文件。
汇编过程是针对汇编语言的步骤,调用as进行工作,一般来讲,.S为后缀的汇编语言源代码文件和汇编、.s为后缀的汇编语言文件经过预编译和汇编之后都生成以.o为后缀的目标文件。
当所有的目标文件都生成之后,gcc就调用ld来完成最后的关键性工作,这个阶段就是连接。
在连接阶段,所有的目标文件被安排在可执行程序中的恰当的位置,同时,该程序所调用到的库函数也从各自所在的档案库中连到合适的地方。
基本用法
在使用Gcc编译器的时候,我们必须给出一系列必要的调用参数和文件名称。
Gcc编译器的调用参数大约有100多个,其中多数参数我们可能根本就用不到,这里只介绍其中最基本、最常用的参数。
Gcc最基本的用法是∶gcc[options][filenames]
其中options就是编译器所需要的参数,filenames给出相关的文件名称。
-c,只编译,不连接成为可执行文件,编译器只是由输入的.c等源代码文件生成.o为后缀的目标文件,通常用于编译不包含主程序的子程序文件。
-ooutput_filename,确定输出文件的名称为output_filename,同时这个名称不能和源文件同名。
如果不给出这个选项,gcc就给出预设的可执行文件a.out。
-g,产生符号调试工具(GNU的gdb)所必要的符号资讯,要想对源代码进行调试,我们就必须加入这个选项。
-O,对程序进行优化编译、连接,采用这个选项,整个源代码会在编译、连接过程中进行优化处理,这样产生的可执行文件的执行效率可以提高,但是,编译、连接的速度就相应地要慢一些。
-O2,比-O更好的优化编译、连接,当然整个编译、连接过程会更慢。
-Idirname,将dirname所指出的目录加入到程序头文件目录列表中,是在预编译过程中使用的参数。
C程序中的头文件包含两种情况∶
A)#include
B)#include“myinc.h”
其中,A类使用尖括号(<>),B类使用双引号(“”)。
对于A类,预处理程序cpp在系统预设包含文件目录(如/usr/include)中搜寻相应的文件,而B类,预处理程序在目标文件的文件夹内搜索相应文件。
GCC执行过程示例
示例代码a.c:
#include
intmain()
{
printf("hello\n");
}
预编译过程:
这个过程处理宏定义和include,并做语法检查。
可以看到预编译后,代码从5行扩展到了910行。
gcc-Ea.c-oa.i
cata.c|wc-l
5
cata.i|wc-l
910
编译过程:
这个阶段,生成汇编代码。
gcc-Sa.i-oa.s
cata.s|wc-l
59
汇编过程:
这个阶段,生成目标代码。
此过程生成ELF格式的目标代码。
asa.s-oa.o
filea.o
a.o:
ELF64-bitLSBrelocatable,AMDx86-64,version1(SYSV),notstripped
链接过程:
链接过程。
生成可执行代码。
链接分为两种,一种是静态链接,另外一种是动态链接。
使用静态链接的好处是,依赖的动态链接库较少,对动态链接库的版本不会很敏感,具有较好的兼容性;缺点是生成的程序比较大。
使用动态链接的好处是,生成的程序比较小,占用较少的内存。
gcca.o-oa
程序运行:
./a
hello
GCC编译简单例子
编写如下代码:
#include
intmain()
{
printf("hello,world!
\n");
}
执行情况如下:
wenjun@ubuntu:
~/temp/01$gcchello.c-ohello
wenjun@ubuntu:
~/temp/01$ls
hellohello.c
wenjun@ubuntu:
~/temp/01$./hello
hello,world!
目前支持的语言
以2006年5月24日释出的4.1.1版为准,本编译器版本可处理下列语言:
Ada〈GNAT〉
C〈GCC〉
C++(G++)
Fortran〈Fortran77:
G77,Fortran90:
GFORTRAN〉
Java〈编译器:
GCJ;解释器:
GIJ〉
Objective-C〈GOBJC〉
Objective-C++
先前版本纳入的CHILL前端由于缺乏维护而被废弃。
Fortran前端在4.0版之前是G77,此前端仅支援Fortran77。
在本版本中,G77被废弃而采用更新的GFortran,因为此前端支援Fortran95。
下列前端依然存在:
Modula-2
Modula-3
Pascal
PL/I
D语言
Mercury
VHDL
支援的处理器架构
GCC目前支援下列处理器架构(以4.1版为准):
Alpha
ARM
AtmelAVR
Blackfin
H8/300
IA-32〈x86〉与x86-64
IA-64例如:
Itanium
MorphoSys家族
Motorola68000
Motorola88000
MIPS
PA-RISC
PDP-11
PowerPC
System/370,System/390
SuperH
HC12
SPARC
VAX
RenesasR8C/M16C/M32C家族
较不知名的处理器架构也在官方释出版本中支援:
A29K
ARC
C4x
CRIS
D30V
DSP16xx
FR-30
FR-V
Inteli960
IP2000
XX文库-让每个人平等地提升自我 M32R
68HC11
MCORE
MMIX
MN10200
MN10300
NS32K
ROMP
Stormy16
V850
Xtensa
由FSF个别维护的GCC处理器架构:
D10V
MicroBlaze
PDP-10
MSP430
Z8000
当GCC需要移植到一个新平台上,通常使用此平台固有的语言来撰写其初始阶段。
为GCC程序除错
为GCC除错的首选工具当然是GNU除错器。
其他特殊用途的除错工具是Valgrind,用以发现内存漏失(Memoryleak)。
而GNU测量器(gprof)可以得知程序中某些函式花费多少时间,以及其呼叫频率;此功能需要使用者在编译时选定测量〈profiling〉选项。
GCC编译器的使用
首先检查是否在你的机器上安装了GCC,使用命令:
可用rpm-qgcc 检查。
如果没有安装,请依序检查并安装下面各RPM
libbinutils
binutils
make
glibc-devel
gcc-cpp
gcc
看下面的例子:
test.c
#include
main()
{char*str="IlikeLinux!
IadvicesyoujionintheLinuxWorld";
printf("%s",str);
exit(0);
}
使用gcc编译。
输入gcc-ctest.c得到目标文件test.o.-c命令表示对文件进行编译和汇编。
但并不连接。
如果再健入gcc-o../bin/testtest.o,那么将得到名为test的可执行文件。
其实这两不可以一气呵成,gcc../bin/testtest.c.如果程序没有错误救生成了可执行文件。
也许你会觉得基于命令行的编译器比不上如VC之类的集成开发环境,的确gcc的界面要改进,但是你一旦熟练了就会感到。
gcc的效率如此之高。
可以告诉大家的是Linux底下强大的C/C++集成开发环境Kdevelope和Vc一样强大,使用了Gcc编译器。
GNUC编译器即gcc是一个功能强大的ANSIC兼容编译器,你会操作其他操作系统下的一种C编译器,能很快掌握GCC,我也是学了不久的GCC.
1、使用Gcc,Gcc是基于命令行的,使用时通常后跟一些选项和文件名。
Gcc的基本用法如下:
gcc[options][filenames]命令行选项制定操作将对命令行上的每个给出的文件执行。
2、GCC的常用选项
编译选项:
gcc有超过100个的编译选项可用。
具体的可以使用命令mangcc察看
优化选项:
用GCC编译C/C++代码时,它会试着用最少的时间完成编译并且编译后的代码易于调试。
易于调试意味着编译后的代码与源代码有同样的执行顺序,编译后的代码没有经过优化。
有很多的选想可以告诉GCc在耗费更多编译时间和牺牲易调试性的基础上产生更小更快的可执行文件。
这些选项中最典型的就是-O和-O2。
-O选项告诉gcc对源代码进行基本优化。
-O2选项告诉Gcc产生尽可能小的和尽可能快的代码。
还有一些很特殊的选项可以通过mangcc察看。
调试和剖析选项:
GCC支持数种调试剖析选项。
在这些选项中最常用的是-g和-pg.