makefile的编写.ppt
- 文档编号:171239
- 上传时间:2022-10-05
- 格式:PPT
- 页数:39
- 大小:701KB
makefile的编写.ppt
《makefile的编写.ppt》由会员分享,可在线阅读,更多相关《makefile的编写.ppt(39页珍藏版)》请在冰豆网上搜索。
Makefile编写,目的:
掌握make的基本语法,使用make编译程序。
8.1.1Make概述,makefile定义整个工程的编译规则一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。
自动化编译只需要一个make命令,整个工程完全自动编译;make是一个命令工具,是一个解释makefile中指令的命令工具;一般来说,大多数的IDE都有这个命令,比如:
Delphi的make,VisualC+的nmake,Linux下GNU的make。
可见,makefile都成为了一种在工程方面的编译方法。
Makefile里主要有什么,显式规则、隐晦规则、变量定义、文件指示和注释。
1、显式规则。
显式规则说明了,如何生成一个或多的的目标文件。
这是由Makefile的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。
2、隐晦规则。
由于我们的make有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略地书写Makefile,这是由make所支持的。
3、变量的定义。
在Makefile中我们要定义一系列的变量,变量一般都是字符串,这个有点你C语言中的宏,当Makefile被执行时,其中的变量都会被扩展到相应的引用位置上。
4、文件指示。
其包括了三个部分,一个是在一个Makefile中引用另一个Makefile,就像C语言中的include一样;另一个是指根据某些情况指定Makefile中的有效部分,就像C语言中的预编译#if一样;还有就是定义一个多行的命令。
有关这一部分的内容,我会在后续的部分中讲述。
5、注释。
Makefile中只有行注释,和UNIX的Shell脚本一样,其注释是用“#”字符。
如果你要在你的Makefile中使用“#”字符,可以用反斜框进行转义,如:
“#”。
8.1.2关于程序的编译和链接,无论是C、C+,首先要把源文件编译成中间代码文件,在Windows下是.obj文件,UNIX下是.o文件,即目标文件,这个动作叫做编译(compile)。
然后再把大量的目标文件链接成执行文件,这个动作叫作链接(link)。
编译时,编译器检查语法,函数与变量的声明是否正确。
对于声明,通常需要你告诉编译器头文件所在的位置(头文件中应该只是声明,而定义应该放在源文件中),只要所有的语法正确,编译器就可以编译出中间目标文件。
一般来说,每个源文件可以生成一个中间目标文件(.o文件或是.obj文件)。
关于程序的编译和链接,链接时,主要是找到函数和全局变量的定义。
链接器并不管函数所在的源文件,只管函数的中间目标文件(ObjectFile)。
在大多数时候,由于源文件太多,编译生成的目标文件太多,而在链接时需要明显地指出中间目标文件名,这对于编译很不方便,所以,我们要给中间目标文件打个包,在Windows下这种包叫“库文件”(LibraryFile),也就是.lib文件,在UNIX下,是ArchiveFile,也就是.a文件或.so下面是一个包含三个文件的工程,8.1.3准备文件file1.c,#include#includefile2.hintmain()printf(printfile1n);File2Print();return0;,返回,准备文件file2.c,#includefile2.hvoidFile2Print()printf(Printfile2n);,返回,准备文件file2.h,#ifndefFILE2_H_#defineFILE2_H_#includevoidFile2Print();#endif,返回,8.1.4Makefile里的主要规则,target.:
mand.target是一个目标文件,可以是ObjectFile,也可以是执行文件。
还可以是一个标签(伪目标)。
prerequisites是要生成那个target所需要的文件或是目标。
command也就是make需要执行的命令。
(任意的Shell命令)文件的依赖关系,也就是说,target是需要生成的一个或多个文件,它们依赖于prerequisites.中列出的文件,通过执行command来生成target.。
一个规则可以有多个命令行,每一条命令占一行。
注意:
每一个命令行必须以Tab字符开始,Tab字符告诉make此行是一个命令行。
make按照命令完成相应的动作。
这也是书写Makefile中容易产生,而且比较隐蔽的错误。
这就是Makefile的规则,也是Makefile中最核心的内容。
helloworld:
file1.ofile2.ogccfile1.ofile2.o-ohelloworldfile1.o:
file1.cfile2.hgcc-cfile1.c-ofile1.ofile2.o:
file2.cfile2.hgcc-cfile2.c-ofile2.oclean:
rm-rf*.ohelloworld,编写Makefile文件,详细解读Makefile文件,helloworld:
file1.ofile2.ogccfile1.ofile2.o-ohelloworldhelloworld依赖file1.ofile2.o两个文件编译出helloworld可执行文件。
-o表示指定的目标文件名。
若file1.o和file2.o都存在,但是其中一个比helloworld新或helloworld不存在时,执行下面的gcc命令。
若file1.o和file2.o有任意一个不存在,假设是file1.o,会先找到file1.o的生成关系,生成file1.o后,再执行下面的gcc命令。
详细解读Makefile文件(续),file1.o:
file1.cfile2.hgcc-cfile1.c-ofile1.ofile1.o依赖file1.c和file2.h这两个文件,编译出file1.o文件。
若依赖文件中有任意一个文件不存在或比file1.o新,都会重新执行下面的gcc命令。
-c表示gcc只把给它的文件编译成.o文件,用源码文件的文件名命名但把其后缀由“.c”变成“.o”。
在这句中,可以省略-ofile1.o,编译器默认生成file1.o文件,这就是-c的作用。
file2.o:
file2.cfile2.hgcc-cfile2.c-ofile2.o这两句的功能同上。
返回,详细解读Makefile文件(续),clean:
rm-rf*.ohelloworld#当用户输入makeclean命令时,会执行rm指令,其功能是删除*.o和helloworld文件。
写好Makefile文件,在命令行中直接键入make命令,就会执行Makefile中的内容了,返回,假设一个工程有3个头文件,和8个源文件,我们按照那三个规则写出的makefile应该是下面的这个样子的。
edit:
main.okbd.ocommand.odisplay.oinsert.osearch.ofiles.outils.occ-oeditmain.okbd.ocommand.odisplay.oinsert.osearch.ofiles.outils.omain.o:
main.cdefs.hcc-cmain.ckbd.o:
kbd.cdefs.hcommand.hcc-ckbd.ccommand.o:
command.cdefs.hcommand.hcc-ccommand.c,display.o:
display.cdefs.hbuffer.hcc-cdisplay.cinsert.o:
insert.cdefs.hbuffer.hcc-cinsert.csearch.o:
search.cdefs.hbuffer.hcc-csearch.cfiles.o:
files.cdefs.hbuffer.hcommand.hcc-cfiles.cutils.o:
utils.cdefs.hcc-cutils.cclean:
rmeditmain.okbd.ocommand.odisplay.oinsert.osearch.ofiles.outils.o,在这个makefile中,目标文件(target)包含:
执行文件edit和中间目标文件(*.o)。
依赖文件(prerequisites)就是冒号后面的那些.c文件和.h文件。
每一个.o文件都有一组依赖文件,而这些.o文件又是执行文件edit的依赖文件。
依赖关系的实质上就是说明了目标文件是由哪些文件生成的,换言之,目标文件是哪些文件更新的。
make如何工作,在默认的方式下,也就是我们只输入make命令。
那么:
1、make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
2、默认的情况下,make执行的是Makefile中的第一个规则。
此规则的第一个目标称之为“最终目的”或者“终极目标”。
在上面的例子中,它会找文件中的第一个目标文件(target),即“edit”这个文件,并把这个文件作为最终的目标文件。
3、如果edit文件不存在,或是edit所依赖的后面的.o文件的文件修改时间要比edit这个文件新,那么,他就会执行后面所定义的命令来生成edit这个文件。
4、如果edit所依赖的.o文件也不存在,那么make会在当前文件中找目标为该.o文件的依赖规则,如果找到则再根据那一个规则生成.o文件。
(这有点像一个栈的过程)5、前提你的.c文件和.h文件是存在,make如何工作,这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。
在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理。
通过上述分析,我们知道,像clean这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,不过,我们可以显示要make执行。
即命令“makeclean”,以此来清除所有的目标文件,以便重编译。
使用变量,取得变量值的方式:
$(变量名)或$变量名定义变量=使用时展开:
=定义时即展开(只能使用已经定义好的变量)+=变量追加?
=若未定义则定义,若已定义则不执行此定义例如:
objects=main.okbd.ocommand.odisplay.oinsert.osearch.ofiles.outils.o于是,我们就可以很方便地在我们的makefile中以“$(objects)”的方式来使用这个变量了,变量基础,objects=program.ofoo.outils.oprogram:
$(objects)cc-oprogram$(objects)或者:
cc$-o$和$属于自动化变量$表示规则中的目标文件集。
在模式规则中,如果有多个目标,那么,$就是匹配于目标中模式定义的集合。
这里是program$所有的依赖目标的集合。
以空格分隔。
如果在依赖目标中有多个重复的,那个这个变量会去除重复的依赖目标,只保留一份。
这里是$(objects)$(objects):
defs.h变量会在使用它的地方精确地展开,就像C/C+中的宏一样,Makefile里使用变量,OBJS=file1.ofile2.oCC=gccCFLAGS=-Wall-Og-Wall:
输出所有的警告信息;-O:
在编译时进行优化;-g:
表示编译debug版本。
helloworld:
$(OBJS)$(CC)$(OBJS)-ohelloworldfile1.o:
file1.cfile2.h$(CC)$(CFLAGS)-cfile1.c-ofile1.ofile2.o:
fi
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- makefile 编写