rxhf@rhf2s001:~/testdir0 $ vim Makefile 1 #源文件和头文件路径 2 VPATH = ./cal 3 #源文件名称 4 Sources =cal.c main.c 5 6 #取目标文件名 7 Targets = $(Sources:%.c=%.o) 8 # 指定编译器对头文件的搜索路径 9 IncludePath = $(patsubst %,-I%,$(subst :, ,$(VPATH))) 10 11 all : $(Targets) 12 gcc $^ -o all 13 -mkdir ./Linking; mv *.o *.d ./Linking 14 @echo "makefile文件执行完毕" 15 %.o : %.c 16 gcc -c $< $(IncludePath) -o $@ 17 #自动生成文件依赖性 18 %.d : %.c 19 @set -e; rm -f $@; $(CC) -MM $< > $@.$$$$;\ 20 sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@;\ 21 rm -f $@.$$$$ 22 -include $(Sources:.c=.d) 23 .PHONY : clean 24 clean : 25 -rm all 26 -rm -f *.d* 27 -rm -rf ./Linking
代码解析如下:
第1、2行:VPATH是Makefile的特殊变量,指定了文件的搜索路径,表示make工具如果找不到规则中的目标文件或依赖文件,可以在VPATH变量定义 的目录查找。
第3、4行:定义了一个Makefile变量Srouces,指定了源代码文件的名字,如:Sources =cal.c main.c
第6、7行:定义了一个变量Targets,表示目标文件的名字,Targets = $(Sources:%.c=%.o),其中$(Sources:%.c=%.o)表示用.o替换Sources变量中以.c结尾的字符串,%字符在Makefile中表示匹配任意个非空字符串,类似shell的通配符
第8、9行:定义了一个变量IncludePath,表示编译器对头文件的搜索路径。$(patsubst %,-I%,$(subst :, ,$(VPATH)))语句可以把<目录>转换成 -I<目录>,如本例中,转换成 -I./cal(大写的I)
第11-14行:定义了Makefile文件的终极规则,这也是本Makefile文件的第一条规则,目标为all文件,依赖文件为$(Targets)变量,其下的命令表示编译目标文件生成可执行文件,在当前目录创建文件夹./Linking,并把所有的.o文件和.d文件移动到该文件夹下
第15、16行:定义了目标为.o文件的模式规则
第17、21行:定义了自动生成文件依赖性的模式规则(也是.d文件的生成规则)
第22 行:用include包含了所有的.d文件,如果.d文件不存在,则用.d文件的生成规则生成
第23-27行:用.PHONY声明一个伪目标clean,表示清除所有的中间文件(.o文件和.d文件)和all可执行文件,make工具不会自动执行本条规则,我们只能在shell命令行下输入make clean来显式执行。