4.编写规则
Phony Targets¶
一个伪目标不是一个真正的文件名,只是一个当你明确的运行make请求时会被执行的recipe名字。有两个原因使用伪目标:
- 避免同名文件冲突
- 提升性能
解决的问题:
clean:
rm *.o temp
这种写法在没有文件名冲突的时候可以通过make clean
正常执行。但是如果在这个目录下有一个同名的文件clean
,clean
总是会被考虑是最新的文件,它的recipe不会执行。
添加一个伪目标即可解决这个问题:
.PHONY: clean
clean:
rm *.o temp
与make的递归调用结合使用:
SUBDIRS = foo bar baz
subdirs:
for dir in $(SUBDIRS); do \
$(MAKE) -C $$dir; \
done
这种写法的问题:任何在sub-make中的错误都会被忽视;不能并行构建目标。
改进后的写法:
SUBDIRS = foo bar baz
.PHONY: subdirs $(SUBDIRS)
subdirs: $(SUBDIRS)
$(SUBDIRS):
$(MAKE) -C $@
foo: baz
最后一句声明了baz完成之后才能构建foo。
对于伪目标将跳过隐含规则的搜索。
伪目标不应该成为一个真实的目标文件的prerequisites,负责每次make更新文件都会执行伪目标的recipe。
伪目标也可以有prerequisites:
all : prog1 prog2 prog3
.PHONY : all
prog1 : prog1.o utils.o
cc -o prog1 prog1.o utils.o
prog2 : prog2.o
cc -o prog2 prog2.o
prog3 : prog3.o sort.o utils.o
cc -o prog3 prog3.o sort.o utils.o
一个伪目标的prerequisites是另一个伪目标时,表现为另一个的子程序:
.PHONY: cleanall cleanobj cleandiff
cleanall : cleanobj cleandiff
rm program
cleanobj :
rm *.o
cleandiff :
rm *.diff
执行顺序:rm *.o
-> rm *.diff
-> rm program