前面一篇介绍的makefile只是较为简单普通的写法,还是有很多改进的余地的。
例如依赖不一定要写在一条规则中,也可以拆开写,例如:
main.o: main.h stack.h maze.h main.o: main.c gcc -c main.c这么一来上面的例子可以该写成下面的形式:
main:main.o stack.o maze.o gcc main.o stack.o maze.p -o main main.o: main.h stack.h maze.h stack.o: stack.h main.h maze.o: maze.h main.h main.o: main.c gcc -c main.c stack.o: stack.c gcc -c stack.c maze.o: maze.c gcc -c stack.c clean: -rm main *.o .PHONY: clean
这样,提出去的三条规则就可以删去,写成下面的形式:
main: main.o stack.o maze.o gcc main.o stack.o maze.o -o main main.o: main.h stack.h maze.h stack.o: stack.h main.h maze.o: maze.h main.h clean: -rm main *.o .PHONY: clean
隐式规则中:#表示注释,这和shell脚本中是一样的, = 表示赋值, $则可以用来展开一个变量,例如下面这里的隐式规则:
# default OUTPUT_OPTION = -o $@ # default CC = cc # default COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c %.o: %.c # commands to execute (built-in): $(COMPILE.c) $(OUTPUT_OPTION) $<这里的CC在$符号的作用下,会被展开成cc,cc 是一个符号链接,通常指向 gcc
上面的CFLAGS以及CPPFLAGS, TARGET_ARCH也都是这样的
按照上面这样展开 那么COMPILE.c展开就是cc -c,而OUTPUT_OPTION展开是 -o $@,所以按照整个式子追后展开就是:
$@和$< 是两个特殊的变量,$@ 的取值为规则中的目标, $< 的取值为规则中的第一个条件
%.o:%.c 是一种特殊的规则,称为模式规则(Pattern Rule),这里的.o .o非别就可以替换成为main.o main.c, 那么makefile会隐式的推断出下面这条规则:
main.o : main.c cc -c -o main.o main.c其他的两条也是像这样的来进行推断。
都是以目标为中心,一个目标依赖于若干条件,现在换个角度,以条件为中
心,Makefile还可以这么写:
cc -c -o $@ $<
main: main.o stack.o maze.o gcc main.o stack.o maze.o -o main main.o stack.o maze.o: main.h main.o maze.o: maze.h main.o stack.o: stack.h clean: -rm main *.o .PHONY: clean