4.13 GNU制作手册部分描述了所谓的双冒号规则:
双冒号规则是在目标名称之后用“::”而不是“:”编写的规则。当同一目标出现在多条规则中时,它们的处理方式与普通规则不同。 当一个目标出现在多个规则中时,所有规则都必须是相同的类型:所有普通的,或所有的双冒号。如果它们是双冒号,那么它们中的每一个都是独立的.如果目标早于该规则的任何先决条件,则执行每个双冒号规则的命令。如果该规则没有先决条件,则始终执行它的命令(即使目标已经存在)。这可能导致执行任何、任何或所有双冒号规则. 具有相同目标的双冒号规则实际上是完全独立的。每个双冒号规则被单独处理,就像处理不同目标的规则一样. 目标的双冒号规则按照它们在makefile中出现的顺序执行。然而,在双冒号规则真正有意义的情况下,执行命令的顺序并不重要。 双冒号规则有点模糊,而且通常不太有用;它们提供了一种机制,用于更新目标的方法因导致更新的前提文件不同而不同,而且这种情况非常罕见。 每个双冒号规则都应该指定命令;如果不指定,则在应用时将使用隐式规则。参见使用隐式规则的一节。
我有点摸索这一节每句话的意思,但我仍然不清楚双冒号规则是干什么用的。至于很少,我还没有看到任何开放源码项目的Makefile没有开始。
all::因此:在Makefiles中双冒号规则的目的是什么?
发布于 2014-09-19 21:05:26
规则是独立处理的,所以它可以更简单。例如,单一规则:
libxxx.a : sub1.o sub2.o
ar rv libxxx.a sub1.o
ar rv libxxx.a sub2.o可以用两个更简单的规则来代替:
libxxx.a :: sub1.o
ar rv libxxx.a sub1.o
libxxx.a :: sub2.o
ar rv libxxx.a sub2.o与一些复杂的规则相比,像AutoMake这样的实用程序更容易抛出许多简单的规则。
更多的例子给出了一个很好的答案,然后取下来,然后在这里找到:
感谢R.K.欧文写了这本书,爱德华·明尼克斯又找到了它!
发布于 2015-11-01 20:02:30
有三种情况下,双冒号是有用的:
示例.c文件:
c@desk:~/test/circle$ cat circle.c
#include <stdio.h>
int main (void)
{
printf("Example.\n");
return 0;
}使用Makefile:
c@desk:~/test/circle$ cat Makefile
# A makefile for "circle" to demonstrate double-colon rules.
CC = gcc
RM = rm -f
CFLAGS = -Wall -std=c99
DBGFLAGS = -ggdb -pg
DEBUGFILE = ./debug
SRC = circle.c
circle :: $(SRC)
$(CC) $(CFLAGS) -o $@ -lm $^
circle :: $(DEBUGFILE)
$(CC) $(CFLAGS) $(DBGFLAGS) -o $@ -lm $(SRC)
.PHONY : clean
clean :
$(RM) circle结果:
c@desk:~/test/circle$ make circle
gcc -Wall -std=c99 -o circle -lm circle.c
make: *** No rule to make target 'debug', needed by 'circle'. Stop.
c@desk:~/test/circle$ make circle
gcc -Wall -std=c99 -o circle -lm circle.c
gcc -Wall -std=c99 -ggdb -pg -o circle -lm circle.c
c@desk:~/test/circle$ vim circle.c
c@desk:~/test/circle$ make circle
gcc -Wall -std=c99 -o circle -lm circle.c
c@desk:~/test/circle$ vim debug
c@desk:~/test/circle$ make circle
gcc -Wall -std=c99 -ggdb -pg -o circle -lm circle.c下面的示例解释了这种情况: a.config文件是从a.cfg获得的,而后者又是从a.cfg1 (a.cfg是中间文件)获得的。
c@desk:~/test/circle1$ ls
a.cfg1 log.txt Makefile
c@desk:~/test/circle1$ cat Makefile
CP=/bin/cp
%.config:: %.cfg
@echo "$@ from $<"
@$(CP) $< $@
%.cfg: %.cfg1
@echo "$@ from $<"
@$(CP) $< $@
clean:
-$(RM) *.config结果(因为%.config规则是终端的,所以要阻止从a.cfg1创建中间a.cfg文件):
c@desk:~/test/circle1$ make a.conf
make: *** No rule to make target 'a.conf'. Stop.如果没有%.config的双冒号,结果是:
c@desk:~/test/circle1$ make a.config
a.cfg from a.cfg1
a.config from a.cfg
rm a.cfgC@desk:~/test/圆形3$ cat Makefile
CP=/bin/cp
a.config::
@echo "Always" >> $@
a.config::
@echo "Always!" >> $@
clean:
-$(RM) *.config 结果:
c@desk:~/test/circle3$ make a.config
c@desk:~/test/circle3$ cat a.config
Always
Always!
c@desk:~/test/circle3$ make a.config
c@desk:~/test/circle3$ cat a.config
Always
Always!
Always
Always!发布于 2011-10-25 14:50:21
对于非递归的makefile和像clean这样的目标,它们非常方便。也就是说,单个.mk文件可以将自己的命令添加到其他地方已经定义的clean目标中。
文档给出了答案:
双冒号规则有点模糊,而且通常不太有用;提供了一种机制,用于更新目标的方法因导致更新的前提文件不同而不同,而且这种情况很少见。
https://stackoverflow.com/questions/7891097
复制相似问题