.PHONY makefile中的伪目标

个人理解:shell

  拿clean举例,若是make完成后,本身另外定义一个名叫clean的文件,再执行make clean时,将不会执行rm命令。 命令行

  为了不出现这个问题,须要.PHONY: clean递归

 

=======================================================================================效率

所谓伪目标就是这样一个目标,它不表明一个真正的文件名,在执行make时能够指定这个目标来执行其所在规则定义的命令,有时咱们将一个伪目标成为标签。file

那么到底什么是伪目标呢?可能做为初学者还不会在意这个问题,下面咱们来看下咱们将在何时须要它。循环

首先来看下面一个例子:程序

当前目录下只有一个myls1.c,因而为了让程序让makefile来管理,写了一个以下的简单的makefile。并行

执行:makefile

你们会发现,真的能够利用这个makefile管理当前的工程,也能如期按照咱们的要求生成执行文件myls。di

执行make clean,这样就能够删除可执行程序。

接着我作了个手脚,在当前目录下创建一个叫clean的文件,那么这样执行的效果是如何?

那么这个时候为何又不能执行了?在个人makefile中其实并无修改任何东西,为何这个时候已经能管理工程的makefile又不能来管理文件了。

那要解决这个问题就是添加两行,修改后的makefile以下:

再次返回执行:

这样就解决了问题,那具体的缘由是什么?

在makefile中咱们使用伪目标就能够解决上述的问题,那为何要使用伪目标,一种就是如例题,为了不在makefile中定义的只执行命令的目标和工做目录下的实际文件出现名字冲突,另外一种是提交执行makefile时的效率。

第一种状况:

若是咱们须要书写这样的一个规则:规则所定义的命令不是去建立目标文件,而是经过make命令行明确指定它来执行一些特色的命令,就像例题中的clean。当文件夹中没有clean这个文件的时候,咱们输入“make clean”能按照初衷执行,可是一旦文件夹中出现clean文件,咱们再次输入“make clean”,因为这个规则没有任何依赖文件,因此目标被认为是最新的而不去执行规则所定义的命令。因此rm命令不会被执行。为了解决问题,咱们将目标clean定义成伪目标。

也就是添加:

.PHONY:clean

那么目录中不管是否有clean文件,只要输入“make clean”就能执行rm命令了。

当一个目标被声明为伪目标后,make在执行规则时不会去试图去查找隐含规则来建立它。这样就提升了make的执行效率,也不用担忧因为目标和文件名重名了。

第二种状况:

伪目标的另外一种使用场合时在make的并行和递归执行过程当中。

给了例子:

SUBDIRS=foo bar baz
        Subdirs:
                for dir in $(SUBDIRS)
                do
                $(MAKE) –C $$dir
                done

若是这样写,会出现几个问题:

一、 当子目录执行make出现错误,make不会退出;

二、 使用这种shell的循环方式时,没有用到make对目录的并行处理功能。

有了伪目标就能够解决上面的两个问题。

SUBDIRS=foo bar baz
        .PHONY:subdirs $(SUBDIRS)
        subdirs: $(SUBDIRS)
        $(SUBDIRS):
                $(MAKE) –C $@

通常状况下,一个伪目标不做为另外一个目标的依赖。当一个伪目标没有做为任何目标的依赖时,咱们只能经过make命令来明确指定它为make的终极目标,来执行它所在规则所定义的命令。

还有一个特别的伪目标——all,若是咱们在一个目录下建立多个可执行程序,咱们能够将全部程序的重建规则在一个makefile中描述。

all: p1 p2 p3        p1:p1.c        p2:p2.c        p3:p3.c

相关文章
相关标签/搜索