Makefile札记之:Makefile工作原理及隐含规则应用

简介:

从只有一个Makefile的单级Makefile开始。



对于一个稍大的项目或者说软件来说,源程序(.c文件或者是.h文件),以及源程序文件夹,绝对不只是一个文件或者源程序文件夹,想想你写的代码只有一个源程序或者程序文件夹还是什么时候。一个好的程序员,总是希望自己写的代码文件,清晰,一目了然,通过不同的文件夹,不用的名字就能大致看出该程序的功能。

当只有一个源程序文件的时候,比如main.h,main.c,这个时候,由于源程序文件少,我们可以手动对程序进行编译:gcc  main.c   -o  main_exe。这个时候,手动编译程序还是很方便的。但是,如果程序有几十甚至几百几千个的时候,这个时候,通过gcc手动的对源程序进行编译的时候,就有困难了。另外,好的程序员会去考虑到程序的可移植性和程序文件之间的关系,我们总是希望把源程序拿过来直接编译然后就能运行,我们会把源程序放在不同的文件夹下。这样一来,对于手动编译程序就更加困难了。这个时候,Makefile优势就显现出来了。

下面以实例来说明Makefile究竟如何编写,

 

 

/*

*************************************

name:example-one.c

*************************************

*/

#include “example-one.h”

{

      …….

      ……..

}

 

 

*************************************

name:example-one.h

养成每个.c源程序都有一个与之同名的.h

与之对应来做一些声明。

*************************************

*/

#include <>

#include <>

 

 

 

 

/*

*************************************

name:example-two.c

*************************************

*/

#include “example-two.h”

#include “example-one.h”

{

      …….

      ……..

}

 

 

*************************************

name:example-two.h

养成每个.c源程序都有一个与之同名的.h

与之对应来做一些声明。

*************************************

*/

#include <>

#include <>

 

 

 

 

 

…..

…..

 

 

*************************************

name:main.c

*************************************

#include “example-two.h”

{

  

}

 

在这里我不讲Makefile的规则,对于这些规则,网上的关于Makefile的编写都大同小异,我主要讲讲Makefile的工作原理。

按照上述文件之间的关系不难看出,example-two.c由于使用了example-one.c的东西,那么当我们编译example-two.c的时候就需要example-one.c。

还是先来说下几个关键词

target:cond

按照Makefile的规则,target就是目标,然后cond就是要编译得到target目标所需要的条件。

其实在很多情况下,我们的Makefile可以只写出

%:%.o

这个规则就可以了。

以这个例子为例。虽然按照实际情况上来说,有个层次关系,main.o的编译需要example-two.c, example-two.h作为必要条件,同理,example-two.o需要example-one.h和example-one.c作为必要条件。

但是,你可以试试,这个例子的Makefile可以简化到如此简单:

OBJS := main.o example-one.o example-two.o

EXEC := test

$(EXEC):$(OBJS)

tab           gcc –o $(EXEC)  $(OBJS)

 

写好commamd之后,make就可以编译出程序了,绝对没问题。

Makefile其实也是一种脚本语言。他只需要知道编译成可执行程序EXEC所必须的目标文件OBJS有哪些(这里对于将目标文件.o文件,源文件 .h, .c文件同名很重要,所以要养成这种习惯会给变成带来很大的方便的)。

    GNU 的make 工作时的执行步骤入下:

1、读入所有的Makefile。

2、读入被include 的其它Makefile。

3、初始化文件中的变量。

4、推导隐晦规则,并分析所有规则。

5、为所有的目标文件创建依赖关系链。

6、根据依赖关系,决定哪些目标要重新生成。

7、执行生成命令。

当make一旦知道可执行文件所需的目标文件.o文件之后,他发现要生成可执行文件需要哪些.o文件,他就会在你所指定的目录已经当前目录中查找,当他找不到某一.o文件的时候,就会启动隐含规则去试图生成.o文件。同样,当生成.o文件的时候就会去找相应的.c文件和.h文件。这才是这个例子会有如此简单的Makefile的真正原因。而Makefile的编写工作最终落实到你给出文件,让make去找文件。而本身源程序.c文件中的include也同时告诉Makefile,.c文件需要哪些.h条件,所以在由.c文件到.o文件的过程中可以由它自动来完成,不需要我们明确的显示的告诉他这些关系。

给个不恰当的比喻:.c  .h文件相当于人,通过#include  已经extern 等血缘关系,在make之后,构成了家庭这种.o文件。

family.o: zhang.c   wang.c   zhang_son.h

所有的人都用过这种关系来构成家庭。

然后那么社区这种可执行文件是有家庭这种.o文件构成的。那么在组装可执行文件这一阶段只需要列出该社区的所有的家庭,于是也就自动完成了社区的组建。

community:family_one.o  family_two.o…

总之,在组装可执行程序的规则中,要列出所需要的所有的.o文件。

 

 

 

 

 

 


版权申明:
转载文章请注明原文出处http://blog.csdn.net/feiyinzilgd/archive/2010/02/07/5297161.aspx
并请联系谭海燕本人或者前往谭海燕个人主页留言 

 

 

目录
相关文章
|
3天前
|
编译器 Shell Linux
Makefile(2)原理
Makefile(2)原理
19 0
|
6月前
|
Linux Windows
makefile 结构规则,依赖,伪目标
makefile 结构规则,依赖,伪目标
40 0
|
Shell Linux 开发工具
【六、深度解析Makefile】工程文件编译链接的“规则制定者”:带你走进 makefile 的世界(一)
【六、深度解析Makefile】工程文件编译链接的“规则制定者”:带你走进 makefile 的世界
351 0
【六、深度解析Makefile】工程文件编译链接的“规则制定者”:带你走进 makefile 的世界(一)
|
NoSQL Shell Linux
【六、深度解析Makefile】工程文件编译链接的“规则制定者”:带你走进 makefile 的世界(三)
【六、深度解析Makefile】工程文件编译链接的“规则制定者”:带你走进 makefile 的世界
205 0
【六、深度解析Makefile】工程文件编译链接的“规则制定者”:带你走进 makefile 的世界(三)
|
自然语言处理 算法 NoSQL
【六、深度解析Makefile】工程文件编译链接的“规则制定者”:带你走进 makefile 的世界(二)
【六、深度解析Makefile】工程文件编译链接的“规则制定者”:带你走进 makefile 的世界
153 0
【六、深度解析Makefile】工程文件编译链接的“规则制定者”:带你走进 makefile 的世界(二)
|
小程序 C语言
玩转Makefile | 一次编译多个目标
玩转Makefile | 一次编译多个目标
479 0
玩转Makefile | 一次编译多个目标