GNU Make 简介( 七 )



如果编写一个规则,并不产生目标文件,则其命令在每次make 该目标时都执行 。

例如:

clean:
rm *.o temp

因为"rm"命令并不产生"clean"文件,则每次执行"make clean"的时候,该命令都会执行 。如果目录中出现了"clean"文件,则规则失效了:没有依赖文件,文件"clean"始终是最新的,命令永远不会执行;为避免这个问题,可使用".PHONY"指明该目标 。如:

.PHONY : clean

这样执行"make clean"会无视"clean"文件存在与否 。

已知phony 目标并非是由其它文件生成的实际文件,make 会跳过隐含规则搜索 。这就是声明phony 目标会改善性能的原因,即使你并不担心实际文件存在与否 。

完整的例子如下:

.PHONY : clean
clean :
rm *.o temp

phony 目标不应是真正目标文件的依赖 。如果这样,每次make 在更新此文件时,命令都会执行 。只要phony 目标不是真正目标的依赖,规则的命令只有在指定此目标时才执行 。

phony 目标可以有依赖关系 。当一个目录中有多个程序,将其放在一个makefile 中会更方便 。因为缺省目标是makefile 中的第一个目标,通常将这个phony 目标叫做"all",其依赖文件为各个程序:

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

这样,使用"make"将可以将三个程序都生成了 。d
当一个phony 目标是另一个的依赖,其作用相当于子程序,例如:

.PHONY: cleanall cleanobj cleandiff
cleanall : cleanobj cleandiff
rm program
cleanobj :
rm *.o
cleandiff :
rm *.diff

3.6 FORCE 目标

当规则没有依赖关系也没有命令,而且其目标不是存在的文件名,make 认为此规则运行时这个目标总是被更新 。这意味着如果规则依赖于此目标,其命令总是被执行 。

clean: FORCE
rm $(objects)
FORCE:

例中目标"FORCE"满足这种特殊条件,这样依赖于它的目标"clean"被强制执行其命令 。名字"FORCE"没有特殊含义,只不过通常这样用而已 。这种方式使用"FORCE"和".PHONY : clean"效果相同 。使用".PHONY"更加明确高效,但不是所有的"make"都支持;这样许多makefile 中使用了"FORCE" 。

3.7 空目标

空目标(empty target)是phony 目标的变种:用来执行显式请求的一个动作 。和phony 目标不同的是:这个目标文件可以真实存在,但文件的内容无关紧要,通常是空的 。空目标文件的目的是利用其最后修改时间来记录命令最近一次执行的时间,这是通过使用"touch"命令更新目标文件来达到的 。

print: foo.c bar.c
lpr -p $?
touch print

利用这条规则,执行"make print"时如果自上次"make print"之后任一文件改变了,"lpr"命令会执行 。自动变量"$?"是为了只打印出那些变化了的文件 。

3.8 内建的特殊目标

某些名字作为目标存在时有特殊含义 。

推荐阅读