GNU Make 手册的 4.13 部分描述了所谓的 double - 冒号规则:
双冒号规则是在目标名称后面使用“::”而不是“:”编写的规则。当同一目标出现在多个规则中时,它们的处理方式与普通规则不同。
当一个目标出现在多个规则中时,所有规则必须是同一类型:全部是普通的,或者全部是双冒号。如果它们是双冒号,则它们彼此独立。如果目标早于该规则的任何先决条件,则执行每个双冒号规则的命令。如果该规则没有先决条件,则始终执行其命令(即使目标已存在)。这可能会导致不执行任何双冒号规则、执行任何双冒号规则或执行所有双冒号规则。
具有相同目标的双冒号规则实际上是完全独立的。每个双冒号规则都是单独处理的,就像处理不同目标的规则一样。
目标的双冒号规则按照它们在 makefile 中出现的顺序执行。然而,双冒号规则真正有意义的情况是执行命令的顺序并不重要的情况。
双冒号规则有些晦涩难懂,而且通常不是很有用;它们为用于更新目标的方法根据导致更新的必备文件而不同的情况提供了一种机制,但这种情况很少见。
每个双冒号规则应指定命令;如果不存在,则将使用隐含规则(如果适用)。请参阅使用隐式规则部分。
我有点单独理解本节每个句子的含义,但我仍然不清楚双冒号规则的用途。至于罕见性,我还没有看到任何开源项目的 Makefile 不是以“
all::
因此:Makefile 中双冒号规则的预期目的是什么?”
Section 4.13 of the GNU Make manual describes the so-called double-colon rules:
Double-colon rules are rules written with ‘::’ instead of ‘:’ after the target names. They are handled differently from ordinary rules when the same target appears in more than one rule.
When a target appears in multiple rules, all the rules must be the same type: all ordinary, or all double-colon. If they are double-colon, each of them is independent of the others. Each double-colon rule's commands are executed if the target is older than any prerequisites of that rule. If there are no prerequisites for that rule, its commands are always executed (even if the target already exists). This can result in executing none, any, or all of the double-colon rules.
Double-colon rules with the same target are in fact completely separate from one another. Each double-colon rule is processed individually, just as rules with different targets are processed.
The double-colon rules for a target are executed in the order they appear in the makefile. However, the cases where double-colon rules really make sense are those where the order of executing the commands would not matter.
Double-colon rules are somewhat obscure and not often very useful; they provide a mechanism for cases in which the method used to update a target differs depending on which prerequisite files caused the update, and such cases are rare.
Each double-colon rule should specify commands; if it does not, an implicit rule will be used if one applies. See section Using Implicit Rules.
I kinda grok the meaning of each sentence of this section individually, but it's still not clear to me what double-colon rules are for. As for being rare, I have not yet seen any open-source project whose Makefile did not begin with
all::
Therefore: What's the intended purpose of double-colon rules in Makefiles?
发布评论
评论(5)
每个::规则都是独立处理的,所以可以更简单。例如,单个规则:
可以用两个更简单的规则替换:
像 AutoMake 这样的实用程序比一些复杂的规则更容易输出许多简单的规则。
发布了一个包含更多示例的精彩答案,然后将其删除,然后在此处找到:
https://web.archive.org/web/20180122002430/http://owen.sj.ca.us/~rk/howto/slides/make/slides/makecolon.html
感谢 RK Owen 写下它,感谢 Edward Minnix 再次找到它!
Each :: rule is processed independently, so it can be simpler. For example, the single rule:
can be replaced with two simpler rules:
Utilities like AutoMake have an easier time spitting out many simple rules than a few complex ones.
A great answer with more examples was posted, then taken down, then found here:
https://web.archive.org/web/20180122002430/http://owen.sj.ca.us/~rk/howto/slides/make/slides/makecolon.html
Thanks to R.K. Owen for writing it, and Edward Minnix for finding it again!
双冒号在 3 种情况下很有用:
示例 .c 文件:
使用的 Makefile:
结果:
下面的例子解释了这种情况:a.config文件是从a.cfg中获取的,而a.cfg又是从a.cfg1中获取的(a.cfg是中间文件)。
结果(由于 %.config 规则是终端,make 禁止从 a.cfg1 创建中间 a.cfg 文件):
%.config 没有双冒号,结果是:
c@desk:~/test/circle3$ cat Makefile
结果:
There are 3 situations where the double colon are useful:
Sample .c file:
Makefile used:
Outcome:
The following example explains this situation: the a.config file is obtained from a.cfg, which in turn is obtained from a.cfg1 (a.cfg being the intermediate file).
Outcome (as the %.config rule is terminal, make inhibits the creation of the intermediate a.cfg file from a.cfg1):
Without the double colon for the %.config, the outcome is:
c@desk:~/test/circle3$ cat Makefile
Outcome:
正如文档所说,双冒号规则很少有用。它们是一种很好的小方法,可以不命名复合虚假目标的各个目标(如 all::),但在这个角色中并不是真正必要的。我只能在必要时构建一个人为的示例:
假设您有一个日志文件 L,它是由其他几个日志文件 L1、L2、... 连接而成。您制定了许多双冒号规则,例如:
如今在 GNU make 中,您当然会使用
$^
来实现这种魔法,但它在 GNU make 的功能选项卡上被列为一个受启发的功能。Just as the documentation says, double-colon rules are rarely very useful. They are a nice, little way of not naming the individual targets of a composite phony target (like all::), but not really necessary in this role. I can only form one contrived example where they are necessary:
Suppose you have a logfile L that is concatenated from several other logfiles L1, L2, .... You formulate a number of double-colon rules like:
Nowadays in GNU make, you would of course use
$^
for this kind of magic, but it is listed as an inspired feature on GNU make's feature tab.它们对于非递归 makefile 和诸如
clean
之类的目标非常方便。也就是说,单个 .mk 文件可以将自己的命令添加到已在其他地方定义的clean
目标中。文档给出了答案:
They are handy for non-recursive makefiles and targets like
clean
. That is, an individual .mk file can add its own commands to theclean
target already defined elsewhere.Documentation gives an answer:
我将提供一个简单的示例,希望使用法更清楚:
使用以下 makefile 进行实验:
运行
make a.faux
,它将导致dep1.fake
和dep2.fake 运行。删除
dep1.fake
并再次运行make a.faux
,只有dep1.fake
会运行。I'll contribute a simple example to hopefully make the usage clear:
Experiment with the following makefile:
Run
make a.faux
, it will causesdep1.fake
anddep2.fake
to run. Deletedep1.fake
and runmake a.faux
again, onlydep1.fake
will run.