Gcc的编译流程分为了四个步骤:
Gcc的编译流程分为了四个步骤:
1.预处理,⽣成预编译⽂件(.⽂件):
Gcc –E hello.c –o hello.i
2.编译,⽣成汇编代码(.s⽂件):
Gcc –S hello.i –o hello.s
3.汇编,⽣成⽬标⽂件(.o⽂件):
Gcc –c hello.s –o hello.o
4.链接,⽣成可执⾏⽂件:
Gcc hello.o –o hello
在成功编译之后,就进⼊了链接阶段。在这⾥涉及到⼀个重要的概念:函数库。
读者可以重新查看这个⼩程序,在这个程序中并没有定义”printf”的函数实现,且在预编译中包含进的”stdio.h”中也只有该函数的声明,⽽没有定义函数的实现,那么,是在哪⾥实现”printf”函数的呢?最后的答案是:系统把这些函数实现都被做到名为libc.so.6的库⽂件中去了,在没有特别指定时,Gcc会到系统默认的搜索路径”/usr/lib”下进⾏查,也就是链接到libc.so.6库函数中去,这样就能实现函数”printf”了,⽽这也就是链接的作⽤。
函数库⼀般分为静态库和动态库两种。静态库是指编译链接时,把库⽂件的代码全部加⼊到可执⾏⽂件中,因此⽣成的⽂件⽐较⼤,但在运⾏时也就不再需要库⽂件了。其后缀名⼀般为”.a”。动态库与之相反,在编译链接时并没有把库⽂件的代码加⼊到可执⾏⽂件中,⽽是在程序执⾏时由运⾏时链接⽂件加载库,这样可以节省系统的开销。动态库⼀般后缀名为”.so”,如前⾯所述的libc.so.6就是动态库。Gcc在编译时默认使⽤动态库。
整个过程如果想⼀步到位:
gcc hello.c -o hello
即可
gcc简介
Linux系统下的gcc(GNU C Compiler)是GNU推出的功能强⼤、性能优越的多平台编译器,是GNU的代表作品之⼀。gcc是可以在多种硬体平台上编译出可执⾏程序的超级编译器,其执⾏效率与⼀般的编译器相⽐平均效率要⾼20%~30%。gcc编译器能将C、C++语⾔源程序、汇程式化序和⽬标程序编译、连接成可执⾏⽂件,如果没有给出可执⾏⽂件的名字,gcc将⽣成⼀个名为a.out的⽂件。在Linux系统中,可执⾏⽂件没有统⼀的后缀,系统从⽂件的属性来区分可执⾏⽂件和不可执⾏⽂件。⽽gcc则通过后缀来区别输⼊⽂件的类别,下⾯我们来介绍gcc所遵循的部分约定规则。
.c为后缀的⽂件,C语⾔源代码⽂件;
唐三的魂环年限.a为后缀的⽂件,是由⽬标⽂件构成的档案库⽂件;
.C,.cc或.cxx 为后缀的⽂件,是C++源代码⽂件;
.h为后缀的⽂件,是程序所包含的头⽂件;
.i 为后缀的⽂件,是已经预处理过的C源代码⽂件;
.ii为后缀的⽂件,是已经预处理过的C++源代码⽂件;
.m为后缀的⽂件,是Objective-C源代码⽂件;
.o为后缀的⽂件,是编译后的⽬标⽂件;
.s为后缀的⽂件,是汇编语⾔源代码⽂件;
.S为后缀的⽂件,是经过预编译的汇编语⾔源代码⽂件。
qq伤感名称gcc的执⾏过程
虽然我们称gcc是C语⾔的编译器,但使⽤gcc由C语⾔源代码⽂件⽣成可执⾏⽂件的过程不仅仅是编译的过程,⽽是要经历四个相互关联的步骤∶预处理(也称预编译,Preprocessing)、编译(Compilation)、汇编(Assembly)和连接(Linking)。命令gcc⾸先调⽤cpp进⾏预处
的步骤∶预处理(也称预编译,Preprocessing)、编译(Compilation)、汇编(Assembly)和连接(Linking)。命令gcc⾸先调⽤cpp进⾏预处理,在预处理过程中,对源代码⽂件中的⽂件包含(include)、预编译语句(如宏定义define等)进⾏分析。接着调⽤cc1进⾏编译,这个阶段根据输⼊⽂件⽣成以.o为后缀的⽬标⽂件。汇编过程是针对汇编语⾔的步骤,调⽤as进⾏⼯作,⼀般来讲,.S为后缀的汇编语⾔源代码⽂件和汇编、.s为后缀的汇编语⾔⽂件经过预编译和汇编之后都⽣成以.o为后缀的⽬标⽂件。当所有的⽬标⽂件都⽣成之后,gcc就调⽤ld来完成最后的关键性⼯作,这个阶段就是连接。在连接阶段,所有的⽬标⽂件被安排在可执⾏程序中的恰当的位置,同时,该程序所调⽤到的库函数也从各⾃所在的档案库中连到合适的地⽅。
gcc的基本⽤法和选项
在使⽤gcc编译器的时候,我们必须给出⼀系列必要的调⽤参数和⽂件名称。gcc编译器的调⽤参数⼤约有100多个,其中多数参数我们可能根本就⽤不到,这⾥只介绍其中最基本、最常⽤的参数。
gcc最基本的⽤法是∶gcc [options] [filenames]
其中options就是编译器所需要的参数,filenames给出相关的⽂件名称。
网络流行用语-c,只编译,不连接成为可执⾏⽂件,编译器只是由输⼊的.c等源代码⽂件⽣成.o为后缀的⽬标⽂件,通常⽤于编译不包含主程序的⼦程序⽂件。
-o output_filename,确定输出⽂件的名称为output_filename,同时这个名称不能和源⽂件同名。如果不给出这个选项,gcc就给出预设的可执⾏⽂件a.out。
-g,产⽣符号调试⼯具(GNU的gdb)所必要的符号资讯,要想对源代码进⾏调试,我们就必须加⼊这个选项。
-O,对程序进⾏优化编译、连接,采⽤这个选项,整个源代码会在编译、连接过程中进⾏优化处理,这样产⽣的可执⾏⽂件的执⾏效率可以提⾼,但是,编译、连接的速度就相应地要慢⼀些。
奥迪a4多少公里保养-O2,⽐-O更好的优化编译、连接,当然整个编译、连接过程会更慢。
-Idirname,将dirname所指出的⽬录加⼊到程序头⽂件⽬录列表中,是在预编译过程中使⽤的参数。
C程序中的头⽂件包含两种情况∶
A)#include
B)#include “myinc.h”
其中,A类使⽤尖括号(< >),B类使⽤双引号(“ ”)。对于A类,预处理程序cpp在系统预设包含⽂件⽬录(如/usr/include)中搜寻相应的⽂件,⽽对于B类,cpp在当前⽬录中搜寻头⽂件,这个选项的作⽤是告诉cpp,如果在当前⽬录中没有到需要的⽂件,就到指定的dirname⽬录中去寻。在程序设计中,如果我们需要的这种包含⽂件分别分布在不同的⽬录中,就需要逐个使⽤-I选项给出搜索路径。炸鱼的做法
-Ldirname,将dirname所指出的⽬录加⼊到程序函数档案库⽂件的⽬录列表中,是在连接过程中使⽤的参数。在预设状态下,连接程序ld在系统的预设路径中(如/usr/lib)寻所需要的档案库⽂件,这个选项告诉连接程序,⾸先到-L指定的⽬录中去寻,然后到系统预设路径中寻,如果函数库存放在多个⽬录下,就需要依次使⽤这个选项,给出相应的存放⽬录。-lname,在连接时,装载名字
兰水晶为“libname.a”的函数库,该函数库位于系统预设的⽬录或者由-L选项确定的⽬录下。例如,-lm表⽰连接名为“libm.a”的数学函数库。上⾯我们简要介绍了gcc编译器最常⽤的功能和主要参数选项,更为详尽的资料可以参看Linux系统的联机帮助。
假定我们有⼀个程序名为test.c的C语⾔源代码⽂件,要⽣成⼀个可执⾏⽂件,最简单的
办法就是∶
gcc test.c
这时,预编译、编译连接⼀次完成,⽣成⼀个系统预设的名为a.out的可执⾏⽂件,对于稍为复杂的情况,⽐如有多个源代码⽂件、需要连接档案库或者有其他⽐较特别的要求,就要给定适当的调⽤选项参数。再看⼀个简单的例⼦。整个源代码程序由两个⽂件testmain.c 和testsub.c组成,程序中使⽤了系统提供的数学库,同时希望给出的可执⾏⽂件为test,这时的编译命令可以是∶
gcc testmain.c testsub.c -lm -o test
其中,-lm表⽰连接系统的数学库libm.a,这个过程可以⽤图12-1框图描述。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论