节选自:《Linux C编程一站式学习》,作者:宋劲杉
Makefile出现的原因最主要是减少每次编译时的工作量,避免由于编译命令的输入错误而导致的bug;同时,make的时候可以检测是否有源文件被修改过,如果有则对这些更改过的文件重新编译,如果没有则不更新。
下面是一个完整的Makefile文件:
main : main.o stack.o maze.o
gcc main.o stack.o maze.o -o main
main.o : main.c main.h stack.h maze.h
gcc -c main.c
stack.o : stack.c stack.h main.h
gcc -c stack.c
maze.o : maze.c maze.h main.h
gcc -c maze.h
clean :
@echo "cleanning project"
-rm main *.o
@echo "clean completed"
如果当前目录下有Makefile文件,则输入make就会自动读取这个Makefile文件,完成相应地编译步骤。Makefile文件由规则(Rule)组成,每条规则的格式如下:
target ... : prerequisites ...
command1
command2
...
例如上面的例子就是由4组规则组成的。
在第一组规则中,main是目标(target), main.o stack.o maze.o是条件(prerequisites).
如果想要更新target,则必须先更新它的所有prerequisites;同时,如果任意prerequisite有更新,则这个target必须更新。target的“更新”在这的意思就是将其下方的所有command执行一遍。每一个command均以tab开头。对于Makefile中每个以tab开头的命令,make都会创建一个shell进程去执行它。
对于每一个Makefile文件,第一个rule的target都是default target,如果这个default target更新了,则make结束,其余所有都是为这个default target服务的。第一次编译时,需要生成main文件,需要更新,但这需要先更新其所有的prerequisites,所有会进一步以这几个prerequisites为targets去检测是否需要更新,若需更新,则进行更新操作。直到最后main文件成功更新,结束。
make检测文件是否被修改过的原理是:检测target与其prerequisites的最近修改时间,如果某一prerequisite的最近修改时间比target晚,则说明target需要更新。
最后,Makefile文件都会有一个clean规则,用于清除编译产生的二进制文件,仅保留源文件。使用命令make clean 来执行clean规则。这里,make clean的意思就是从clean这条rule开始执行编译,这样就不会从第一条rule开始。
@意味着,不显示其后命令本身,只显示命令的结果。echo 是输出其后的信息
rm命令是remove,-可以忽略错误,继续执行后续命令,防止由于rm失败,而导致的make终止运行的情况。如果没有-,当rm的目标文件不存在时,rm命令是失败的,会出错,则make直接终止,不会去执行接下来的第二个echo命令;如果有-,则虽然rm失败了,但这个错误会被忽略,继续执行接下来的命令。