Chinaunix首页 | 论坛 | 博客
  • 博客访问: 83516
  • 博文数量: 15
  • 博客积分: 301
  • 博客等级: 二等列兵
  • 技术积分: 180
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-07 13:51
个人简介

热爱户外运动,热爱Linux系统

文章分类

全部博文(15)

文章存档

2014年(1)

2013年(8)

2012年(6)

我的朋友

分类: LINUX

2013-03-11 21:57:45


什么是make?

make是一种自动化工具,用于解决更新依赖问题。所谓更新依赖,是指一个对象的更新,会导致其它对象过期,失效,必须重新创建或更新过期对象,以保证过期对象的有效性。这里的对象,一般是指文件。例如,源文件main.c在编译之后生成目标文件main.o,当main.c更新后,我们必须重新编译生成main.o, main.o的更新依赖于main.c,  make 就擅长处理这类问题,主要用于自动控制大型程序源代码的编译流程,像Linux内核的编译。

 

什么是Makefile?

make之所以能够自动解决更新依赖问题,是因为有“人”告诉它各对象之间的更新依赖关系,以及如何解决更新依赖的方法, 这个“人”就是MakefileMakefile的核心任务就是:

1.       告诉make, 什么时候对象过期

2.       告诉make, 如何处理过期对象

 

Makefile 的命名。

GNU make默认识别的Makefile文件名,依次为GNUmakefile , makefile, Makefile。若不使用上述标准命名,则必须使用-f name—file=name 选项指定文件名。GNUmakefile 仅能被GNU make识别,其它的make无法识别,一般不使用。一般使用makefile Makefile。推荐使用Makefile。因为,在目录列表中,Makefile靠近起始部分,并且靠近其它重要文件,例如README

 

Makefile rule 的语法格式

依赖关系 + 解决方法 = 规则(rule),是Makefile最核心,最基本的东西,其语法格式有两种:

1.

target 。。。 : prerequisites 。。。

    recipe

    。。。

2.

target 。。。 : prerequisites 。。。 ;recipe

    recipe

    。。。

 

其中target(目标)与 prerequisite (前提)构成了依赖关系,而recipe(方法)构成了解决方法

 

依赖关系有两层含义,分别是更新依赖,更新顺序依赖

 

更新依赖

target永远是最年轻的(时间戳最新),它见不得任何一个prerequisite比它年轻,若存在这样的prerequisite, target将涅磐重生。

这是一种更新依赖关系,即:prerequisite的更新导致target的更新。

 

更新顺序依赖

target需要更新时, make首先把prerequisites分别作为一个target,尝试对其更新,等所有的prerequisite处理完毕,再对target进行更新处理,这是一个递归处理过程, 也是一种更新顺序依赖关系,即:prerequisite 的更新先于target的更新。

 

说到依赖关系,不得不提prerequisite的分类,实际上,prerequisite分两类,分别是普通,顺序,类属的划分跟依赖关系的含义相关。普通prerequisite(normal prerequisite)满足依赖关系的两层含义,而顺序prerequisiteorder-only prerequisite)只满足依赖关系的更新顺序依赖,不满足更新依赖,也就是说,此prerequisite的更新,不会导致target的更新,但当target需要更新时,此prerequisite会像其它普通prerequisite一样,参与target的更新。在rule的语法格式中,用如下方式区分两类prerequisite, order-only-prerequisite置于normal-prerequisite的后面,并用“|”隔开,其中normal-prerequisite可以为空,但“|”不可省略。

 

targets normal-prerequisites | order-only-prerequisites

 

 

解决方法

recipeshell命令构成,负责target的涅槃(一般情况是这样), make不会直接执行recipe, 而是把它丢给shell处理,另外,recipe行(新行,不包含直接跟在prerequisite之后的recipe)必须以Tab键(或.RECIPEPREFIX的值)打头,这些都是需要特别注意的地方。

 

同一个target可以同时处在多条rule中,多个target也可同时处在一条rule中,如下所示

1. target A, 处在三条rule

A B C

recipeA1

 

A B D

recipeA2

 

    A E

 

2. target A, B, C处在一条rule

A B C D

recipeABC

 

make 对上述规则的处理原则是一致的:一个target对应一条规则。

当一个target分处在多条规则中时,make会把多条规则合成一条规则,规则的prerequisite是所有prerequisite的集合,而recipe是最后一个非空recipe。经make处理后,例1的结果为

 

A B C D E

recipeA2

 

当一个规则有多个target时,make会把此规则分解成多条规则,每一个target独占一条规则,分解出的多条规则,除target不一样外,其它完全相同。经make处理后,例2的结果为

 

A D

recipeABC

 

B D

recipeABC

 

C D

recipeABC

 

简单的说就是,

 

多目标,要分解

多规则,要合一

 

一句话,经make处理后的 makefile,每一条规则只包含一个target,规则与规则的target都是唯一的,均不相同。

 

需要注意的几个点:

1.       一条规则中不仅可有多个prerequisite,也可有多个target,相互之间以空格间隔。

2.       recipe行必须以Tab键(或.RECIPEPREFIX的值)打头。

3.       只要以Tab键(或.RECIPEPREFIX的值)打头的行,make均视作recipe

4.       prerequisite recipe均可以为空,但target不得为空。

5.       recipeshell命令组成,并由shell负责执行,make不参与recipe的执行。

 

除了规则外,Makefile还包含变量,指令,注释




阅读(1823) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~