Makefile
概述:源文件首先会生成中间目标文件,再由中间目标文件生成可执行文件。
中间目标文件:windows是obj文件,unix是.o文件(Object File)
Makefile介绍
编译规则
(1) 如果工程没有编译过,那么所有C文件都要被编译和链接。
(2) 如果工程里有几个C文件被修改,那么只编译被修改的C文件,并链接。
(3) 如果工程的头文件被改变了,那么需要编译引用了这几个头文件的C文件,并连接。
一、Makefile的规则
target ... : prerequisites...
command
...
...
target :目标文件,可以是中间目标文件,也可以是可执行文件,还可以是label
prerequisites:生成target所需要的文件或是目标
command:是make需要执行的命令。(任意的shell命令)
二、示例
假设一个工程有三个头文件(.h),8个C文件(.c)文件
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
(1) 上面的反斜杠“\”是换行符,为了增加可读性。
(2) 把上面文件内容保存在“Makefile”或者“makefile”中,就可以在该目录中使用make命令生成可执行文件,使用make clean命令可以直接删除中间文件和可执行文件。
(3)
target (目标文件):edit 和 (*).o
prerequisites(依赖文件):*.c 和 *.h 。每一个 *.o都有一组依赖文件,而每一个 *.o文件又是edit的依赖文件
(4)当定义好依赖关系之后,接下来的一行文件为生成目标文件的操作系统命令,并且要以一个Tab键位开头。
三、make是如何工作的
在我们输入make命令后
step[1]:make会在当前目录中找到“Makefile”或者“makefile”文件
step[2]:如果找到,他会找到第一个目标文件。如例子中的edit,并且会把他当成最终的目标文件。
step[3]:如果edit不存在,或者edit所依赖的.o文件修改时间要比edit新,那么就会执行后面的定义的命令行生成新的edit
step[4]:如果edit所依赖的.o文件也存在,那么就会根据上面的规则生成.o文件
step[5]:根据写好的.c和.h文件生成.o文件,然后再生成edit文件
四、makefile中使用变量
为了易于维护,可以再makefile中使用变量来代替依赖文件,类似C语言中的宏定义
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
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 $(objects)
如果有新的.o文件加入,我们只需要再变量中加入就可以了
五、让makefile自动推导
GNU的make命令还可以自动推导文件以及文件依赖关系后面的命令,所以我们就可以不用再每个文件后面都加入相类似的命令,可以让make 自动识别并推导命令。
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
main.o : defs.h
kbd.o : defs.h command.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
files.o : defs.h buffer.h command.h
utils.o : defs.h
.PHONY : clean
clean :
rm edit $(objects)
六、另类风格的makefile
上面的方法中可以看到有很多相同的.h文件,可以把他们合并到一起
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
$(objects) : defs.h
kbd.o command.o files.o : command.h
display.o insert.o search.o files.o : buffer.h
.PHONY : clean
clean :
rm edit $(objects)
七、清空目标文件的规则
clean一般都是放在makefile文件的结尾。
#一般的风格都是:
clean:
rm edit $(objects)
#更为稳健的做法是:
.PHONY : clean
clean :
-rm edit $(objects)
rm前面减号的意思就是,也许某些文件出现问题,但不要管,继续做后面的事。