1.Makefile简介
Makefile文件中写的是:工程编译的规则以及编译顺序。
只需要每次执行make命令,make就会自动在当前目录下搜索Makefile或makefile。
然后按照makefile中指定的规则编译整个工程。
注意:如果文件不修改,则不需要重新编译!!!
例如:
//makefile
main:main.o
gcc main.o -o main
main.o:
gcc -c main.c
(从“main:”进入,先找到main.o执行gcc -c main.c,然后再回到main执行gcc main.o -o main)
1.1主要的五部分
- 显示规则
- 隐晦规则
- 变量定义
- 文件指示
- 注释
Makefile基本格式:
target ... : condition ...
command
...
...
- target是目标文件,即生成的目标文件或可执行文件的名称
- condition为生成target所需要的文件或目标文件
- command是需要执行的全部命令 MakeFile中的命令必须以TAB键开头
- 显示规则 :显式规则说明了,如何生成一个或多的的目标文件。这是由 Makefile 的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。
- 隐晦规则:由于我们的 make 有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略地书写 Makefile,这是由 make 所支持的。
- 变量定义:在 Makefile 中我们要定义一系列的变量,变量一般都是字符串,这个有点你 C 语言中的宏,当 Makefile 被执行时,其中的变量都会被扩展到相应的引用位置上。
- 文件指示:Makefile中的目标文件编译依赖其他的头文件;或是依赖其他makefile
- 注释:Makefile 中只有行注释,和 UNIX 的 Shell 脚本一样,其注释是用“#”字符,这个就像 C/C++中的“//”一样。如果你要在你的 Makefile 中使用“#”字符,可以用反斜框进行转义,如:“\#”。
还值得一提的是,在 Makefile 中的命令,必须要以[Tab]键开始
1.2 GNU make 的工作流程
- 读入文件中的主Makefile
- 读入被引入的其他Makefile文件
- 初始化文件的变量
- 推倒隐晦规则,并分析文件当中其他的规则
- 为所有的目标文件创建依赖关系链
- 根据依赖关系,确定哪些目标要重新生成
- 执行生成命令
2.Makefile基本语法
2.1Makefile规则
2.1.1 规则语法
语法有以下两种
target ... : condition ...
command
...
...
或
target ... : condition ... ;command
command
...
...
target也就是一个目标文件,可以使Object File,也可以是可执行文件。还可以是一个标签,即伪目标
2.1.2 规则中的通配符
* 标识任意一个或多个字符
? 表示任意一个字符
~ 表示用户的home目录
输入' \ '可在下一行继续输入
2.1.3 路径搜索
当Makefile文件中依赖的文件有不在当前路径下时则要标明文件路径。
所以要在Makefile文件中标明文件的路径,Makefile中有一个特殊的标量VPATH或vpath就是完成这个功能的。
指定了路径之后,如果有文件在当前目录没有找到时,就会到VPATH指定的路径下去找。
- VPATH和vpath的使用方法:
VPATH = ./src : ./sum : ./public : ...
//大写的VPATH可以直接赋值要找的路径,每个路径之间用 : 号隔开
vpath sum.c ./sum
vpath main.c ./public
vpath %.h ./public
vpath %.c ./max : ./sum : ./sub : ./public
//使用vpath可以对指定文件或指定的类标明路径
vpath %.c
//清楚符合%.c文件的搜索路径
vpath
//清楚所有设置的搜索路径
2.2Makefile 中的变量
2.2.1 变量定义
OBJS = sum.o sub.o max.o min.o main.o
OBJS2 = $(OBJS) program.o
//目标OBJS包含了sum.o ... main.o
//目标OBJS2包含了OBJS的所有内容以及 program.o
测试:
OBJS = main.o max.o min.o\
sub.o
objects = $(OBJS) + sum.o
PATH = ./main : ./max : ./min : ./sub : ./sum
edit: $(objects)
gcc -o edit $(objects)
# bash中执行make命令
$ make
edit main.o max.o min.o sub.o sum.o
好处:如果有新的 .o 文件加入,我们只需简单地修改一下 objects 变量就可以了。
2.2.2 目标变量
objects = main.o command.o display.o \
insert.o search.o
edit : $(objects)
gcc -o edit $(objects)
main.o : main.c defs.h
cc -c main.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
clean :
rm edit $(objects)//edit就是一个目标变量,即最后生成的目标文件或可执行文件名就是edit
3. Makefile的自动推倒
GNU 的 make 很强大,它可以自动推导文件以及文件依赖关系后面的命令,于是我们就没必要去在每一个[.o]文件后都写上类似的命令,因为,我们的 make 会自动识别,并自己推导命令。
只要 make 看到一个[.o]文件,它就会自动的把[.c]文件加在依赖关系中,如果 make 找到一个 whatever.o,那么 whatever.c,就会是 whatever.o 的依赖文件。并且 cc -c whatever.c 也会被推导出来,于是,我们的 makefile 再也不用写得这么复杂。我们的是新的 makefile 又出炉了。
objects = main.o command.o display.o \
insert.o search.o
edit : $(objects)
cc -o edit $(objects)
main.o : defs.h
command.o : defs.h command.h
display.o : defs.h buffer.h
insert.o : defs.h buffer.h
search.o : defs.h buffer.h
.PHONY : clean
clean :
rm edit $(objects)
这种方法就是 make 的“隐晦规则”。上面文件内容中,“.PHONY”表示,clean 是个伪目标文件。
执行clean命令,所生成的文件就会全部删除。
4. 清空目标文件的规则
每个 Makefile 中都应该写一个清空目标文件(.o 和执行文件)的规则,这不仅便于重编译,也很利于保持文件的清洁。
例如:
clean:
rm edit $(objects)
更为完全的做法是
.PHONY : clean
clean :
-rm edit $(objects)
.PHONY 意思表示 clean 是一个“伪目标”,。而在 rm 命令前面加了一个小减号的意思就是,也许某些文件出现问题,但不要管,继续做后面的事。当然,clean 的规则不要放在文件的开头,不然,这就会变成 make 的默认目标,
记住——clean从来都是放在文件的最后
暂时就先整理了这么多,初学者知识能力有限,还望大佬们指教,谢谢!