一个工程中的源文件可能很多的情况下,按其类型、功能、模块分别放到若干个目录中,makefile定义了一系列的规则,用以指定那些需要先编译,那些需要后编译,那些需要重新编译,和一些更复杂的操作。,makefile的好处就是自动化编译,一点写好,只需要make命令,整个工程就会自动编译,提高了项目的管理能力和软件的开发效率。
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,如果在目录中输入make,就可以生成edit可执行文件。如果想要删除可执行文件或者是中间目标文件直接make clean就行了。
依赖关系:
有上述例子可以看出,目标文件包含两种:执行文件(edit)和中间目标文件(*.obj),依赖文件(prerequisites)就是冒号后面的那些.c和.h文件。每一个.o 文件都有一组依赖文件,这些.o的文件又是执行文件edit的依赖文件。其实依赖关系就是说明了目标文件是有那些文件申城的,换言之就是目标文件是哪些文件更新的。
定义好依赖关系后,后面的一行就定义了如何生成目标文件的操作系统命令,一定要以tab键开头。记住make并不管命令式怎么工作的,它只关心定义的命令。Make会比较目标文件和依赖文件的修改日期,如果依赖文件的日期要比目标文件的日期更新,或者是目标文件不存在的话,make就会执行后续定义的命令。
Make是如何工作的
1. 查找Makefile或makefile文件
2. 查找第一个目标文件,并将这个文件作为最终的目标文件
3. 查找目标文件是否存在,或者是当前目标文件依赖的.o 文件的文件修改时间要比当前目标文件新,则执行后面定义的命令来生成edit这个文件
4. 如果edit依赖的.o文件也存在,那么make会在当前文件中查找目标文件为.o文件的依赖性,如果找到则根据哪一个规则生成.o文件。
5. 根据c文件和.h文件,make生成.o文件,然后生成最终目标文件。
Make会一层已成的查找文件的依赖关系,知道最终编译出第一个目标文件。在查找过程中,如果出现错误,比如被依赖的文件找不到,那么make就会直接退出,并报错,但是对于所定义的命令的错误,或者是编译不成功,make会置之不理。但是当查找到一个文件的依赖关系的时候,并且执行依赖关系之后命令,冒号后面的依赖文件如果还是不存在,那么make就会退出。
由上可知,想clean这种没有被第一个目标文件直接或间接关联,那么他后面定义的命令将不会自动执行。如果想显式执行要求make执行clean之后的命令,“输入make clean”就行了,用以清除所有的目标文件,便于重新编译。
1. 另外makefile中也可以添加一些宏定义(变量)
2. gnu make可以实现自动推倒