make命令会自动读取当前目录下的Makefile文件,完成相应的编译步骤。
Makefile由一组规则(Rule)组成,每条规则的格式是:
target ... : prerequisites ...
command1
command2
例如:
main: main.o stack.o maze.o
gcc main.o stack.o maze.o -o main
- main是这条规则的目标(Target),main.o、stack.o和maze.o是这条规则的条件(Prerequisite)。
- 目标和条件之间的关系是:欲更新目标,必须首先更新它的所有条件。
- 所有条件中只要有一个条件被更新了,目标也必须随之被更新。
- 所谓“更新”就是执行一遍规则中的命令列表。
- 命令列表中的每条命令必须以一个Tab开头,注意不能是空格,Makefile的格式不像C语言的缩进那么随意,对于Makefile中的每个以Tab开头的命令,make会创建一个Shell进程去执行它。
通常Makefile文件末尾都会有一个clean规则,用于清除编译过程中产生的二进制文件,保留源文件:
clean:
@echo "cleanning project"
-rm main *.o
@echo "clean completed"
和前面介绍的规则不同,clean目标不依赖于任何条件,并且执行它的命令列表不会生成clean这个文件。
$ make clean
cleanning projectr
rm main *.o
clean completed
在这个例子还演示了命令前面加@和 - 字符的效果:
如果make执行的命令前面加了@字符,则不显示命令本身而只显示它的结果;
通常make执行的命令如果出错(该命令的退出状态非0)就立刻终止,不再执行后续命令,但如果命令前面加了-号,即使这条命令出错,make也会继续执行后续命令。通常rm命令和mkdir命令前面要加-号,因为rm要删除的文件可能不存在,mkdir要创建的目录可能已存在,这两个命令都有可能出错,但这种错误是应该忽略的。
例如上面已经执行过一遍make clean,再执行一遍就没有文件可删了,这时rm会报错,但make忽略这一错误,继续执行后面的echo命令:
cleanning projectrm
rm main *.o
rm: cannot remove `main': No such file or directory
rm: cannot remove `*.o': No such file or directory
make: [clean] Error 1 (ignored)
clean completed
- 如果在make的命令行中指定一个目标(例如clean),则更新这个目标。
- 如果不指定目标,则更新Makefile中第一条规则的目标(缺省目标)。