没有合适的资源?快使用搜索试试~ 我知道了~
首页"深入了解Makefile:规则、示例及变量使用"
资源详情
资源推荐
12
五、make 的工作方式
GNU 的 make 工作时的执行步骤入下:(想来其它的 make 也是类似)
1. 读入所有的 Makefile。
2. 读入被 include 的其它 Makefile。
3. 初始化文件中的变量。
4. 推导隐晦规则,并分析所有规则。
5. 为所有的目标文件创建依赖关系链。
6. 根据依赖关系,决定哪些目标要重新生成。
7. 执行生成命令。
1-5 步为第一个阶段,6-7 为第二个阶段。第一个阶段中,如果定义的变量被使
用了,那么,make 会把其展开在使用的位置。但 make 并不会完全马上展开,
make 使用的是拖延战术,如果变量出现在依赖关系的规则中,那么仅当这条依
赖被决定要使用了,变量才会在其内部展开。
当然,这个工作方式你不一定要清楚,但是知道这个方式你也会对 make 更为
熟悉。有了这个基础,后续部分也就容易看懂了。
书写规则
————————
规则包含两个部分,一个是依赖关系,一个是生成目标的方法。
在 Makefile 中,规则的顺序是很重要的,因为,Makefile 中只应该有一个最终
目标,其它的目标都是被这个目标所连带出来的,所以一定要让 make 知道你
的最终目标是什么。一般来说,定义在 Makefile 中的目标可能会有很多,但是
第一条规则中的目标将被确立为最终的目标。如果第一条规则中的目标有很多
个,那么,第一个目标会成为最终的目标。make 所完成的也就是这个目标。
一、规则举例
foo.o : foo.c defs.h # foo 模块
13
cc -c -g foo.c
看到这个例子,各位应该不是很陌生了,前面也已说过,foo.o 是我们的目标,
foo.c 和 defs.h 是目标所依赖的源文件,而只有一个命令“cc -c -g foo.c”(以 Tab
键开头)。这个规则告诉我们两件事:
1. 文件的依赖关系,foo.o 依赖于 foo.c 和 defs.h 的文件,如果 foo.c 和 defs.h 的
文件日期要比 foo.o 文件日期要新,或是 foo.o 不存在,那么依赖关系发生。
2. 如何生成(或更新)foo.o 文件。也就是那个 cc 命令,其说明了,如何生成
foo.o 这个文件。(当然 foo.c 文件 include 了 defs.h 文件)
二、规则的语法
targets : prerequisites
command
...
或是这样:
targets : prerequisites ; command
command
...
targets 是文件名,以空格分开,可以使用通配符。一般来说,我们的目标基本
上是一个文件,但也有可能是多个文件。
command 是命令行,如果其不与“target:prerequisites”在一行,那么,必须以[Tab
键]开头,如果和 prerequisites 在一行,那么可以用分号做为分隔。(见上)
prerequisites 也就是目标所依赖的文件(或依赖目标)。如果其中的某个文件要
比目标文件要新,那么,目标就被认为是“过时的”,被认为是需要重生成的。
这个在前面已经讲过了。
如果命令太长,你可以使用反斜框(‘\’)作为换行符。make 对一行上有多少个
字符没有限制。规则告诉 make 两件事,文件的依赖关系和如何成成目标文
件。
一般来说,make 会以 UNIX 的标准 Shell,也就是/bin/sh 来执行命令。
14
三、在规则中使用通配符
如果我们想定义一系列比较类似的文件,我们很自然地就想起使用通配符。
make 支持三各通配符:“*”,“?”和“[...]”。这是和 Unix 的 B-Shell 是相同的。
波浪号(“~”)字符在文件名中也有比较特殊的用途。如果是“~/test”,这就表示
当前用户的$HOME 目录下的 test 目录。而“~hchen/test”则表示用户 hchen 的宿
主目录下的 test 目录。(这些都是 Unix 下的小知识了,make 也支持)而在
Windows 或是 MS-DOS 下,用户没有宿主目录,那么波浪号所指的目录则根据
环境变量“HOME”而定。
通配符代替了你一系列的文件,如“*.c”表示所以后缀为 c 的文件。一个需要我
们注意的是,如果我们的文件名中有通配符,如:“*”,那么可以用转义字符
“\”,如“\*”来表示真实的“*”字符,而不是任意长度的字符串。
好吧,还是先来看几个例子吧:
clean:
rm -f *.o
上面这个例子我不不多说了,这是操作系统 Shell 所支持的通配符。这是在命令
中的通配符。
print: *.c
lpr -p $?
touch print
上面这个例子说明了通配符也可以在我们的规则中,目标 print 依赖于所有的[.c]
文件。其中的“$?”是一个自动化变量,我会在后面给你讲述。
objects = *.o
上面这个例子,表示了,通符同样可以用在变量中。并不是说[*.o]会展开,
不!objects 的值就是“*.o”。Makefile 中的变量其实就是 C/C++中的宏。如果你
要让通配符在变量中展开,也就是让 objects 的值是所有[.o]的文件名的集合,
那么,你可以这样:
objects := $(wildcard *.o)
这种用法由关键字“wildcard”指出,关于 Makefile 的关键字,我们将在后面讨
论。
15
四、文件搜寻
在一些大的工程中,有大量的源文件,我们通常的做法是把这许多的源文件分
类,并存放在不同的目录中。所以,当 make 需要去找寻文件的依赖关系时,
你可以在文件前加上路径,但最好的方法是把一个路径告诉 make,让 make 在
自动去找。
Makefile 文件中的特殊变量“VPATH”就是完成这个功能的,如果没有指明这个
变量,make 只会在当前的目录中去找寻依赖文件和目标文件。如果定义了这个
变量,那么,make 就会在当当前目录找不到的情况下,到所指定的目录中去找
寻文件了。
VPATH = src:../headers
上面的的定义指定两个目录,“src”和“../headers”,make 会按照这个顺序进行搜
索。目录由“冒号”分隔。(当然,当前目录永远是最高优先搜索的地方)
另一个设置文件搜索路径的方法是使用 make 的“vpath”关键字(注意,它是全
小写的),这不是变量,这是一个 make 的关键字,这和上面提到的那个
VPATH 变量很类似,但是它更为灵活。它可以指定不同的文件在不同的搜索目
录中。这是一个很灵活的功能。它的使用方法有三种:
1. vpath <pattern>; <directories>;
为符合模式<pattern>;的文件指定搜索目录<directories>;。
2. vpath <pattern>;
清除符合模式<pattern>;的文件的搜索目录。
3. vpath
清除所有已被设置好了的文件搜索目录。
vapth 使用方法中的<pattern>;需要包含“%”字符。“%”的意思是匹配零或若干字
符,例如,“%.h”表示所有以“.h”结尾的文件。<pattern>;指定了要搜索的文件
集,而<directories>;则指定了<pattern>;的文件集的搜索的目录。例如:
vpath %.h ../headers
该语句表示,要求 make 在“../headers”目录下搜索所有以“.h”结尾的文件。(如
果某文件在当前目录没有找到的话)
我们可以连续地使用 vpath 语句,以指定不同搜索策略。如果连续的 vpath 语句
中出现了相同的<pattern>;,或是被重复了的<pattern>;,那么,make 会按照
vpath 语句的先后顺序来执行搜索。如:
剩余80页未读,继续阅读
yuazhang
- 粉丝: 2
- 资源: 13
上传资源 快速赚钱
- 我的内容管理 收起
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
会员权益专享
最新资源
- VMP技术解析:Handle块优化与壳模板初始化
- C++ Primer 第四版更新:现代编程风格与标准库
- 计算机系统基础实验:缓冲区溢出攻击(Lab3)
- 中国结算网上业务平台:证券登记操作详解与常见问题
- FPGA驱动的五子棋博弈系统:加速与创新娱乐体验
- 多旋翼飞行器定点位置控制器设计实验
- 基于流量预测与潮汐效应的动态载频优化策略
- SQL练习:查询分析与高级操作
- 海底数据中心散热优化:从MATLAB到动态模拟
- 移动应用作业:MyDiaryBook - Google Material Design 日记APP
- Linux提权技术详解:从内核漏洞到Sudo配置错误
- 93分钟快速入门 LaTeX:从入门到实践
- 5G测试新挑战与罗德与施瓦茨解决方案
- EAS系统性能优化与故障诊断指南
- Java并发编程:JUC核心概念解析与应用
- 数据结构实验报告:基于不同存储结构的线性表和树实现
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功