Makefile
目录
Makefile
Makefile格式
Makefile函数:foreach和wildcard
$(foreach var,list,text)
$(wildcard pattern)
完善Makefile
Makefile
在Linux中使用make工具来编译程序(特别是大程序),而make工具所执行的动作依赖于Makefile文件。
make命令根据文件更新的时间戳来决定哪些文件需要重新编译,这使得可以避免编译已经编译过的、没有变化的程序,可以大大提高编译效率。
注意:要想完整地了解Makefile的规则,请参考《GNU Make使用手册》。
Makefile格式
一个简单的Makefile文件包含一系列的规则,格式如下:
目标:依赖
<tab>命令
目标通常是要生成的文件名称,可以是可执行文件或OBJ文件,也可以是一个执行的动作名称(比如clean)。
依赖是用来产生目标的材料(比如源文件),一个目标经常有几个依赖。
命令是生成目标时所执行的动作。一个规则可以含有几个命令,每个命令占一行。
注意:每个命令行前面必须是一个Tab字符。
命令被执行的条件:依赖文件比目标文件新 或 目标文件还没生成。
通常,如果一个依赖发生了变化,就需要规则调用命令以更新或创建目标。但是并非所有的目标都有依赖,例如目标clean的作用只是清除文件,并没有依赖。
Makefile函数:foreach和wildcard
$(foreach var,list,text)
对list的每一个元素,取出来赋值给var,然后把var改为text所描述的形式。如:
objs := a.o b.o
dep_files := $(foreach f, $(objs), .$(f).d)
最终dep_files := a.o.d b.o.d
$(wildcard pattern)
pattern所列出的文件是否存在,把存在的文件都列出来。如:
src_files := $(wildcard *.c)
最终src_files为当前目录下的所有.c文件。
完善Makefile
第一种。简单,但效率低(统一编译)。
test : main.c sub.c sub.hgcc -o test main.c sub.c
第二种。效率高(没改动不编译),但相似规则重复啰嗦,不支持检测头文件。
test : main.o sub.ogcc -o test main.o sub.omain.o : main.cgcc -c -o main.o main.csub.o : sub.cgcc -c -o sub.o sub.cclean:rm *.o test -f
第三种。效率高(没改动不编译,相对简洁),但不支持检测头文件。
test : main.o sub.ogcc -o test main.o sub.o%.o : %.cgcc -c -o $@ $<clean:rm *.o test -f
第四种。效率高(没改动不编译,相对简洁),支持检测头文件(但是需要手动添加头文件规则)。
test : main.o sub.ogcc -o test main.o sub.o%.o : %.cgcc -c -o $@ $<sub.o : sub.hclean:rm *.o test -f
第五种。效率高(没改动不编译,相对简洁),支持自动检测头文件。
objs := main.o sub.otest : $(objs)gcc -o test $^# 需要判断是否存在依赖文件
# .main.o.d .sub.o.d
dep_files := $(foreach f,$(objs), .$(f).d)
dep_files := $(wildcard $(dep_files))# 把依赖文件包含进来
ifneq ($(dep_files),)include $(dep_files)
endif%.o : %.cgcc -Wp,-MD,.$@.d -c -o $@ $<clean:rm *.o test -fdistclean:rm $(dep_files) *.o test -f
详细Makefile内容可以阅读博主的另一篇文章:
Makefile