Makefile 教程

我们编写的程序代码生成可执行文件,需要经过编译(compile)和链接(link)两个过程。在编译和链接过程中,由于程序代码可能由多个文件组成,就存在先编译哪个,后编译哪个,需要链接哪些模块等问题。

程序代码按照预定的步骤进行编译和链接,生成可执行文件的过程,称之为构建(build)。

 

1. 什么是 Makefile 文件

构建可执行文件,通常使用 make 命令。make 命令执行时,需要一个 Makefile 文件。Makefile 文件中包含了一系列规则,告诉 make 命令如何去编译和链接程序。

make 是最常用的构建工具,诞生于1977年,主要用于 C 语言的项目。但实际上,任何一个项目,只要满足源文件有变化,就要重新构建,都可以用 make 命令。

make 和 Makefile 相关的资料可以参考 Isaac Schlueter 的《Makefile文件教程》和《GNU Make手册》。

 

2. Makefile 文件的规则

Makefile 文件包含了许多规则,指导 make命令 去编译和链接程序。

Makefile 文件是一个纯文本文件,可以使用任何文本编辑器去编辑它的内容。

Makefile 的内容有自己特定的组织方式,是由一系列的规则组成。我们看一下 Makefile 中的单条规则的格式:

target...: prerequisites ...
    command
    ...
  • target:目标文件,可以是 Object File(.o 后缀的文件),也可以是可执行文件,还可以是一个标签,对于标签这种特性,在后续的 “伪目标” 章节中会有叙述。
  • prerequisites:前置条件,即生成 target 所需要的依赖文件。
  • command:也就是 make 需要执行的命令,可以是任意 Shell 命令。

这条规则描述了一个文件的依赖关系。也就是,生成 target 目标文件依赖于 prerequisites 中的文件,生成规则定义在 command中。

换一种说法,prerequisites 中如果有一个以上的文件比 target文件 要新的话,也就是 prerequisites 中的文件做了变动,那么就会 执行 command 所定义的命令。这就是 Makefile 的规则,它是 Makefile 中最核心的内容。

 

3. Makefile 文件的范例

假设一个工程有 3 个头文件,和 8 个 C 文件,最终要生成可执行文件 edit。Makefile 内容如下:

edit : main.o kbd.o command.o display.o insert.o search.o files.o utils.o
	cc -o edit main.o kbd.o command.o display.o \
	insert.o search.o files.o utils.o

main.o : main.c defs.h
	cc -c main.c
	
kbd.o : kbd.c defs.h command.h
	cc -c kbd.c

command.o : command.c defs.h command.h
	cc -c command.c

display.o : display.c defs.h buffer.h
	cc -c display.c

insert.o : insert.c defs.h buffer.h
	cc -c insert.c

search.o : search.c defs.h buffer.h
	cc -c search.c

files.o : files.c defs.h buffer.h command.h
	cc -c files.c

utils.o : utils.c defs.h
	cc -c utils.c

clean :
	rm edit main.o kbd.o command.o display.o \
	insert.o search.o files.o utils.o

反斜杠(\)是换行符,这样便于阅读 Makefile。我们可以把这个内容保存在文件为 “Makefile” 或 “makefile” 的文件中。

在这个 Makefile 中,目标文件(target)包含:执行文件 edit 和 中间目标文件(*.o)。依赖文件(prerequisites)就是冒号后面的那些 .c 文件和 .h文件。每一个 .o 文件都有一组依赖文件,而这些 .o 文件又是执行文件 edit 的依赖文件。依赖关系就是说明了目标文件是由哪些文件生成。

在定义好依赖关系后,后续的那一行定义了如何生成目标文件的操作系统命令,一定要以一个 Tab 键作为开头。 记住,make并不管命令是怎么工作的,他只管执行所定义的命令。make 会比较 targets 文件和 prerequisites 文件的修改日期,如果 prerequisites 文件的日期要比 targets 文件的日期要新,或者 target 不存在的话,那么,make就会执行后续定义的命令。

 

4. 使用 Makefile 文件

Makefile 编辑保存之后,在当前目录下直接输入命令 “make” 就可以生成可执行文件 edit。如果要删除可执行文件和所有的中间目标文件,那么,只要执行一下 “make clean” 就可以了。

Makefile 是一个纯文本文件,它包含了构建目标文件的规则(rules), 这些规则最终由 make 命令解释执行。Makefile 文件的规则:Makefile 文件由一系列规则(rules)构成。每条规则的形式如下:<target> : <prerequisites>[tab] <commands> 上面第一行冒号前面的部分,叫做"目标"(target)...