




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、1GCC编译器编译器2初识初识GCC GCC(GNU Compiler Collection,GNU编译器套装),是一套由 GNU 开发的编程语言编译器。它是一套 GNU编译器套装 以 GPL 及 LGPL 许可证所发行的自由软件,也是 GNU计划的关键部分,亦是自由的类Unix及苹果电脑 Mac OS X 操作系统的标准编译器。 GCC 原名为 GNU C 语言编译器,因为它原本只能处理 C语言。GCC 很快地扩展,变得可处理 C+。之后也变得可处理 Fortran、Pascal、Objective-C、Java, 以及 Ada与其他语言。3GCC是什么?是什么?GCC: GNU Compi
2、ler Collection;GCC支持多种硬件平台和操作系统,能编译多种语言(C, C+, Java, Ada95, Objective C, .etc);GCC与G+的关系: GCC用于编译多种语言编写的程序,主要是C; G+用于编译C+程序,以GCC为基础,编译过程中加入了C+的支持库,参数与GCC基本一致; 可以利用GCC编译C+程序,但是需要在参数中加入引用的C+库,比如libstdc+ (如gcc -o out lstdc+ main.cc)。4可执行程序的生成过程可执行程序的生成过程 预处理(Preprocessing):分析各种预处理命令,如#define, #include,
3、 #if等; 编译(Compilation): 根据输入文件产生汇编语言的程序; 汇编(Assembly): 将汇编语言输入,产生扩展名为.o的目标文件; 链接(Linking):以.o目标文件,库文件作为输入,生成可执行文件;源程序文件(.h, .c, .cc, .etc)经预处理的文件(.i, .ii)汇编语言文件(.s)目标文件(.o)可执行程序(.out).cc是Linux/Unix下为C+源文件的默认扩展名,与.cpp一个意思 。用GCC/G+在 Linux/Unix下可以打开和编译 5预编译过程预编译过程 预编译又称为预处理,是做些代码文本的替换工作。 处理#开头的指令,比如拷贝#
4、include包含的文件代码,#define宏定义的替换,条件编译等。 就是为编译做的预备工作的阶段 该阶段会生成一个中间文件*.i,但实际工作中通常不用专门生成这种文件,因为基本上用不到;若非要生成这种文件不可,可以利用下面的示例命令: gcc -E test.c -o test.i6常见的预编译指令常见的预编译指令 常见的预编译指令处理以下指令: (1)#include 指令:头文件包含指令 (2)#define指令 :宏定义指令 (3)#if、#else和#endif指令:条件编译指令7(1)#include 指令指令 :头文件包含指令:头文件包含指令 该指令指示编译器将xxx.xxx文
5、件的全部内容插入此处。若用括起文件则在系统的INCLUDE目录中寻找文件,若用“ ”括起文件则在当前目录中寻找文件。一般来说,该文件是后缀名为“h”或“cpp”的头文件。 一般为/usr/include路径 注意:不会在当前目录下搜索头文件,如果我们不用而用把头文件名扩起,其意义为在先在当前目录下搜索头文件,再在系统默认目录下搜索。 8(2)#define指令指令 :宏定义指令:宏定义指令 该指令常用有二种用法: 第一种是定义标识,标识有效范围为整个程序,形如#define XXX,常与#if配合使用; 第二种是定义常数,如#define max 100,则max代表100; 注意:这种情况下
6、使用const 定义常数更好,const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查,而对后者只进行字符替换,没有类型安全检查,并且在字符替换时可能会产生意料不到的错误(边际效应)。 9(3)#if、#else和和#endif指令:条件编译指令指令:条件编译指令 条件编译指令程序员在源程序中通过定义不同的宏来决定编译程序程序员在源程序中通过定义不同的宏来决定编译程序对哪些代码进行处理。对哪些代码进行处理。10查看预编译后文件举例查看预编译后文件举例可以使用-E选项查看预编译结果: 执行gcc a1.c -E|more源文件11预编译结果预编译结果12预编译结果预编译结
7、果13预编译结果预编译结果14预编译结果预编译结果15预编译结果预编译结果16预编译结果预编译结果 17预编译结果预编译结果18编译编译 经预编译后,将生成新的源程序(中间文件.i或.ii)。 在新程序中,只有常量、变量的定义,以及C语言关键字信息。 编译程序将通过词法分析和语法分析,确认所有指令都符合规则,并将其编译成汇编代码。 在编译阶段,输入的是中间文件*.i,编译后生成汇编语言文件*.s 。这个阶段对应的GCC命令如下所示:GCC -S test.i -o test.s19汇编汇编 使用GCC编译,缺省下是不会输出汇编代码文件的。 如需查看汇编代码文件,可以在编译时制定-S选项。注:大
8、写20例:编译文件例:编译文件example8_3.cexample8_3.sexample8_3.c源文件源文件执行gcc example8_3.c S生成 example8_3.s文件21例:编译后的汇编语言文件例:编译后的汇编语言文件example8_3.cexample8_3.s注:并不是读者熟悉的Intel 80X86汇编语言,而是AT&T汇编语言。22汇编汇编 在汇编阶段,将输入的汇编文件*.s转换成机器语言*.o。这个阶段对应的GCC命令如下所示: GCC -c test.s -o test.o 23连接阶段连接阶段 最后,在连接阶段将输入的机器代码文件*.s(与其它的机
9、器代码文件和库文件)汇集成一个可执行的二进制代码文件。这一步骤,可以利用下面的示例命令完成: GCC test.o -o test 24连接阶段连接阶段 迄今为止,我们谈论的程序仅涉及到一个源文件;现实中,一个程序的源代码通常包含在多个源文件之中,这该怎么办?没关系,即使这样,用GCC处理起来也并不复杂,见下例:GCC -o test first.c second.c third.c 25Gcc编译总结编译总结 在实际编译的时候,GCC首先调用cpp命令进行预处理,主要实现对源代码编译前的预处理,比如将源代码中指定的头文件包含进来。 接着调用cc1命令进行编译,作为整个编译过程的一个中间步骤,
10、该过程会将源代码翻译生成汇编代码。 汇编过程是针对汇编语言的步骤,调用as命令进行工作,生成扩展名为.o的目标文件。 当所有的目标文件都生成之后,GCC就调用连接器ld来完成最后的关键性工作链接。26GCC支持的文件类型支持的文件类型C文件. .cC源代码 .h C头文件C+文件 file.hh, file.hC+头文件 file.C, file.cc, file.cxx等C+源文件预处理后的文件 file.i预处理后的C源文件 file.ii预处理后的C+源文件编译后的文件 .o 目标代码 (obj) .s 汇编代码文件 file.a目标文件库27GCC编译选项编译选项命令行:命令行:gcc
11、 options infile -E不生成文件,只输出预处理结果(输出终端) -S只预处理和编译,把文件编译成为汇编代码name.s -c预处理,编译和汇编,生成.o的obj文件 ( name.o ) -o file输出名为file的可执行文件名(缺省为a.out) -O -O2 -O3优化编译(逐渐级别升高)28GCC - 编译选项预编译选项编译选项预编译选项 -DMACRO定义“MACRO” 宏为字符串“1” -DMACRO=DEF 定义“MACRO” 宏为字符串“DEF” -UMACRO取消对“MACRO” 宏的定义29GCC编译选项编译选项 出错检查和警告提示选项出错检查和警告提示选项
12、 -Werror 它要求GCC将所有的警告当成错误进行处理。GCC会在所有产生警告的地方停止编译,迫使程序员对自己的代码进行修改。只有当相应的警告信息消除时,才可能将编译过程继续朝前推进。 -Wall 显示所有警告信息。Wall选项可以打开所有类型的语法警告,以便于确定程序源代码是否是正确的,并且尽可能实现可移植性。 -w 禁止输出警告信息。30GCC编译选项编译选项 出错检查和警告提示选项出错检查和警告提示选项 -pedantic 当GCC在编译不符合ANSI/ISO C语言标准的源代码时,如果加上了-pedantic选项,那么使用了扩展语法的地方将产生相应的警告信息。 例如: #inclu
13、de void main(void) long long int var = 1; printf(It is not standard C code!n); gcc -pedantic illcode.c.31GCC编译选项编译选项 调试分析选项调试分析选项 -g选项:生成调试信息,GNU调试器可以利用该信息。GCC编译器使用该选项进行编译时,将调试信息加入到目标文件中,这样gdb调试器就可以根据这些调试信息来跟中程序的执行状态。 -ggdb生成只被gdb使用的扩展调试信息 -mXXX针对“XXX”CPU进行优化,如“XXX”可以是486、586等 -pg选项:编译完成后,额外产生一个性能分析
14、所需信息。注意:注意:使用调试选项都会使最终生成的二进制文件的大小急剧增加,同时增加程序在执行时的开销,因此调试选项统常推荐仅仅在程序开发和调试阶段中使用。32GCC编译选项编译选项 与库和路径相关选项与库和路径相关选项 -I dir 在dir这个目录寻找被include的文件 -L dir 在dir这个目录寻找被-l的库 -lname 链接库文件名为libname.a 或libname.so的库. -fpic或或-fPIC 产生位置无关的目标代码,以构造共 享库(shared library) -static 链接静态库 -shared 产生共享库,在创建共享函数库时使用小写的字母L小写的字
15、母L-I 指定头文件所在目录,如为系统头文件,则不需指定;/usr/include-L指定链接库所在目录,如为系统库,则不需指定;/usr/lib或/lib-fpic与-shared配合制作动态函数库33与库和路径相关选项与库和路径相关选项 -I选项:库依赖选项,指定库及头文件路径。 在Linux下开发程序的时候,统常来讲都需要借助一个或多个函数库的支持才能够完成相应的功能。一般情况下,Linux下的大多数函数都将头文件放到系统/usr/include目录下,而库文件则放到/usr/lib目录下。但在有些情况下并不是这样的,在这些情况下,使用GCC编译时必须指定所需要的头文件和库文件所在的路径
16、。-I选项可以向GCC的头文件搜索路径中添加新的目录。例如,一个源程序所依赖的头文件在用户/home/include/目录下,此时就应该使用-I选项来指定。 # gcc I /home/include -o test test.c34与库和路径相关选项与库和路径相关选项 -L:类似于上面的情况,用来特别指定所依赖库所在的路径 如果使用不在标准位置的库,那么可以通过-L选项向GCC的库文件搜索路径中添加新的目录。例如,一个程序要用到的库libapp.so在/home/zxq/lib/目录下,为了能让GCC能够顺利地链接该库,可以使用下面的指令: 这里的-L选项表示GCC去链接库文件libapp.
17、so。在Linux下的库文件在命名时遵循了一个约定,那就是应该以lib三个字母开头,由于所有的库文件都遵循了同样的规范,因此在使用-L选项指定链接的库文件名时可以省去lib三个字母,也就是说GCC在对-lapp进行处理的时候,会自动去链接名为libapp.so的文件 gcc -Test.c -L /home/zxq/lib/ -lapp o Test35与库和路径相关选项与库和路径相关选项 -static选项: GCC在默认情况下链接的是动态库,有时为了把一些函数静态编译到程序中,而无需链接动态库就采用-static选项,它会强制程序连接静态库。 库文件: 提供了函数库的文件,有两种,一种是静
18、态连接的(.a),需要在程序编译时连接;另一种是动态连接的(.o,.so),在程序运行时连接。当使用静态库时,连接器找出程序所需的函数,然后将它们拷贝到可执行文件,一旦连接成功,静态程序库也就不再需要了。然而,对动态库而言,就不是这样,动态库会在执行程序内留下一个标记指明当程序执行时,首先必须载入这个库。由于动态库节省空间,linux下进行连接的缺省操作是首先连接动态库。36静态库与动态库静态库与动态库 创建函数库 分类: 静态库静态库: 在编译过程中将库函数代码直接加入到生成的可执行程序中,程序运行过程中不需要利用库函数。 共享库共享库: 编译时,只是在生成的可执行程序中简单指定需要使用的库
19、函数信息,程序运行过程中需要利用库函数。 动态库动态库: 共享库的一种变化形式,目前大都采用共享库的方式。 命名: 静态库: 前缀lib+库名+.a (libm.a, libstdc+.a等) 共享库: 前缀lib+库名+.so+版本号 (libm.so.6, libc.so.6)37示例示例38GCC编译过程编译过程39GCC编译过程(回顾)编译过程(回顾) 典型的编译过程 test.c 预处理 test.i 编译 test.s 汇编test.o 连接 test$ cat test.c (查看程序源代码) #include int main(int argc, char *argv) pri
20、ntf(hello worldn); return 0; $ gcc o test test.c (编译连接程序)$ ./test (执行test程序)40预处理预处理预编译命令: $ gcc -o test.i -E test.c或者 $ cpp -o test.i test.c 或cpp -o test.i E test.c 这里cpp不是指c plus plus,而是the C Preprocessor)执行结果: 生成预处理后的文件生成预处理后的文件test.i, 该文件包含了该文件包含了test.c需要需要的所有的类型和函数声明。的所有的类型和函数声明。原理:读取c源程序,对伪指令和
21、特殊符号进行处理。包括宏,条件编译,包含的头文件,以及一些特殊符号。基本上是一个替换的过程。41Hello.c#include int main(void) printf(“hellon”);预处理命令gcc E hello.c gcc E hello.c o hello.i注释这一行看看预处理的结果注意#include的作用和用途-E表示做预处理-o 表示预处理的输出存于hello.i文件中,而不是屏幕上去掉头文件语句后,xxxx.i文件行数减少极多。原因:读取c源程序,对伪指令和特殊符号进行处理。包括宏,条件编译,包含的头文件,以及一些特殊符号。基本上是一个替换的过程。42#define用
22、法用法#include #define AA 100int main(void) AA; BB; printf(“hellon”);预处理命令gcc E hello.c DBB=200 o hello.igcc E hello.c DBB (等效于-DBB=1)注释这一行看看预处理的结果结果:AA有没有替换为100-D表示在命令行中传入宏定义-DBB=后面是一个宏的定义。43#define带参数带参数#include #define AA(a,b) a = bint main(void) AA(int a, 1); BB; printf(“hellon”);预处理命令gcc E hello.c
23、 DBB o hello.igcc hello.c DBB=200 o hello注释这一行看看预处理的结果结果: AA(int a, 1);没有改变-D表示在命令行中传入宏定义-DBB=后面是一个宏的定义。展开就成了: int a = 1; AA宏带两个参数44#if使用使用 条件编译指令程序员在源程序中通过定义不同的宏来程序员在源程序中通过定义不同的宏来决定编译程序对哪些代码进行处理。决定编译程序对哪些代码进行处理。45条件编译举例条件编译举例#include #if AAaa#elif BBbb#elif CCcc#elseother#endifint main(void) printf
24、(“hellon”);#if AA 表示AA非零的情况也就是AA除了0其它数字都为真表示除此之外的情况#elif BB 表示BB非零的情况#elif表示否则如果46条件编译举例条件编译举例编译指令可引起程序执行的差异编译指令可引起程序执行的差异编译指令:编译指令:gcc E hello.c DAA=1执行程序:执行程序:aaint main(void) printf(“hellon”);gcc E hello.c DAA=0otherint main(void) printf(“hellon”);47条件编译举例条件编译举例gcc E hello.c DBB=1bbint main(void)
25、 printf(“hellon”);gcc E hello.c DBB=0otherint main(void) printf(“hellon”);48条件编译举例条件编译举例gcc E hello.c DCC=1ccint main(void) printf(“hellon”);gcc E hello.c DCC=0otherint main(void) printf(“hellon”);49条件编译举例条件编译举例gcc E hello.cotherint main(void) printf(“hellon”);50条件预处理头文件条件预处理头文件xxx.h #ifndef HEADER_
26、FILENAME #define HEADER_FILENAME /* body of header */ 程序段程序段1 #endif这是宏定义的一种,它可以根据是否已经定义了一个变量来进这是宏定义的一种,它可以根据是否已经定义了一个变量来进行分支选择,一般用于调试等等。行分支选择,一般用于调试等等。 #ifndef x /先测试x是否被宏定义过 #define x 程序段1 /如果x没有被宏定义过,定义x,并编译程序段1 #endif 51条件预处理头文件条件预处理头文件xxx.h 有三个头文件和一个C文件 common.h file1.h file2.h main.c52条件预处理头文件
27、条件预处理头文件xxx.hcommon.h内容:#ifndef _COMMON_H_#define _COMMON_H_static int test(void) printf(“hellon”);#endif53条件预处理头文件条件预处理头文件xxx.h file1.h文件内容如下 #include “common.h” file2.h文件内容如下 #include “common.h”54条件预处理头文件条件预处理头文件xxx.h main.c内容如下:内容如下: #include #include “file1.h” #include “file2.h” int main(void) test(); 55条件预处理头文件条件预处理头文件xxx.h 编译执行 gcc o main main.c 输出:hello56预处理头文件预处理头文件 #include 和” ”区别 #include 标准头文件 #include “common.h” 用户自定义
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年临淄中学测试题及答案
- 2025年博士思政面试题及答案
- 2025年云南农职考试试题及答案
- 2025年有趣的汉字大班标准教案
- 2025年蛙泳理论考试试题及答案
- 2025年6数第2单元试题及答案
- 2025年开动脑筋试题及答案
- 2025年美术体育学考试题及答案
- 2025年街道晋升面试题及答案
- 2025年高中地理招教试题及答案
- 2025年广东江门中医药职业学院单招职业适应性测试题库参考答案
- 2025年阜阳职业技术学院单招职业适应性测试题库带答案
- 新媒体运营课件
- 《鼹鼠的月亮河》考试题附答案
- 2025年内蒙古巴彦淖尔市交通投资集团有限公司招聘笔试参考题库附带答案详解
- 2025年新公司法知识竞赛题库与答案
- 2025年新人教版物理八年级下册全册教案
- 微量注射泵培训
- 形象设计师三级习题库及答案
- 2025年度能源行业员工聘用合同范本
- 户外广告安装安全施工方案
评论
0/150
提交评论