允执 引商刻羽,杂以流徵

Makefile的知识

本文根据李云的博客及别的一些知识整理而来,作为我在写作Makefile中的一些参考。

Makefile的规则

1. 目标

当没有指明具体的目标是什么时,那么 make 以 Makefile 文件中定义的第一个目标作为这次运行的目标。这“第一个”目标也称之为默认目标。要使 make 不打印出命令, 只要做一点小小的修改就行了,就是在命令前加了一个‘@’。

Makefile
all:
	@echo "Hello,wold"

2. 依赖

make 工具会按从左到右的先后顺序先构建规则中所依赖的每一个目标

targets : prerequisites
	command
	...

make在运行一个规则时,我们前面已经提到了目标和先决条件之间的依赖关系,make 在检查一个规则时,采用的方法是:如果先决条件中相关的文件的时间戳大于目标的时间戳,即先决条件中的文件比目标更新, 则知道有变化,那么需要运行规则当中的命令重新构建目标。这条规则会运用到所有与我们在 make 时指定的目标的依赖树中的每一个规则。

3. 假目标

在现实中也难免存在所定义的目标与所存在的文件是同名的,采用 Makefile 如何处理这种情况呢?Makefile 中的假目标(phony target)可以解决这个问题。假目标可以采 用.PHONY 关键字来定义,需要注意的是其必须是大写字母。

Makefile

.PHONY: clean

simple.exe: main.o foo.o
	gcc -o simple.exe main.o foo.o
main.o: main.c
	gcc -o main.o -c main.c
foo.o: foo.c
	gcc -o foo.o -c foo.c
clean:
	rm simple.exe main.o foo.o

对于假目标,我们可以想像的是由于并不与文件关联,所以每 一次 make 这个假目标时,其所在的规则中的命令都会被执行。

4.变量

变量的引入增加了 Makefile 的可维护性。

4.1 自动变量

Makefile中的自动变量,它们包括:

需要注意的是,在 Makefile 中‘$’ 具有特殊的意思,因此,如果想采用 echo 输出‘$’,则必需用两个连着的‘$’。还有就是,$@对 于 Shell 也有特殊的意思,我们需要在“$$@”之前再加一个脱字符‘\’。

包含变量后的Makefile:

.PHONY: clean
CC = gcc RM = rm
EXE = simple.exe
OBJS = main.o foo.o

$(EXE): $(OBJS)
	$(CC) -o $@ $^
main.o: main.c
	$(CC) -o $@ -c $^
foo.o: foo.c
	$(CC) -o $@ -c $^

clean:
	$(RM) $(EXE) $(OBJS)

4.2 特殊变量

Makefile 中有几个特殊变量,我们可能经常需要用到。第一个就是 MAKE 变量,它表示的是 make 命令名是什么。第二个特殊变量则是 MAKECMDGOALS,它表示的是当前用户所输入的 make 目标是什么。

MAKECMDGOALS 指的是用户输入的目标,当我们只运行 make 命令时, 虽然根据 Makefile 的语法,第一个目标将成为缺省目标,即 all 目标,但 MAKECMDGOALS 仍然 是空,而不是 all,这一点我们需要注意。

4.3 变量的类别

只用一个“=”符号定义的变量,我们 称之为递归扩展变量(recursively expanded variable)。不能对递归变量再采用赋值操作,否则会陷入死循环。

除了递归扩展变量还有一种变量称之为简单扩展变量(simply expanded variables),是用“:=” 操作符来定义的。对于这种变量,make 只对其进行一次扫描和替换。

Makefile中还存在一种条件赋值符“?=”,条件赋值的意思是当变量以前没有定义时,就定义它并且将左边的值赋值给它,如果已经定义了那么就不再改变其值。条件赋值类似于提供了给变量赋缺省值的功能。

采用“+=”操作符对变量进行斌值的方法相当于在变量后追加目标

4.4 变量及其值来源

4.5 高级变量的引用

foo = a.o b.o c.o
bar := $(foo:.o=.c) #该方法同patsubst,将变量foo中的文件名从.o后缀变成了.c

4.6 override 指令

在设计 Makefile 时,我们并不希望用户将我们在 Makefile 中定义的某个变量覆盖掉,那就得用 override 指令了。

override foo = x

5. 模式

使用统配符 % 来进行相同文件的匹配,达到简化makefile的目的。

.PHONY: clean

CC = gcc

RM = rm

EXE = simple.exe

OBJS = main.o foo.o

$(EXE): $(OBJS) ` $(CC) -o $@ $^`

%.o: %.c ` $(CC) -o $@ -c $^ `

clean: ` $(RM) $(EXE) $(OBJS)`

6.函数

提高

在进行 complicated 项目之前,我们需要了解对于它的 Makefile 的一些基本需求,这些基本需求是:

“Yunzhi made” ©

点击查看评论
推荐到豆瓣

Blog

Opinion

Project