GCC详解及makefile规则.doc
《GCC详解及makefile规则.doc》由会员分享,可在线阅读,更多相关《GCC详解及makefile规则.doc(35页珍藏版)》请在咨信网上搜索。
1、GCC 编译详解GNU CC(简称为Gcc)是GNU项目中符合ANSI C标准的编译系统,能够编译用C、C+和Object C等语言编写的程序。Gcc不仅功能强大,而且可以编译如C、C+、Object C、Java、Fortran、Pascal、Modula-3和Ada等多种语言,而且Gcc又是一个交叉平台编译器,它能够在当前CPU平台上为多种不同体系结构的硬件平台开发软件,因此尤其适合在嵌入式领域的开发编译。本章中的示例,除非特别注明,否则均采用Gcc版本为4.0.0。GCC入门基础表3.6 Gcc所支持后缀名解释后 缀 名所对应的语言后 缀 名所对应的语言.cC原始程序.s/.S汇编语言原
2、始程序.C/.cc/.cxxC+原始程序.h预处理文件(头文件).mObjective-C原始程序.o目标文件.i已经过预处理的C原始程序.a/.so编译后的库文件.ii已经过预处理的C+原始程序如本章开头提到的,Gcc的编译流程分为了四个步骤,分别为: 预处理(Pre-Processing) 编译(Compiling) 汇编(Assembling) 链接(Linking)下面就具体来查看一下Gcc是如何完成四个步骤的。首先,有以下hello.c源代码#includeint main()printf(Hello! This is our embedded world!n);return 0;(
3、1)预处理阶段在该阶段,编译器将上述代码中的stdio.h编译进来,并且用户可以使用Gcc的选项”-E”进行查看,该选项的作用是让Gcc在预处理结束后停止编译过程。注意Gcc指令的一般格式为:Gcc 选项 要编译的文件 选项 目标文件其中,目标文件可缺省,Gcc默认生成可执行的文件,命为:编译文件.outrootlocalhost Gcc# Gcc E hello.c o hello.i在此处,选项”-o”是指目标文件,由表3.6可知,”.i”文件为已经过预处理的C原始程序。以下列出了hello.i文件的部分内容:typedef int (*_gconv_trans_fct) (struct
4、_gconv_step *,struct _gconv_step_data *, void *,_const unsigned char *,_const unsigned char *,_const unsigned char *, unsigned char *,size_t *);# 2 hello.c 2int main()printf(Hello! This is our embedded world!n);return 0;由此可见,Gcc确实进行了预处理,它把”stdio.h”的内容插入到hello.i文件中。(2)编译阶段接下来进行的是编译阶段,在这个阶段中,Gcc首先要检查代
5、码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,Gcc把代码翻译成汇编语言。用户可以使用”-S”选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。rootlocalhost Gcc# Gcc S hello.i o hello.s以下列出了hello.s的内容,可见Gcc已经将其转化为汇编了,感兴趣的读者可以分析一下这一行简单的C语言小程序是如何用汇编代码实现的。.file hello.c.section .rodata.align 4.LC0:.stringHello! This is our embedded world!.text.globl main.
6、type main, functionmain:pushl pmovl %esp, psubl $8, %espandl $-16, %espmovl $0, xaddl $15, xaddl $15, xshrl $4, xsall $4, xsubl x, %espsubl $12, %esppushl $.LC0call putsaddl $16, %espmovl $0, xleaveret.size main, .-main.ident GCC: (GNU) 4.0.0 20050519 (Red Hat 4.0.0-8).section .note.GNU-stack,progbi
7、ts(3)汇编阶段汇编阶段是把编译阶段生成的”.s”文件转成目标文件,读者在此可使用选项”-c”就可看到汇编代码已转化为”.o”的二进制目标代码了。如下所示:rootlocalhost Gcc# Gcc c hello.s o hello.o(4)链接阶段在成功编译之后,就进入了链接阶段。在这里涉及到一个重要的概念:函数库。读者可以重新查看这个小程序,在这个程序中并没有定义”printf”的函数实现,且在预编译中包含进的”stdio.h”中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实现”printf”函数的呢?最后的答案是:系统把这些函数实现都被做到名为libc.so.6的库文件
8、中去了,在没有特别指定时,Gcc会到系统默认的搜索路径”/usr/lib”下进行查找,也就是链接到libc.so.6库函数中去,这样就能实现函数”printf”了,而这也就是链接的作用。函数库一般分为静态库和动态库两种。静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为”.a”。动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为”.so”,如前面所述的libc.so.6就是动态库。Gcc在编译时默认使用动态库。完成了链
9、接之后,Gcc就可以生成可执行文件,如下所示。rootlocalhost Gcc# Gcc hello.o o hello运行该可执行文件,出现正确的结果如下。rootlocalhost Gcc# ./helloHello! This is our embedded world!Gcc编译选项分析Gcc有超过100个的可用选项,主要包括总体选项、告警和出错选项、优化选项和体系结构相关选项。以下对每一类中最常用的选项进行讲解。(1)总体选项Gcc的总结选项如表3.7所示,很多在前面的示例中已经有所涉及。表3.7 Gcc总体选项列表后缀名所对应的语言-c只是编译不链接,生成目标文件“.o”-S只是
10、编译不汇编,生成汇编代码-E只进行预编译,不做其他处理-g在可执行程序中包含标准调试信息-o file把输出文件输出到file里-v打印出编译器内部编译各过程的命令行信息和编译器的版本-I dir在头文件的搜索路径列表中添加dir目录-L dir在库文件的搜索路径列表中添加dir目录-static链接静态库-llibrary连接名为library的库文件对于“-c”、“-E”、“-o”、“-S”选项在前一小节中已经讲解了其使用方法,在此主要讲解另外两个非常常用的库依赖选项“-I dir”和“-L dir”。 “-I dir”正如上表中所述,“-I dir”选项可以在头文件的搜索路径列表中添加d
11、ir目录。由于Linux中头文件都默认放到了“/usr/include/”目录下,因此,当用户希望添加放置在其他位置的头文件时,就可以通过“-I dir”选项来指定,这样,Gcc就会到相应的位置查找对应的目录。比如在“/root/workplace/Gcc”下有两个文件:#includeint main()printf(“Hello!n”);return 0;#include这样,就可在Gcc命令行中加入“-I”选项:rootlocalhost Gcc Gcc hello1.c I /root/workplace/Gcc/ -o hello1这样,Gcc就能够执行出正确结果。小知识在inclu
12、de语句中,“”表示在标准路径中搜索头文件,“”表示在本目录中搜索。故在上例中,可把hello1.c的“#include”改为“#include “my.h”,就不需要加上“-I”选项了。 “-L dir”选项“-L dir”的功能与“-I dir”类似,能够在库文件的搜索路径列表中添加dir目录。例如有程序hello_sq.c需要用到目录“/root/workplace/Gcc/lib”下的一个动态库libsunq.so,则只需键入如下命令即可:rootlocalhost Gcc Gcc hello_sq.c L /root/workplace/Gcc/lib lsunq o hello_s
13、q需要注意的是,“-I dir”和“-L dir”都只是指定了路径,而没有指定文件,因此不能在路径中包含文件名。另外值得详细解释一下的是“-l”选项,它指示Gcc去连接库文件libsunq.so。由于在Linux下的库文件命名时有一个规定:必须以lib三个字母开头。因此在用-l选项指定链接的库文件名时可以省去lib三个字母。也就是说Gcc在对”-lsunq”进行处理时,会自动去链接名为libsunq.so的文件。(2)告警和出错选项Gcc的告警和出错选项如表3.8所示。表3.8 Gcc总体选项列表选项含义-ansi支持符合ANSI标准的C程序-pedantic允许发出ANSI C标准所列的全部
14、警告信息选项含义-pedantic-error允许发出ANSI C标准所列的全部错误信息-w关闭所有告警-Wall允许发出Gcc提供的所有有用的报警信息-werror把所有的告警信息转化为错误信息,并在告警发生时终止编译过程下面结合实例对这几个告警和出错选项进行简单的讲解。如有以下程序段:#includevoid main()long long tmp = 1;printf(“This is a bad code!n”);return 0;这是一个很糟糕的程序,读者可以考虑一下有哪些问题? “-ansi”该选项强制Gcc生成标准语法所要求的告警信息,尽管这还并不能保证所有没有警告的程序都是符合
15、ANSI C标准的。运行结果如下所示:rootlocalhost Gcc# Gcc ansi warning.c o warningwarning.c: 在函数“main”中:warning.c:7 警告:在无返回值的函数中,“return”带返回值warning.c:4 警告:“main”的返回类型不是“int”可以看出,该选项并没有发现”long long”这个无效数据类型的错误。 “-pedantic”允许发出ANSI C标准所列的全部警告信息,同样也保证所有没有警告的程序都是符合ANSI C标准的。其运行结果如下所示:rootlocalhost Gcc# Gcc pedantic wa
16、rning.c o warningwarning.c: 在函数“main”中:warning.c:5 警告:ISO C90不支持“long long”warning.c:7 警告:在无返回值的函数中,“return”带返回值warning.c:4 警告:“main”的返回类型不是“int”可以看出,使用该选项查看出了”long long”这个无效数据类型的错误。 “-Wall”允许发出Gcc能够提供的所有有用的报警信息。该选项的运行结果如下所示:rootlocalhost Gcc# Gcc Wall warning.c o warningwarning.c:4 警告:“main”的返回类型不是
17、“int”warning.c: 在函数”main”中:warning.c:7 警告:在无返回值的函数中,”return”带返回值warning.c:5 警告:未使用的变量“tmp”使用“-Wall”选项找出了未使用的变量tmp,但它并没有找出无效数据类型的错误。另外,Gcc还可以利用选项对单独的常见错误分别指定警告,有关具体选项的含义感兴趣的读者可以查看Gcc手册进行学习。(3)优化选项Gcc可以对代码进行优化,它通过编译选项“-On”来控制优化代码的生成,其中n是一个代表优化级别的整数。对于不同版本的Gcc来讲,n的取值范围及其对应的优化效果可能并不完全相同,比较典型的范围是从0变化到2或3
18、。不同的优化级别对应不同的优化处理工作。如使用优化选项“-O”主要进行线程跳转(Thread Jump)和延迟退栈(Deferred Stack Pops)两种优化。使用优化选项“-O2”除了完成所有“-O1”级别的优化之外,同时还要进行一些额外的调整工作,如处理器指令调度等。选项“-O3”则还包括循环展开和其他一些与处理器特性相关的优化工作。虽然优化选项可以加速代码的运行速度,但对于调试而言将是一个很大的挑战。因为代码在经过优化之后,原先在源程序中声明和使用的变量很可能不再使用,控制流也可能会突然跳转到意外的地方,循环语句也有可能因为循环展开而变得到处都有,所有这些对调试来讲都将是一场噩梦。
19、所以笔者建议在调试的时候最好不使用任何优化选项,只有当程序在最终发行的时候才考虑对其进行优化。(4)体系结构相关选项Gcc的体系结构相关选项如表3.9所示。表3.9Gcc体系结构相关选项列表选项含义-mcpu=type针对不同的CPU使用相应的CPU指令。可选择的type有i386、i486、pentium及i686等-mieee-fp使用IEEE标准进行浮点数的比较-mno-ieee-fp不使用IEEE标准进行浮点数的比较-msoft-float输出包含浮点库调用的目标代码-mshort把int类型作为16位处理,相当于short int-mrtd强行将函数参数个数固定的函数用ret NUM
20、返回,节省调用函数的一条指令这些体系结构相关选项在嵌入式的设计中会有较多的应用,读者需根据不同体系结构将对应的选项进行组合处理。在本书后面涉及到具体实例会有针对性的讲解。Gdb调试器调试是所有程序员都会面临的问题。如何提高程序员的调试效率,更好更快地定位程序中的问题从而加快程序开发的进度,是大家共同面对的。就如读者熟知的Windows下的一些调试工具,如VC自带的如设置断点、单步跟踪等,都受到了广大用户的赞赏。那么,在Linux下有什么很好的调试工具呢?本文所介绍的Gdb调试器是一款GNU开发组织并发布的UNIX/Linux下的程序调试工具。虽然,它没有图形化的友好界面,但是它强大的功能也足以
21、与微软的VC工具等媲美。下面就请跟随笔者一步步学习Gdb调试器。Gdb使用流程首先,笔者给出了一个短小的程序,由此带领读者熟悉一下Gdb的使用流程。强烈建议读者能够实际动手操作。首先,打开Linux下的编辑器Vi或者Emacs,编辑如下代码。(由于为了更好地熟悉Gdb的操作,笔者在此使用Vi编辑,希望读者能够参见3.3节中对Vi的介绍,并熟练使用Vi)。#include int sum(int m);int main()int i,n=0;sum(50);for(i=1; i=50; i+)n += i;printf(The sum of 1-50 is %d n, n );int sum(i
22、nt m)int i,n=0;for(i=1; i=m;i+)n += i;printf(The sum of 1-m is %dn, n);在保存退出后首先使用Gcc对test.c进行编译,注意一定要加上选项”-g”,这样编译出的可执行代码中才包含调试信息,否则之后Gdb无法载入该可执行文件。rootlocalhost Gdb# gcc -g test.c -o test虽然这段程序没有错误,但调试完全正确的程序可以更加了解Gdb的使用流程。接下来就启动Gdb进行调试。注意,Gdb进行调试的是可执行文件,而不是如”.c”的源代码,因此,需要先通过Gcc编译生成可执行文件才能用Gdb进行调试。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- GCC 详解 makefile 规则
1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前自行私信或留言给上传者【a199****6536】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时私信或留言给本站上传会员【a199****6536】,需本站解决可联系【 微信客服】、【 QQ客服】,若有其他问题请点击或扫码反馈【 服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【 版权申诉】”(推荐),意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:4008-655-100;投诉/维权电话:4009-655-100。