Makefile ------ .PHONY的作用,伪目标

试想想这种情形,如果一个目标名和当前目录下的某个文件名相同, make 的时候会出现什么情形?

先来尝试一下,将生成的 a.out 文件复制为新文件 all,然后再 make,操作过程和结果如下图所示

可以看到, make 提示“all" 是最新的。根据前面介绍的 make 处理流程,“是最新的”意味着, all 目标对应的规则永远不会被执行,哪怕实际需要编译的文件已经修改过,也不会被重新编译。 

 

如果在编写 Makefile 的时候,一不小心出现这样的问题,对程序是致命的。针对这个问题, Makefile 有一个解决办法,引入了一个新的目标——伪目标。伪目标是一个标签,这个目标只执行命令,不创建目标,还能避免目标与工作目录下的实际文件名冲突。

伪目标的写法如下:

.PHONY:标签

 

 对于前面这个示例,将 Makefile 文件稍微修改一下,在末尾增加一行:

.PHONY:all

 

 

将 all 设置为伪目标后,尽管在当前目录下有同名的 all 文件,但是在终端输入 make 命令,可以看到, all 的命令被正确执行,如下图所示。

 

 

在实际应用中,通常会有一个 clean 目标,这个目标几乎都会被设置为伪目标,用于清除编译产生的中间文件和可执行文件。在进行源码打包或者发布的时候,先通过 make clean 命令清除, 可得到干净的代码文件

如果为 hello.c 的 Makefile 增加一个伪目标 clean, 可以这么写:

.PHONY:clean
(TAB)-rm -v a.out

 clean 对应的命令是-rm -v a.out。就是普通的删除命令, 加-v 参数是显示删除列表。完整的 Makefile 文件如下图所示

 

如果一个 Makefile 文件有多个伪目标,可以分多行单独声明,也可以将多个伪目标一并声明,各伪目标之间用空格隔开

clean 伪目标的命令为“-rm”,在 rm 命令前加了“-”,含义是如果这条命令执行失败,make 将忽略这个错误,继续往下执行;如果不加“-”,则 make 会停止。 如果一个工程连续进行两次 make clean 操作, 那么在进行第二次 clean 的时候,由于相关文件已经不存在了,所以 make 会报错。但若加了“-”, clean 出错但被忽略(参考图 10.29(a)), 而不加“-”则不忽略(参考图 10.29(b))。

 

-”的含义不仅仅对 rm 命令有效,对 Makefile 中的所有命令都有效。等效于“make -i”命令。

 

posted @ 2018-05-24 18:09  流水灯  阅读(1540)  评论(0编辑  收藏  举报