




已阅读5页,还剩76页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
.,嵌入式LinuxGCC培训,主讲老师:欧阳坚,.,GCC是什么?,GCC:GNUCompilerCollection;GCC支持多种硬件平台和操作系统,能编译多种语言(C,C+,Java,Ada95,ObjectiveC,.etc);GCC与G+的关系:GCC用于编译多种语言编写的程序,主要是C;G+用于编译C+程序,以GCC为基础,编译过程中加入了C+的支持库,参数与GCC基本一致;可以利用GCC编译C+程序,但是需要在参数中加入引用的C+库,比如libstdc+(如gcc-ooutlstdc+main.cc)。,.,可执行程序的生成过程,预处理(Preprocessing):分析各种预处理命令,如#define,#include,#if等;编译(Compilation):根据输入文件产生汇编语言的程序;汇编(Assembly):将汇编语言输入,产生扩展名为.o的目标文件;链接(Linking):以.o目标文件,库文件作为输入,生成可执行文件;,源程序文件(.h,.c,.cc,.etc),经预处理的文件(.i,.ii),汇编语言文件(.s),目标文件(.o),可执行程序(.out),.,GCC支持的文件类型,C文件.cC源代码.hC头文件C+文件file.hh,file.hC+头文件file.C,file.cc,file.cxx等C+源文件预处理后的文件file.i预处理后的C源文件file.ii预处理后的C+源文件编译后的文件.o目标代码(obj).s汇编代码文件file.a目标文件库,.,GCC编译选项,命令行:gccoptionsinfile-E不生成文件,只输出预处理结果(输出终端)-S只预处理和编译,把文件编译成为汇编代码greet.s-c预处理,编译和汇编,生成.o的obj文件(greet.o)-ofile输出名为file的可执行文件名(缺省为a.out)-O-O2优化编译-g:产生可用于调试的输出-Wall提示更多警告信息-Wstrict-prototypes如果函数的声明或定义没有指出参数类型,编译器就发出警告.-Wl,option将option作为选项传递给linker,option逗号分割,如:-Wl,-soname,libmymath.so.1,.,与库和路径相关选项,-Idir在dir这个目录寻找被include的文件-Ldir在dir这个目录寻找被-l的库-lname链接库文件名为libname.a或libname.so的库-fpic或-fPIC产生位置无关的目标代码,以构造共享库(sharedlibrary)-static禁止与共享库链接,若没有,则优先选择共享库链接-shared产生共享库,在创建共享函数库时使用,.,示例,.,与宏相关的选项,-Dmacro:相当于在源程序中使用#definemacro1-Dmacro=value-Umacro:取消宏的定义,.,.,3.GCC编译过程,.,3.1GCC编译过程,典型的编译过程test.c预处理test.i编译test.s汇编test.o连接test$cattest.c(查看程序源代码)#includeintmain(intargc,char*argv)printf(helloworldn);return0;$gccotesttest.c(编译连接程序)$./test(执行test程序),.,3.2预处理,预编译命令:$gcc-otest.i-Etest.c或者$cpp-otest.itest.c这里cpp不是值cplusplus,而是theCPreprocessor)执行结果:生成预处理后的文件test.i,该文件包含了test.c需要的所有的类型和函数申明。原理:读取c源程序,对伪指令和特殊符号进行处理。包括宏,条件编译,包含的头文件,以及一些特殊符号。基本上是一个替换的过程。,.,Hello.c,#includeintmain(void)printf(“hellon”);预处理命令gccEhello.cgccEhello.cohello.i,注释这一行看看预处理的结果注意#include的作用和用途,-E表示做预处理-o表示预处理的输出存于hello.i文件中,而不是屏幕上,.,#define用法,#include#defineAA100intmain(void)AABBprintf(“hellon”);预处理命令gccEhello.cDBB=hellogccEhello.cDBB=“printf(”hello”);”gccEhello.cDBB(等效于-DBB=1),注释这一行看看预处理的结果,-D表示在命令行中传入宏定义-DBB=后面是一个宏的定义,可以加双引号。,.,#define带参数,#include#defineAA(a,b)a=bintmain(void)AA(inta,1);BB;printf(“hellon”);预处理命令gccEhello.cDBB=hellogccEhello.cDBB=“printf(”hello”);”,注释这一行看看预处理的结果,-D表示在命令行中传入宏定义-DBB=后面是一个宏的定义,可以加双引号。,展开就成了:inta=1;AA宏带两个参数,.,#ifdef#ifdefined#if!defined#ifndef#elifdefined#elif!defined#else#if#elif#endif-ED”AA=100”,.,#define带参数,#include#ifdefAAaa#elifdefinedBBbb#elifdefinedCCcc#elseother#endifintmain(void)printf(“hellon”);,#ifdefAA等效于#ifdefinedAA表示当定义了宏AA,表示除此之外的情况,表示否则定义了宏CC的情况,.,gccEhello.cDAA=1,aaintmain(void)printf(“hellon”);,.,gccEhello.cDBB=1,bbintmain(void)printf(“hellon”);,.,gccEhello.cDCC=1,ccintmain(void)printf(“hellon”);,.,gccEhello.c,otherintmain(void)printf(“hellon”);,.,#if使用,.,#define带参数,#include#ifAAaa#elifBBbb#elifCCcc#elseother#endifintmain(void)printf(“hellon”);,#ifAA表示AA非零的情况也就是AA除了0其它数字都为真,表示除此之外的情况,#elifBB表示BB非零的情况#elif表示否则如果,.,gccEhello.cDAA=1,aaintmain(void)printf(“hellon”);gccEhello.cDAA=0otherintmain(void)printf(“hellon”);,.,gccEhello.cDBB=1,bbintmain(void)printf(“hellon”);gccEhello.cDBB=0otherintmain(void)printf(“hellon”);,.,gccEhello.cDCC=1,ccintmain(void)printf(“hellon”);gccEhello.cDCC=0otherintmain(void)printf(“hellon”);,.,gccEhello.c,otherintmain(void)printf(“hellon”);,.,#的用法,在函数式宏定义中,#运算符用于创建字符串,#运算符后面应该跟一个形参(中间可以有空格或Tab),例如:#defineSTR(s)#schar*p=STR(helloworld)结果变成:char*p=“helloworld”,.,#的用法,在宏定义中可以用#运算符把前后两个预处理Token连接成一个预处理Token,和#运算符不同,#运算符不仅限于函数式宏定义,变量式宏定义也可以用。例如:#defineFOO(a)foo#ainta=FOO(bar);intb=FOO();预处理之后变成:inta=foobar;intb=foo;,.,预处理头文件xxx.h,#ifndefHEADER_FILENAME#defineHEADER_FILENAME/*bodyofheader*/#endif当xxx.h被多次包含的时候。,.,有三个头文件和一个C文件,common.hfile2.hfile3.hmain.c,.,common.h,#ifndef_COMMON_H_#define_COMMON_H_1staticinttest(void)printf(“hellon”);#endif,如果没有写上红色部分的,是什么情况。,.,file1.h,file1.h文件内容如下#include“common.h”file2.h文件内容如下#include“common.h”,.,main.c,main.c内容如下/#include#include“file1.h”#include“file2.h”intmain(void)test();,.,gccEmain.cgccomainmain.c./main#.,.,#include#include#include“common.h”#include“file1.h”,.,.,3.3编译及优化,编译命令:$gcc-otest.s-Stest.i(-S编译选项)$gcc-otest.s-Stest.i(-S编译选项)$cc1-otest.stest.i(cc1为C语言真正编译器)结果:生成汇编文件test.s,test.s中包含了ATinty=3;printf(x+y=%3dn,add(x,y);printf(x-y=%3dn,minus(x,y);printf(x*y=%3dn,multiply(x,y);printf(x%y=%3dn,mod(x,y);return1;,add_minus.cintadd(intx,inty)intresult;result=x+y;returnresult;intminus(intx,inty)intresult;result=x-y;returnresult;,multiply_mod.cintmultiply(intx,inty)intresult;result=x*y;returnresult;intmod(intx,inty)intresult;result=x%y;returnresult;,.,创建静态库示例操作命令,.,一个容易忽略的顺序问题,静态库不能先于原程序链接,这是因为开始时还没有任何未定义的符号,库中的内容不会被链入,所以应该注意将静态库的使用(-l选项)都写在最后。,.,创建、使用共享库示例,vicknec$gcc-fPIC-cadd_minus.cvicknec$gcc-fpic-cmultiply_mod.cvicknec$gcc-shared-fpic-olibalg.soadd_minus.omultiply_mod.ovicknec$gcc-ocacul-lalgcaculation.c/usr/bin/ld:cannotfind-lalgcollect2:ldreturned1exitstatusvicknec$gcc-ocacul-L.-lalgcaculation.cvicknec$./cacul./cacul:errorwhileloadingsharedlibraries:libalg.so:cannotopensharedobjectfile:Nosuchfileordirectory,.,创建共享库步骤,创建共享库gcc-c-fPICtest1.cgcc-c-fPICtest2.cgcc-shared-fPIC-olibtest.sotest1.otest2.o编译使用了共享库的程序gcc-omainLdir-ltestmain.c,.,共享库系统自动动态加载问题,1.拷贝动态库文件到/lib或/usr/lib去$cplibalg.so/usr/libor$cplibalg.so/lib2.改变环境变量LD_LIBRARY_PATH$LD_LIBRARY_PATH=$PWD$exportLD_LIBRARY_PATH,.,应用程序自身完成动态加载,可以在自己的程序中使用dlopen()。该函数将打开一个新库,并把它装入内存。dlopen()在dlfcn.h中定义,并在dl库中实现。,.,检查库依赖关系,函数库之间的相互引用ldd的使用:用于查看库函数之间的依赖性vicknecgcc-lab$cd/usr/libvickneclib$lddlibtiff.solibjpeg.so.62=/usr/lib/libjpeg.so.62(0 x4004c000)libz.so.1=/usr/lib/libz.so.1(0 x4006b000)libc.so.6=/lib/i686/libc.so.6(0 x40079000)/lib/ld-linux.so.2=/lib/ld-linux.so.2(0 x80000000),.,应用程序自身完成动态加载示例,#include#includeintmain(void)intx=5;inty=3;void*handle;int(*dl_add)(int,int);int(*dl_mod)(int,int);,handle=dlopen(/usr/lib/libalg.so,RTLD_LAZY);dl_add=dlsym(handle,add);dl_mod=dlsym(handle,mod);printf(x+y=%3dn,dl_add(x,y);printf(x%y=%3dn,dl_mod(x,y);dlclose(handle);return1;,.,总结:动态共享库的好处,1.动态共享库是共享的,节省了物理开销。2.库版本更新容易,运行时调用,库更新后不用重新链接。3.允许用户在运行时再确定调用哪个库。使得在程序中添加或者删除一个模块时,都不需要在编译时指定库。注意,如果动态共享库无法加载,可能是路径的问题,或是依赖的问题。,.,.,aroption,optioncCreateafileoptiondDeleteafilefromthearchiveoptionpPrintalistoffilesinthearchiveoptionqAppendfilestothearchiveoptionrInsertnewfilesinthearchivebyreplacingifafilealreadyexistsinthearchiveoptiontDisplayingcontentsofanarchiveoptionxExtractingfilesfromanarchive,.,ranlibUtility,The“ranlib”commandisusedtocreateindexentriesinsideanarchivefile.示例:$ranlibstatic-lib-name等价于$arsstatic-lib-name,.,nmUtility,usedtolistsymbolsusedinanobjectfile.示例:$nm-slibcommon.a$nm-sa.out另外:aoptionwiththenmcommandalsoshowsthedebugsymbols.,.,objdumpUtility,-fDisplayingHeaderInformation-hDisplayingSectionHeaders-dDisassemblingaFile-aDisplayingInformationaboutLibraryFiles,.,sizeUtility,Thesizeutilitydisplayssizesofeachsectioninanobjectfile.示例:rootboota#sizea.outtextdatabssdechexfilename10152322412714f7a.out,.,stringsUtility,Thestringsutilitydisplaysprintablestringsinanobjectfile.Bydefaultitdisplaysstringsonlyininitializedandloadedsectionsoftheobjectfile.,.,lddUtility,Thelddutilityisveryusefulinfindingoutthedependenciesofanexecutableonsharedlibraries.示例:rootboota#ldda.outlibc.so.6=/lib/i686/libc.so.6(0 x4002c000)/lib/ld-linux.so.2=/lib/ld-linux.so.2(0 x40000000)rootboota#,.,.,make和Makefile的关系,make和Makefile的关系就像演员和剧本的关系make是系统的一个程序(/usr/bin/make)Makefile是规则的文件make就是去解析Makefile的文件来执行相关的命令Makefile有三种命名形式:Makefile,makefile,GNUMakefile,.,3.7一个简单的Makefile格式,all:helloecho“Begintobuildhello“hello:echo“Displayhello”clean:xxxxrm-rf*.ohello,注意符号的用途,表示后面的命令不要显示出来,第一个target,第二个target,第三个target,红色的xxxx表示键盘上的Tab键,而不是空白,任何命令必须以Tab键开始。,.,make(在上述Makefile中,make和makeall操作一样,因为all是第一个target)makeallmakehellomakeclean,.,3.7一个简单的Makefile格式,myname=Saifall:helloecho“mynameis:$(myname)”echo“Begintobuildhello“hello:echo“Displayhello”clean:rm-rf*.ohello,变量myname使用$()表示,.,一个简单的C程序(hello.c和foo1.c),#include/*hello.c*/externintfoo1(void);intmain(void)foo1();,#include/*foo1.c*/intfoo1(void)printf(“printfoo1n”);,.,3.7通常的Makefile格式,all:helloechoFinishtobuildhello“hello:hello.ofoo1.ogcc-ohellohello.ofoo1.ohello.o:hello.cgcc-c-ohellohello.cfoo1.o:foo1.cgcc-c-ofoo1.ofoo1.cclean:rm-rf*.ohello,.,使用shell脚本来表示,脚本1build.sh#!/bin/shgcc-c-ohellohello.cgcc-c-ofoo1.ofoo1.cgcc-ohellohello.ofoo1.oechoFinishtob
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年度绿色建筑幕墙劳务分包工程合同范本
- 2025东航大客户航空安全培训服务合同
- 肩关节运动康复新策略-洞察及研究
- 2025年新型防盗门窗产品销售代理协议
- 2025年度第三方保密协议与数据传输安全规范模板
- 2025年度地暖垫层施工质量保证与售后服务承包合同范本
- 2025版蔬菜种植基地土地流转承包合同
- 2025版食品添加剂研发委托生产合作协议
- 2025年新能源设备采购合同补充协议范本
- 2025年度山地草场使用权流转合同
- 放射科质控汇报
- 眼科学教学课件:绪论
- GB/T 31091-2014煤场管理通用技术要求
- GB/T 24218.1-2009纺织品非织造布试验方法第1部分:单位面积质量的测定
- 万东GFS型高频高压发生装置维修手册
- 公寓de全人物攻略本为个人爱好而制成如需转载注明信息
- 企业经营沙盘模拟实训指导书
- 汉密尔顿抑郁量表17项
- 《现代物流管理》第一章-导论(课用)
- 智能制造生产线运营与维护课件完整版
- 树木清障专项施工方案
评论
0/150
提交评论