makefile详解(一)

本文介绍了Makefile的基本概念及其在软件编译过程中的应用。通过生动的例子,详细解释了Makefile的规则构成,包括目标、前提和命令,以及如何使用make程序进行解析和执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

PS:直接从WORD文档拷贝,如存在部分格式问题请谅解

 

1 什么是makefile

什么是makefile,说简单点makefile就是一种脚本语言。就像其它脚本语言一样(例如HTML,JAVASCIRPT)往往是用来完成某种特定功能,并且拥有自己的语法。因此学习makefile就是要了解makefile是用来干什么的,以及它的语法规则。

 

那么makefile是用来干什么的呢?

打个比方,假如人只有在肚子饿了的时候才吃饭,而要有饭吃就必须自己做饭。那么我们可以说,吃饭的前提是肚子饿了,而要达到吃饭这个目标,必须有做饭这个行为。因此我们就有了下面的这样一个表达式:

吃饭(目标):肚子饿(前提)

           做饭(行为)

 

现在可以开始解释什么是makefile了:所谓makefile,就是当某个前提成立的时候,为某个目标执行某种行为的脚本(这个是俺自己的定义,可能与官方定义不太一样,仁者见仁了,呵呵)

 

不过在makefile的官方术语中,一般将“行为”称为“命令”,因此makefile[LU1] 就是当某个前提成立的时候,为某个目标执行某种命令的脚本。上面的表达式可以更新为:

目标(Target):前提(DEPENDENCIES)

 命令(Command)

 

一般在makefile中,将上面的一个表达式称为“规则(Ruler)

 

这里需要像大家说明的是,上面的例子其实不太精确。因为在makefile中前提和目标往往是文件(当然目标也可能不是文件)。而在makefile中前提成立的条件一般是目标文件不存在或者目标文件的时间戳比前提文件的时间老。这个前提成立时,就执行规则中的命令。

看下面的例子:

例1       文档拷贝更新

file1.doc:file2.doc

         copy file2.doc file1.doc

        

假设在系统上file1.doc最近的更新日期为2009-11-11 3:20, file2.doc最近的更新日期为2009-11-11 4:20,很明显file1.doc的时间的时间比file2.doc的时间老。因此当在make程序中指定目标file1.doc的时候,make就会执行Shell命令copy file1.doc file2.doc,用file2.doc覆盖file1.doc

相反,如果file.doc的时间戳不比file2.doc的时间戳老,当在make程序中指定目标file1.doc的时候,make就不会执行命令copy file1.doc file2.doc

 

Makefile为什么要用时间戳作为前提的判定条件呢?我们知道大家一般都是用makefile来搭建编译环境的。假设我们有一个源文件叫做test.c,编译生成的目标文件为test.o,因此我们可以用makefile编写下面的规则:

例2      Makefile时间戳前提判定条件

test.o : test.c

         gcc –o test.o –c test.c

 

 

还有几点需要说明的是

(1)前提本身可能也是一个目标。

什么意思呢?我们来看下面的例子:

 

假设我们要编译生成一个可执行程序 ,这个可执行程序叫做app,它由一个叫做app.o的对象文件联编生成,而app.o是由app.c编译生成。因此就有了下面的makefile脚本。

例3      前提也可作为目标

 

app : app.o

         gcc –lm –o app app.o

 

app.o : app.c

         gcc –Wall –g –std=c99 –o app.o –c app.c

 

假设时间戳关系为:app比app.o 老,app.o比app.c老

当在make中执行目标app所在规则的时候, app依赖于app.o,由于make发现app.o也是一个目标,因此会先执行目标app.o所在的规则;该规则会在满足前提条件的情况下,生成app.o;紧接着会再执行app所在规则,该规则会在满足前提条件的情况下,生成可执行程序app。

 

(2)一个目标可以有多个前提。

 

在实际中,一个目标往往会依赖多个规则。例如要生成一个可执行程序往往要一来多个对象文件,而生成一个对象文件往往要依赖一个源文件和多个头文件。

例4      一个目标多个前提

app:obj1.o obj2.o obj3.o

         gcc –lm –o app  obj1.o obj2.o obj3.o

obj1.o : obj1.c hearder1.h hearder2.h

         gcc –Wall –g –std=c99 –o obj1.o –c obj1.c

 

obj2.o : obj2.c hearder1.h hearder2.h

         gcc –Wall –g –std=c99 –o obj2.o –c obj2.c

 

obj3.o : obj3.c hearder1.h hearder2.h

         gcc –Wall –g –std=c99 –o obj3.o –c obj3.c

 

 (3) 一个makefile中可以有多个规则。

在例3的makefile中,存在两个规则:目标app所在的规则,目标app.o所在的规则,这两个规则的关系是规则app依赖于规则app.o。

 

一个makefile中可以存在多个规则,可以在make程序中指定执行哪个规则,例如如果在例3中我们只想生成app.o,并不想生成可执行程序app, 那么我们可以像下面这样执行例3中的makefile脚本

 

make –f example3.mk app.o

 

这里我们假设例3中的makefile脚本保存在文件example3.mk中,-f选项告知make程序要运行的makefile文件,这里就是example3.mk, 紧跟在后面的app.o则是告知make程序要执行的规则。

 

当然在make中也可以存在多个相关独立,无依赖关系的规则,如下例所示

例5      一个makefile多个规则

app1: app1.o

         gcc –lm –o app1 app1.o

 

app1.o: app1.c

         gcc –Wall –g –std=c99 –o app1.o –c app1.c

 

app2: app2.o

         gcc –lm –o app1 app1.o

 

app2.o: app2.c

         gcc –Wall –g –std=c99 –o app2.o –c app2.c

 

利用例5中的makefile脚本我们可以生成两个可执行程序:app1和app2。依次执行下面的命令就可以用make程序每次指定一个规则,分别生成app1和app2(假设例5中的makefile脚本保存在文件example5.mk中):

         make –f example5.mk app1

         make –f example5.mk app2

 

2 什么是make

       在上一节,像大家简单介绍了一下什么是makefile,以及makefile的最基本的语法。我们知道makefile说简单点就是一种脚本,就像其它脚本一样,需要一个工具(或程序)去解析和执行它。举个例子,大家都知道HTML,HTML就是一种脚本,是用来描述静态网页的脚本,而要显示出网页来,必须有一个工具(或程序)来解析和执行HTML脚本,这个工具(或程序)我们通常称为浏览器,例如IE,FireFox等。

         而用来解析和执行makefile脚本的工具(或程序)就是make程序。因此make本质是一个可执行程序,用来解析和执行makefile脚本。[LU2] 

        

         通常运行make程序解析和执行makefile脚本的时候,需要告诉make程序makefile脚本的文件名和要执行的规则

例6      指定makefile文件和规则

make  -f mk\mymakefile myTarget

make  --filename=mk\mymakefile myTarget

make  --makefile=mk\mymakefile myTarget

 

例6中-f、--filename、--makefile都是make程序的命令行选项,这三个选项是等同的,都用来指定要解析和执行的makefile文件,在这里就是当前目录下的mk目录下的mymakefile文件。myTarget则是make要执行的规则的目标。

 

我们还可以下面这样运行make程序,可以不指定makefile文件名

make  myTarget

大家可能会问了,例7没有告诉make程序要执行的makefile文件,它怎么运行?答案是:make程序会在当前目录下寻找名称叫做makefile或Makefile文件,并解析和执行它,如果找不到,则make程序报错

 

甚至可以不用指定目标,如下所示:

         make

会发生什么呢?make程序会在当前目录下寻找名称叫做makefile或Makefile文件,并解析和执行它, 并运行(或称为构建)它的第一个目标

例如例5的makefile脚本如果保存在当前目录的名称为makefile的文件中,上面的命令就会构建它的第一个目标app1。

 

相信现在大家对makefile有了一个基本的认识了吧,有兴趣的同学可继续参考《makefile详解(二)》。

 

 

想了解makefile的可以看看!!! 目录: Ⅰ)概述 3 Ⅱ)关于程序的编译和链接 3 Ⅲ)Makefile 介绍 4 Makefile的规则 4 二、个示例 5 三、make是如何工作的 6 四、makefile中使用变量 7 五、让make自动推导 8 六、另类风格的makefile 9 七、清空目标文件的规则 9 Ⅳ)Makefile 总述 10 Makefile里有什么? 10 二、Makefile的文件名 11 三、引用其它的Makefile 11 四、环境变量 MAKEFILES 12 五、make的工作方式 12 Ⅴ)书写规则 12 、规则举例 13 二、规则的语法 13 三、在规则中使用通配符 14 四、文件搜寻 14 五、伪目标 15 六、多目标 17 七、静态模式 17 八、自动生成依赖性 19 Ⅵ)书写命令 20 、显示命令 21 二、命令执行 21 三、命令出错 22 四、嵌套执行make 22 五、定义命令包 24 Ⅶ)使用变量 24 、变量的基础 25 二、变量中的变量 25 三、变量高级用法 27 四、追加变量值 30 五、override 指示符 30 六、多行变量 31 七、环境变量 31 八、目标变量 32 九、模式变量 33 Ⅷ)使用条件判断 33 、示例 33 二、语法 34 Ⅸ)使用函数 36 、函数的调用语法 36 二、字符串处理函数 37 三、文件名操作函数 40 四、foreach 函数 41 五、if 函数 42 六、call函数 42 七、origin函数 43 八、shell函数 44 九、控制make的函数 44 Ⅹ)make 的运行 45 make的退出码 45 二、指定Makefile 45 三、指定目标 46 四、检查规则 47 五、make的参数 48 Ⅺ)隐含规则 51 、使用隐含规则 51 二、隐含规则览 52 三、隐含规则使用的变量 54 四、隐含规则链 57 五、定义模式规则 57 六、老式风格的"后缀规则" 61 七、隐含规则搜索算法 62 Ⅻ)使用make更新函数库文件 63 、函数库文件的成员 63 二、函数库成员的隐含规则 63 三、函数库文件的后缀规则 64 四、注意事项 64 O)后序 64
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值