配色: 字号:
9-1 Makefile的高级特性
2022-12-16 | 阅:  转:  |  分享 
  

Makefile 的高级特性
除了前面介绍的规则和注释外 ,Makefile 还支持隐式规 则、变量定义、文件包含等 高级
特性。这里将前面 Makefile 示例修改 如下,然后再结合这些内容介绍一些高级特性。
# 第1 部分
objects = main.o input.o output.o command.o files.o utils.o
# 第2 部分
textedit : $(objects)
cc -o edit $(objects)
# 第3 部分
main.o : defs.h
input.o : defs.h command.h
command.o : defs.h command.h
output.o : defs.h buffer.h
insert.o : defs.h buffer.h
tools.o : defs.h
# 第4 部分
.PHONY : clean
clean :
rm edit $(objects)
(1 )隐式规 则。
前面介绍的规则属于显式规则,需要明确定义,指明要生成的文件、文件的依赖文 件 和
生成的 命令。make 功能很强大,可以自动推导文件以及文件依赖关系后面的命令,这就是
Make?le 的隐 式规则(又称隐含规则或隐晦规则) 。
本例中第 3 部分利用隐式规则简化文件依赖关系的描述。make 每发现一 个.o 文件, 它就
会 自动地把 相应的 .c 文件添加在依 赖关系中。 例如 make 找到 main.o ,就会将 main.c 作
为 main.o 的 依赖文件,并且后续命令 cc -c main.c 也会被自 动推导出来。
make 支持的 隐式规则非常多,可以通过 -p 选项 来查看它所支持的全部隐式规则。
(2 )变量定 义。
在 Make?le 中可以定义 一系列变量 ,变量一般 都是文本字 符串,有点 儿类似于 C/C++
语言中的宏, 当 Make?le 被解析时, 其中的变量都会自动被扩展到相应的引用位置上。 变量
可以用在目标、条件、命令等要素中,以及 Make?le 的其他 部分。
变量的名字可以包含字符、 数字, 下画线 (可以是数字开头) , 但不应 该含有 “:” “#”
“=”或空字符(空格、回车等) 。变 量名区分大小写。
变量在声明时需要赋初值,而在引用时需要在变量名前加上“$” ,而且最好使用圆括 号
“( )” 或花 括号 “{}” 将变量给标注起来。 如果变量名中要使用 “$ ” 字 符, 那么需要用 “$$”
来进行转义。
本例第 1 部 分声明变量 objects :
objects = main.o input.o output.o command.o ?les.o utils.o
第 2 部分引 用变量 :
textedit : $(objects)
cc -o edit $(objects)
变量会在使用它的地方精确地展开,就像 C/C++ 中的宏一 样,展开后如下 :
textedit : main.o input.o output.o command.o ?les.o tools.o
cc -o textedit main.o input.o output.o command.o ?les.o utils.o
变量用 “= ” 赋值时, 表示变量被引用时才展开。 如果改用 “:= ” 赋值, 表示变量在赋值
的时候就立刻展开。
Make?le 还提供一种特殊的自动变量,不用声明,其值根据上下文的不同自动改变 。 如
$@ 代表规则中的目标文件名,$< 代 表规则的第一个依赖文件名(条件定义) 。
(3 )伪目标 。
Ubuntu Linux 操作系统实战(微课版)
上例提到过一个名为“clean ”的目标,这是一个伪目标。伪目标并不是一个文 件,只是
一个标签, 因而 make 无法生成它 的依赖关系 和决定它是 否要执行。 只有通过指 明这个 目 标
才能让其生效。当然,伪目标不能和文件名重名。
为了避免与文件重名的这种情况出现, 可以使用一个特殊的标记 “.PHONY” 来显式地指
明一个目标是伪目标, 向 make 说明 , 不管是否有这个文件, 这个目标就是伪目标。 本例第 4
部分就是这样一个例子。
(4 )使用通 配符。
make 支持通 配符 “”、“ ?”和“[...] ” , 用于代替一系列的文件。 如 “.c ” 表示所有扩展
名为 .c 的文 件。下面的例子表明执行 clean 命 令将删除所有的目标文件。
clean:
rm -f .o
如果文件名中包含有通配符, 如 “ ” , 则可以用 “/”转 义 ,如 用“/”来 表 示“”这 个
字符。
(5 )文件包 含。
在一个 Make?le 文件中可以引用另一个 Make?le 文件,就像 C 语 言中的 include 一
样。被包含的文件会放在当前文件的包含位置。具体的语法格式是 :
include < 文件名 >
可以引用任意多个文件,多个文件用空格分隔,也可使用通配符和变量来表示被引 用 的
文件名。 如 果文件名没有指定绝对路径或是相对路径,make 会首先在 当前目录下寻找。 如果
当前目录下没有找到,make 还会在 make 选项 -I 或 --include-dir 指定的 目录下去寻找。

2
献花(0)
+1
(本文系籽油荃面原创)