Makefile的好处:
修改源文件或者头文件,只需要重新编译牵涉的文件,就可以重新生成APP
Makefile文件编写规则
目标(target)...:依赖(prerequiries)
<tab>命令(command)
目标通常是要生成的文件的名称,可以是可执行文件或OBJ文件,也是一个执行动作的名称,如“clean”。
依赖是用来产生目标的材料(比如源文件),一个目标经常有几个依赖。
命令是生成目标执行时的动作,一个规则可以含几个命令,每个命令占一行。
注意:每个命令行前面必须是一个tab字符,即命令行第一个字符是tab。这是容易出错的地方。
通常,如果一个依赖发生变化,就需要规则调用命令以更新或创建目标。但是并非所有的目标都有依赖,例如,目标“clean”的作用是清楚文件,它没有依赖。
规则一般用于解释怎样和何时重建目标。make首先调用命令处理依赖,进而才能创建或更新目标。当然,一个规则也可以用于解释怎样和何时执行一个动作,即打印提示信息。
如果“依赖文件”比“目标文件”更加新,那么执行“命令”来重新生成“目标文件”。
命令被执行的2个条件:依赖文件比目标文件新,或是目标文件还没生成。
$@--目标文件,$^--所有的依赖文件,$<--第一个依赖文件。
demo1
test:main.o sub.o
gcc -o $@ $^
%.o : %.c
gcc -c -o $@ $<
sub.o : sub.h
sub.o : sub.c
gcc -c -o $@ $<
clean:
rm test *.o -f
编译得
demo2
test:main.o sub.o
gcc -o $@ $^
%.o : %.c
gcc -c -Wp,-MD,.$@.d -o $@ $< //生成隐藏的.$@.d可依赖文件
clean:
rm test *.o -f
执行make之后会生成.main.o.d, .sub.o.d可依赖文件
通过查看这两个文件,可以发现里面存放的是没有命令的规则。
main.o依赖于main.c,依赖于这些头文件。
那么我们怎么将依赖文件包含尽量呢?先介绍Makefile的2个函数
1.
$(foreach var,list,test)
简单的说就是For each var in list,change it to text.
对list中的每个元素,取出来赋值给var,然后把var改为text所描述的形式。
objs := a.o b.o
dep_file := $(foreach f, $(objs), .$(f).d) //最终dep_file:=.a.o.d .b.o.d
/***************************************************************************/
$(wildcard pattern)
pattern所列出的文件是否存在,把存在的文件都列出来。
src_file := $(wildcard *.c) //最终src_file中列出当且目录下所有的.c文件
demo3
objs := main.o sub.o
test : $(objs)
gcc -o $@ $^
# 需要判断是否存在依赖文件
# 1.将main.0 sub.o转换成.main.o.d .sub.o.d
dep_file := $(foreach f, $(objs), .$(f).d)
# 2.判断.main.o.d .sub.o.d是否存在
dep_file := $(wildcard $(dep_file))
# 把依赖文件包含进来
ifneq ($(dep_file),)
include $(dep_file)
endif
%.o : %.c
gcc -c -Wp,-MD,.$@.d -o $@ $<
clean:
rm test *.o -f
distclean:
rm test $(dep_file) *.o -f
本人觉得demo3的作用和demo2的差不多,都是当只有.h文件发生更改时也能够进行编译,只不过是看起来更高级。
感谢观看。