【转】makefile的双冒号规则

 在编译一个软件包时看见下面rules文件中出现“binary-predeb/gir1.0-unique-1.0::”,对这里的双冒号很是不解,经查阅资料,才明白一点儿。

#!/usr/bin/make -f


include /usr/share/cdbs/1/class/autotools.mk
include /usr/share/cdbs/1/rules/debhelper.mk
include /usr/share/cdbs/1/rules/simple-patchsys.mk
include /usr/share/cdbs/1/rules/utils.mk
include /usr/share/cdbs/1/class/gnome.mk
include /usr/share/gnome-pkg-tools/1/rules/uploaders.mk
-include /usr/share/gnome-pkg-tools/1/rules/gnome-get-source.mk

LDFLAGS += -Wl,-z,defs -Wl,-O1 -Wl,--as-needed

DEB_DH_MAKESHLIBS_ARGS_libunique-1.0-0 = -V 'libunique-1.0-0 (>= 1.0.2)' -- -c4

binary-predeb/gir1.0-unique-1.0::

    dh_girepository -p$(cdbs_curpkg)

 

双冒号规则就是使用“::”代替普通规则的“:”得到的规则。当同一个文件作为多个规则的目标时,双冒号规则的处理和普通规则的处理过程完全不同(双冒号规则允许在多个规则中为同一个目标指定不同的重建目标的命令)。

首先需要明确的是:Makefile中,一个目标可以出现在多个规则中。但是这些规则必须是同一类型的规则,要么都是普通规则,要么都是双冒号规则。而不允许一个目标同时出现在两种不同类型的规则中。双冒号规则和普通规则的处理的不同点表现在以下几个方面:

1.        双冒号规则中,当依赖文件比目标更新时。规则将会被执行。对于一个没有依赖而只有命令行的双冒号规则,当引用此目标时,规则的命令将会被无条件执行。而普通规则,当规则的目标文件存在时,此规则的命令永远不会被执行(目标文件永远是最新的)。

2.        当同一个文件作为多个双冒号规则的目标时。这些不同的规则会被独立的处理,而不是像普通规则那样合并所有的依赖到一个目标文件。这就意味着对这些规则的处理就像多个不同的普通规则一样。就是说多个双冒号规则中的每一个的依赖文件被改变之后,make只执行此规则定义的命令,而其它的以这个文件作为目标的双冒号规则将不会被执行。

我们来看一个例子,在我们的Makefile中包含以下两个规则:

 

Newprog :: foo.c

       $(CC) $(CFLAGS) $< -o $@

Newprog :: bar.c

       $(CC) $(CFLAGS) $< -o $@

 

如果“foo.c”文件被修改,执行make以后将根据“foo.c”文件重建目标“Newprog”。而如果“bar.c”被修改那么“Newprog”将根据“bar.c”被重建。回想一下,如果以上两个规则为普通规时出现的情况是什么?(make将会出错并提示错误信息)

当同一个目标出现在多个双冒号规则中时,规则的执行顺序和普通规则的执行顺序一样,按照其在Makefile中的书写顺序执行。

GNU make的双冒号规则给我们提供一种根据依赖的更新情况而执行不同的命令来重建同一目标的机制。一般这种需要的情况很少,所以双冒号规则的使用比较罕见。一般双冒号规则都需要定义命令,如果一个双冒号规则没有定义命令,在执行规则时将为其目标自动查找隐含规则。 

 

     看完这个,我猜想,此rules文件开头“include”了许多*.mk文件,这些文件中可能会出现与“binary-predeb/gir1.0-unique-1.0”同名的目标,如果此时使用普通冒号规则的话,一旦出现同名的目标,则rules文件就会出错(makefile不允许同名目标出现在多个普通冒号规则中),另外在此文件中,每当引用“binary-predeb/gir1.0-unique-1.0”目标时,如果使用普通冒号规则并且目标存在的情况下,规则命令就永远也不会执行。针对这两个问题,使用双冒号规则就能得到很好的解决。 
 

 

 

posted on 2012-09-10 10:43  山本二十八  阅读(1292)  评论(0编辑  收藏  举报

导航