edit : main.o kbd.o command.o dislplay,o \
insert.o search.o files.o utils.o
cc -o edit main.o kbd.o command.o dislplay,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 insert.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 buffer.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中的变量
edit : main.o kbd.o command.o dislplay,o insert.o search.o files.o utils.o
cc -o edit main.o kbd.o command.o dislplay,o insert.o search.o files.o utils.o
首先说明一下edit的规则:
(.o)库文件在这里写了两遍,当然完整写的话,clean中也需要再写一遍。当我们的工程中引入了一个新的(.o)文件时,我们需要在这两个地方加入他们,但是随着代码的复杂度增加,这中工作可能就会变得繁琐,我们可能也会因此忘记。为此引入了Make file中的变量(字符串),我们可以将它相近的理解为C语言中的宏。
比如我们可以声明一个objects变量或者是OBJ ,我们就可以在Make file文件的开头定义:
objects = main.o kbd.o command.o \
insert.o search.o files.o utils.o
然后我们就能够在makefile中以 “$(objects)”来使用这个变量了,下面是改版后的样子
objects = main.o kbd.o command.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
cc -c kbd.c
command.o :command.c defs.h command.h
cc -c insert.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 buffer.h
cc -c utils.c
clean:
rm edit $(objects)
这样当我们在新加入库文件,我们只需要在变量中添加就可以了。
二、Make的自动推导
GUN的make功能时很强大的,它能够自动的推导文件以及文件以来后面的命令,所以我们没必要在每一个(,o)文件后面都写上相同的命令。它能够自动推到命令。
具体是怎样操作呢,当make发现一个(.o)文件后,他会自动把(,c)文件加到依赖关系中。例如 make 找到一个 a.o的文件,那么 a.c文件就是a.o的依赖文件,并且cc -c a,c 也会被他自动补全。所以上面代码我们还可以省略:
objects = main.o kbd.o command.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 buffer.h
.PHONY:clean
clean:
rm edit $(objects)
上面的(.PHONY)表示clean是一个伪目标文件。这个后面再说。
三、Makefile的风格
还有一种更加简约的风格,但是不是那么容易理解,我把它贴出来,大家自己理解就行
objects = main.o kbd.o command.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)
哎!像我这种比较笨的,就不适合写这样的,费脑子。
四、清空目标文件的规则
每一个makefile文件中都要写一个清空目标文件的规则,这样能够保证我们文件的整洁,
下面有两种写法
写法一:
clean:
rm edit $(objects)
写法二:
.PHONY:clean
clean:
-rm edit $(objects)
事实上写法二是比较稳妥的写法。
(.PHONY)之前提到过,他会标注clean是一个伪目标。
在rm之前加一个“-”是有啥用呢他会在当rm某些文件碰到问题时不去理会,继续执行后面的事情,
至于为啥么吧clean放在文件最后,这个其实放哪里也可以,大家习惯这样而已。