Make 在我们做linux 开发中是必不可少的一部分,它在我们编写大型项目工程文件中起到非常大的作用。
Make工程管理器也就是个“自动编译管理器”,这里的“自动”是指它能够根据文件时间戳自动发现更新过的文件而减少编译的工作量,同时,它通过读入Makefile文件的内容来执行大量的编译工作。Make将只编译改动的代码文件,而不用完全编译。
而Makefile是Make读入的唯一配置文件,makefile关系到了整个工程的编译规则。一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。
下面我们通过两个个实例来学习makefile的编写:
一、Makefile编写的基本规则
我在文件夹下有如下文件
fs@ubuntu:~/qiang/makefile/example1$ ls
buffer.h defs.h files.c main.c makefile utils.c
fs@ubuntu:~/qiang/makefile/example1$
这里的代码就不展示了,我说一下文件包含关系:files.c需要buffer.h及defs.h , main.c需要defs.h ,utils.c需要defs.h。
我把makefile文件内容展示出来:
OBJS = main.o files.o utils.o
CC = gcc
CFLAGS = -c
Test:$(OBJS)
$(CC) -o Test $(OBJS)
main.o:main.c defs.h
$(CC) $(CFLAGS) main.c
files.o:files.c buffer.h defs.h
$(CC) $(CFLAGS) files.c
utils.o:utils.c defs.h
$(CC) $(CFLAGS) utils.c
.PHONY:clean
clean:
rm -rf *.o Test
@echo "Clean done!"
我们开始学习makefile编写规范:Makefile的根本任务是根据规则生成目标文件。
1、规则
一条规则包含三个:目标文件,目标文件依赖的文件,更新(或生成)目标文件的命令。
规则:
<目标文件>:<依赖文件>
<更新目标的命令>
注意:命令行前面必须是一个“TAB键”,否则会编译错误!
Example
hello.o: hello.c hello.h
gcc -c hello.c -o hello.o
目标hello.o 依赖于hello.c,hello.h. 生成hello.o的命令时是“gcc -c hello.c -o hello.o”
2、终极目标
makefile并不会更新所有规则中的目标,它只会更新终极目标以及终极目标依赖的目标。
默认情况下makefile的第一个目标是终极目标,而且大家约定俗成的总是将all作为第一个目标。环境变量MAKECMDGOALS记录着终极目标。
Test:$(OBJS)
$(CC) -o Test $(OBJS)
我们这里就是终极目标
注意:终极目标必须放在第一个,其余的可以随便放!
3、多规则目标
Makefile中,一个文件可以作为多个规则的目标,这种情形就是多规则目标。
多规则目标下,以这个文件为目标的所有规则的依赖文件将会被合并成此一个依赖文件列表,但是命令不会合并,而且实际上,这多个规则中至多只能有一个规则定义了更新命令。
all:hello.o
all:hello.h
等价于 all: hello.o hello.h
main.o:main.c defs.h
我们这里就是多规则目标;
4、伪目标
一般情况下目标文件是一个具体的文件,但有时候我们只需要一