Makefile GNU制造中的互斥器?

Makefile GNU制造中的互斥器?,makefile,gnu-make,Makefile,Gnu Make,这样的一条规则可以满足两个目标: foo.o foo.h : build_foo # this makes both foo.o and foo.h 后来,一些目标需要一个,其他目标需要两个: bar : foo.o build_bar baz : foo.h build_baz qux : bar baz build qux 当使用-jN调用make时,如何防止配方运行两次?通过设定配方同时构建两个目标来实现这一点 您的目标: foo.o foo.h :

这样的一条规则可以满足两个目标:

foo.o foo.h :
    build_foo # this makes both foo.o and foo.h
后来,一些目标需要一个,其他目标需要两个:

bar : foo.o
    build_bar

baz : foo.h
    build_baz

qux : bar baz
    build qux

当使用
-jN
调用
make
时,如何防止配方运行两次?

通过设定配方同时构建两个目标来实现这一点

您的目标:

foo.o foo.h :
    build_foo # this makes both foo.o and foo.h
通过与以下目标相同的方式查看:

foo.o :
    build_foo # this makes both foo.o and foo.h

foo.h :
    build_foo # this makes both foo.o and foo.h
这就是问题所在

您需要的是指定两个目标文件的模式规则

%.o %.h :
    build_foo # this makes both foo.o and foo.h
这是因为GNU在指定多个目标时是如何生成句柄的(但你确实想给它一个合理的先决条件):

foo.o :
    build_foo # this makes both foo.o and foo.h

foo.h :
    build_foo # this makes both foo.o and foo.h
模式规则可能有多个目标。与普通规则不同的是,这并不像许多具有相同先决条件和配方的不同规则那样起作用。如果模式规则有多个目标,
make
知道规则的配方负责生成所有目标。配方只执行一次以生成所有目标。当搜索与目标匹配的模式规则时,规则的目标模式(与需要规则的目标匹配的模式除外)是偶然的:
make
只担心为当前有问题的文件提供配方和先决条件。但是,当运行此文件的配方时,其他目标会被标记为自己已更新


我尽量避免模式规则。在你的例子中,你会发现在配方运行后,
foo.o
foo.h
中的一个比另一个更新(只需在它们上面使用
$ls--全职的

假设你的食谱创建了
foo.h
,然后继续创建
foo.o
。这表明:

foo.o: foo.h ; # Empty recipe

foo.h: prereq1 prereq2 ...
    build_foo
所以现在如果
foo.o
是另一条规则的先决条件,
make
将首先构建
foo.h
,作为副作用创建
foo.o
。然后它将运行
foo.o
的配方。工作完成了

如果你感到不安, 您可以添加一个简单的断言,
foo.o
确实比
foo.h

foo.o: foo.h
    test $@ -nt $<
foo.o:foo.h
测试$@-nt$<

有关此主题的更多信息,请查看标题为

的automake(非make)一章。此外,GNU make手册中有一章是关于此主题的: