版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
嵌入式系统的组成外围硬件嵌入式处理器操作系统应用程序软件系统开发环境编译下载和调试系统引导中间软件硬件系统第7章linux编程基础
编写简单的C语言程序,使用gcc编译器将程序编译为可执行程序QtopiaCore应用程序设计
利用qt平台,编写可视化的GUIAPP第3章Linux系统编程基础#include<stdio.h>intmain(void){intx;printf(“Helloworld!\n”);return0;}源程序:hello.c如何变成可执行的程序?嵌入式应用的生成编译(Compile)是指从高级语言转换成汇编语言的过程。从本质上编译是一个文本转换的过程(从文本文件到文本文件)。编译包含了C语言的语法解析和生成汇编语言两个步骤。汇编(Assemble)是指从汇编语言程序生成目标系统的二进制代码(机器代码)的过程。相对于编译过程的语法解析,汇编的过程相对简单。这是因为对于一款特定的处理器,其汇编语言和二进制的机器代码是一一对应的。链接(Link)过程将汇编成的多个机器代码组合成一个可执行程序。一般来说,通过编译和汇编过程,每一个源文件将生成一个目标文件。链接器的作用就是将这些目标文件组合,组合的过程包括了代码段、数据段等部分的合并,以及添加相应的文件头。GNUTools综述GNUTools是Linux环境下的开发工具,用于代码的生成。GNUTools的重要组成部分是GCC。GCC
是GNUCompilerCollection的缩写,是一个非常优秀的跨平台编译器集合,支持x86、ARM、MIPS和PowerPC等多种目标平台,支持C、C++、Java、ADA、Fortran和Pascal等多种高级语言。GNUTools综述文件类型扩展名文件说明文本文件*.cC语言源文件*.C/*.cxx/*.cppC++语言源文件*.i预处理后的C语言源文件*.ii预处理后的C++语言源文件*.s*.S汇编语言*.h头文件二进制文件.o目标文件.so动态库.a静态库GNUTools综述
预处理
编译
汇编
链接编译原理gcc/g++在执行编译的时候,只要分四个阶段:阶段功能工具生成文件预处理完成宏定义和include文件展开等工作预处理器无(.i)编译根据编译参数进行不同程度的优化,编译成汇编代码;gcc汇编文件.s汇编用汇编器把汇编代码进一步生成目标代码汇编器as目标文件.o链接用连接器把生成的目标代码和系统或用户提供的库连接起来,生成可执行文件链接器ld可执行文件使用gcc和不同的参数统一编译、汇编和链接过程gcc编译格式:编译器名称[option][filename]…编译器:gcc:linux默认的c编译器g++:linux默认的c++编译器arm-linux-gcc:arm开发板的c编译器,需要安装编译原理gcc常用编译选项:-E
只运行C预编译器cpp,不生成文件-S
只把文件编译成为汇编代码-c
只生成object文件,不链接-o
生成指定的输出文件
gcc一般的用法gcc–其他选项要处理的文件-o输出文件阶段功能命令生成文件预处理完成宏定义展开等工作gcc-Ehello.c–ohello.i无(.i)编译编译成汇编代码;gcc-Shello.i–ohello.s汇编文件.s汇编生成目标代码gcc-chello.s–ohello.o目标文件.o链接用连接器把生成的目标代码gcchello.o–ohello可执行文件#include<stdio.h>intmain(void){printf(“Helloworld!\n”);return0;}gcc编译gcc-chello.c–ohello.o从.c到.o:从.c到
可执行程序一步到位:gcchello.c–ohellogcc-chello.c–ohello.ogcchello.o-ohello从.c到.o,->可执行程序:gcc编译错误类型第一类∶C语法错误错误资讯∶文件中第n行有语法错误(syntexerrror)。这种类型的错误,一般都是C语言的语法错误,检查源代码文件中第n行及该行之前的程序,有时也需要对该文件所包含的头文件进行检查。第二类∶头文件错误错误资讯∶找不到头文件。这类错误是源代码文件中的包含头文件有问题,可能的原因有头文件名错误、指定的头文件所在目录名错误等,也可能是错误地使用了双引号和尖括号。gcc编译错误类型第三类∶档案库错误错误资讯∶连接程序找不到所需的函数库,例如∶ld:-lm:Nosuchfileordirectory这类错误是与目标文件相连接的函数库有错误,可能的原因是函数库名错误、指定的函数库所在目录名称错误等。第四类∶未定义符号错误资讯∶有未定义的符号(Undefinedsymbol)。这类错误是在连接过程中出现的,可能有两种原因∶一是使用变量但没有定义;二是未定义的符号是库函数,在源程序中使用了该库函数,而连接过程中还没有给定相应的函数库的名称,可修改gcc连接选项中的-l和-L项。gcc编译/*main.c*/#include"hello.h"intmain(void){hello();return0;}/*hello1.c*/#include<stdio.h>inthello(void){printf("Helloworld!\n");return0;}/*hello1.h*/inthello(void);可执行程序:
hello1一步完成:gccmain.chello1.c-ohello1多步完成:gcc-cmain.c-omain.ogcc-chello1.c-ohello1.ogccmain.ohello1.o-ohello1练习1:输入三角形的三条边的长,判断是否构成等边三角形、等腰三角形、直角三角形、普通三角形,还是不能构成三角形练习2:输入一个整数n和一个字符c,输出菱形图案,菱形图案由字符c构成,图案总共2n+1行如输入:3*输出:
*
***
***** *******
*****
***
*gcc常用编译选项:-w
不生成任何警告信息
-Wall
生成所有级别的警告信息gcc–ohello–whello.cgcc–ohello–Wallhello.c/***hello.c******/#include<stdio.h>intmain(void){floatx,y;x=2.0;printf(“x=%f\n”,x);}gcc编译gcc优化编译选项:-O0
不进行代码优化处理.默认值-O,O1
进行一般优化,在尽可能快的编译时间内优化代码-O2
进一步优化,时间减少但是不增加代码量,一般在内核编译时使用
-O3
较-O2进一步优化,以增大机器代码为代价gcc–ohello1–O1hello.cgcc–ohello2–O2hello.cgcc–ohello3–O3hello.cgcc编译/***********optimize.c************/#include<stdio.h>intmain(void){doublecounter;doubleresult;doubletemp;for(counter=0;counter<2000.0*2000.0*2000.0/20.0+2020;counter+=(5-1)/4){temp=counter/1979;result=counter;}printf("result=%lf\n",result);return0;}gcc–ooptimize1optimize.cgcc–ooptimize2–O2optimize.cgcc–ooptimize3–O3optimizehello.ctime./optimize1time./optimize2time./optimize3gcc常用编译选项:-lLIBRARY指定链接时需要的其它函数库“LIBRARY”-IDIR指定额外的头文件搜索路径DIR-LDIR指定额外的库函数搜索路径DIR-g
生成可被gdb使用的标准调试信息gcc编译gcc编译/*main.c*/#include"hello.h"intmain(void){hello();return0;}/*hello.c*/#include<stdio.h>inthello(void){printf("Helloworld!\n");return0;}/*hello.h*/inthello(void);main.chello.chello.h存放在同一个目录下-IDIR指定额外的头文件搜索路径DIR一步完成:gccmain.chello.c-ohello源程序:main.c
hello.c多步完成:gcc-cmain.c-omain.ogcc-chello.c-ohello.ogccmain.ohello.o-ohello可执行程序:
hellogcc编译-IDIR指定额外的头文件搜索路径DIR/*main.c*/#include<hello.h>intmain(void){hello();return0;}/*hello.c*/#include<hello.h>inthello(void){printf("Helloworld!\n");return0;}/*hello.h*/inthello(void);main.chello.c存放在同一个目录下hello.h存放另外一个目录下:incgcc编译-IDIR指定额外的头文件搜索路径DIR一步完成:gccmain.chello.c-ohello–I./inc多步完成:gcc-cmain.c-omain.o–I./incgcc-chello.c-ohello.o–I./incgccmain.ohello.o-ohellogcc编译-IDIR指定额外的头文件搜索路径DIR/******sinx.c*******/#include<stdio.h>#include<math.h>intmain(void){floatx,y;x=2.0;y=sin(x);printf(“sin(2.0)=%f\n”,y);return0;}gccsinx.c–osinx-Wall-lm-lLIBRARY指定链接时需要的其它函数库“LIBRARY”这些库存放在系统指定的目录中-lm表示要使用libm.a库文件和sinx.o链接成为可执行程序/****libtest.h存放于myinc目录****///字符串头尾翻转externvoidreverse_string(charstr[]);//每4个字符翻转externvoidflip_string(charstr[]);mylib目录中放了libtest.a库#include<stdio.h>#include<libtest.h>intmain(void){charstr[20]="abcd12345";printf("orgstring:%s\n",str);reverse_string(str);printf("newstring:%s\n",str);return0;}编译时需用-L./mylib指明库所在的目录,同时使用
-ltest指明是用什么库编译时用-I./myinc
指明位置-IDIR指定额外的头文件搜索路径DIR-LDIR指定额外的库函数搜索路径DIRgccuselib.c–ouselib–ltest–I./myinc–L./mylib练习:下载libtest.a库文件和libtest.h头文件,分别保存在mylib和myinc目录下,编写测试完成头文件中的函数的程序。练习1、熟悉gcc的使用:新建一个helloworld程序,对该文件进行编译、汇编、链接,生成可执行文件。2、建立一个10个数的数组,找出数组中第二大和第二小的数,并输出。编写该程序,存放为main.c,并编译成可执行程序,运行程序。3、在第2题程序的基础上,新建一个文件func.c,在该文件中写出两个函数,分别完成寻找数组的最大值和最小值功能。在main.c中调用该函数。编译成可执行程序,运行程序。makefile/*main.c*/#include"hello.h"intmain(void){hello();return0;}/*hello.c*/#include<stdio.h>inthello(void){printf("Helloworld!\n");return0;}/*hello.h*/inthello(void);make和makefilemake是一个工具,一个编译管理工具。或者说make是一个命令。用来解决大项目的程序编译管理问题。make的执行依赖于一个叫做makefile(Makefile)的文件。makefile规则target:file1file2…//依赖关系(tab)<command>//编译命令依赖关系:执行编译命令前,检查file1、file2是否被修改过,如果被修改了,才执行编译命令makefile:hello
:hello.c//依赖关系 gcc–ohellohello.c
//编译命令参考makefile:makefile规则/*main.c*/#include"hello.h"intmain(void){hello();return0;}/*hello.c*/#include<stdio.h>inthello(void){printf("Helloworld!\n");return0;}/*hello.h*/inthello(void);makefile规则makefile:myprog:main.ohello.o//依赖关系 gcc–omyprog
main.ohello.o//编译命令main.o:main.chello.h//依赖关系 gcc–cmain.c//编译命令hello.o:hello.chello.h//依赖关系 gcc–chello.c//编译命令clean: rmmyprogmain.ohello.oMakefile的运行
编写makefile后,在makefile同一个目录下运行命令make,即可执行makefile中的编译命令。
如果文件的命名不是makefile或者Makefile,则需要在make后加入参数格式如下:make–ffilename。make命令运行过程1、在makefile所在目录下运行make命令,系统会自动找到makefile中第一个目标(myprog),并以此为最终目标文件。2、如果目标文件不存在,或者所依赖的文件比目标文件的更新时间更晚,则执行该目标下的命令重新生成目标文件。4、clean:如果与第一个目标(myprog)无关的目标,则需要显式输入makeclean3、如果依赖的文件不存在,则会执行对应的命令生成依赖文件。Make规则
make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。
在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理,make只管文件的依赖性。makefile规则/*main.c*/#include"hello.h“#include“printstar.h”intmain(void){hello();print_star(2,3);return0;}/*hello.c*/#include<stdio.h>inthello(void){printf("Helloworld!\n");return0;}/*hello.h*/inthello(void);/*printstar.c*/#include<stdio.h>include“printstar.h”voidprint_star(unsignedm,unsignedn){unsignedi,j;for(i=0;i<m;i++){for(j=0;j<n;j++)printf(“*”);printf(“\n”);}return;}/*printstar.h*/Voidprint_star(unsignedm,unsignedn);Makefile怎么写?Makefile变量的使用makefile规则makefile:myprog:main.ohello.o//依赖关系 gcc–omyprog
main.ohello.o//编译命令main.o:main.chello.h//依赖关系 gcc–cmain.c//编译命令hello.o:hello.chello.h//依赖关系 gcc–chello.c//编译命令clean: rmmyprogmain.ohello.oedit:main.okbd.ocommand.odisplay.o\insert.osearch.ofiles.outils.o cc-oeditmain.okbd.ocommand.odisplay.o\insert.osearch.ofiles.outils.omain.o:main.cdefs.h cc-cmain.ckbd.o:kbd.cdefs.hcommand.h cc-ckbd.ccommand.o:command.cdefs.hcommand.h cc-ccommand.cdisplay.o:display.cdefs.hbuffer.h cc-cdisplay.cinsert.o:insert.cdefs.hbuffer.h cc-cinsert.csearch.o:search.cdefs.hbuffer.h cc-csearch.cfiles.o:files.cdefs.hbuffer.hcommand.h cc-cfiles.cutils.o:utils.cdefs.h cc-cutils.cclean: rmeditmain.okbd.ocommand.odisplay.o\insert.osearch.ofiles.outils.o变量定义
为了makefile的易维护,在makefile中可以使用变量。makefile的变量也就是一个字符串,理解成C语言中的宏可能会更好。objects=main.okbd.ocommand.odisplay.o\insert.osearch.ofiles.outils.o变量定义:变量使用:$(objects)edit:main.okbd.ocommand.odisplay.o\insert.osearch.ofiles.outils.o gcc-oeditmain.okbd.ocommand.odisplay.o\insert.osearch.ofiles.outils.omain.o:main.cdefs.h
gcc-cmain.ckbd.o:kbd.cdefs.hcommand.h gcc-ckbd.ccommand.o:command.cdefs.hcommand.h gcc-ccommand.cdisplay.o:display.cdefs.hbuffer.h gcc-cdisplay.cinsert.o:insert.cdefs.hbuffer.h gcc-cinsert.csearch.o:search.cdefs.hbuffer.h gcc-csearch.cfiles.o:files.cdefs.hbuffer.hcommand.h gcc-cfiles.cutils.o:utils.cdefs.h gcc-cutils.cclean: rmeditmain.okbd.ocommand.odisplay.o\insert.osearch.ofiles.outils.o
objects=main.okbd.ocommand.odisplay.o\insert.osearch.ofiles.outils.oedit:$(objects) gcc-oedit$(objects)main.o:main.cdefs.h gcc-cmain.ckbd.o:kbd.cdefs.hcommand.h gcc-ckbd.ccommand.o:command.cdefs.hcommand.h gcc-ccommand.cdisplay.o:display.cdefs.hbuffer.h gcc-cdisplay.cinsert.o:insert.cdefs.hbuffer.h gcc-cinsert.csearch.o:search.cdefs.hbuffer.h gcc-csearch.cfiles.o:files.cdefs.hbuffer.hcommand.h gcc-cfiles.cutils.o:utils.cdefs.h gcc-cutils.cclean: rmedit$(objects)makefile规则/*main.c*/#include"hello.h"intmain(void){hello();return0;}/*hello.c*/#include<stdio.h>inthello(void){printf("Helloworld!\n");return0;}/*hello.h*/inthello(void);hello:main.ohello.o//依赖关系 gccmain.ohello.o–ohellomain.o:main.chello.h//依赖关系 gcc-Wall–O2–cmain.c–omain.ohello.o:hello.chello.h//依赖关系 gcc-Wall–O2–chello.c–ohello.oclean: rm–rhellomain.ohello.oCC=gccobjs=main.ohello.oCFLAGS=-Wall–O2
hello:$(objs) $(CC)$(objs)–ohellomain.o:main.chello.h $(CC)$(CFLAGS)–cmain.c-omain.ohello.o:hello.chello.h $(CC)$(CFLAGS)–chello.c–ohello.oclean: rm–rhello$(objs)修改后的makefile:ARM编译器hello:main.ohello.o gccmain.ohello.o–ohellomain.o:main.chello.h gcc-Wall–O2–cmain.c–omain.ohello.o:hello.chello.h gcc-Wall–O2–chello.c–ohello.oclean: rm–rhellomain.ohello.o原来的makefile:CC=arm-linux-gcc几个常用的变量$@:扩展为当前规则的目标文件名$<:扩展为当前规则的依赖文件列表中的第一个文件名$^:扩张为当前规则的所有依赖文件(自动除去重复文件)CC=gccobjs=main.ohello.oCFLAGS=-Wall–O2
hello:$(objs) $(CC)–ohello$(objs)main.o:main.chello.h $(CC)$(CFLAGS)–cmain.c-omain.ohello.o:hello.chello.h $(CC)$(CFLAGS)–chello.c–ohello.oclean: rm–rhello$(objs)CC=gccobjs=main.ohello.oCFLAGS=-Wall–O2
hello:$(objs) $(CC)–o$@$^main.o:main.chello.h $(CC)$(CFLAGS)–c$<-o$@hello.o:hello.chello.h $(CC)$(CFLAGS)–c$<–o$@clean: rm–rhello$(objs)练习一使用变量,修改程序的makefile/*main.c*/#include"hello.h“#include“printstar.h”intmain(void){hello();print_star(2,3);return0;}/*hello.c*/#include<stdio.h>inthello(void){printf("Helloworld!\n");return0;}/*hello.h*/inthel
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 二零二五年度婚姻法律咨询合同:诉讼离婚与协议离婚选择策略
- 2025版门楼安全防范系统设计与实施合同4篇
- 二零二五版环保型排水系统设计施工一体化合同4篇
- 2025年度教育培训机构派遣教师劳动合同
- 2025年度个人住房抵押借款合同范本(全新修订版)2篇
- 2025年度成人外语培训机构课程及教学资源转让合同4篇
- 2025年度钢构结构检测分包服务合同
- 2025年跨境电子商务平台合作经营合同2篇
- 2025年度个人货运货物安全处理合同范本大全4篇
- 林地生态补偿与扶贫合作合同(2025版)3篇
- 脑梗死合并癫痫病人的护理查房
- 苏教版四年级上册脱式计算300题及答案
- 犯罪现场保护培训课件
- 扣款通知单 采购部
- 电除颤操作流程图
- 湖北教育出版社三年级下册信息技术教案
- 设计基础全套教学课件
- IATF16949包装方案评审表
- 人教版八年级美术下册全册完整课件
- 1 运行方案说明
- 北京房地产典当合同
评论
0/150
提交评论