Makefile GNU make:单个规则中的多个目标

Makefile GNU make:单个规则中的多个目标,makefile,gnu-make,Makefile,Gnu Make,可能重复: 如果我有这样的Makefile规则: a b c: echo "Creating a b c" touch a b c output: a b c cat a b c > output .PHONY: things things: echo "Creating a b c" touch a b c output: things cat a b c > output 我运行make-j9输出 make查看3个依赖项(

可能重复:

如果我有这样的Makefile规则:

a b c:
    echo "Creating a b c"
    touch a b c

output: a b c
    cat a b c > output
.PHONY: things
things:
    echo "Creating a b c"
    touch a b c

output: things
    cat a b c > output
我运行make-j9输出

make查看3个依赖项(a、b、c),查找如何生成它们:(上面的“abc”规则),但是接下来会发生什么?它是否应该意识到“abc”规则只需要运行一次就可以创建所有3个目标

这就是make的实际功能:

[pavel@orianna test]$ make -j9 output -n
echo "Creating a b c"
touch a b c
echo "Creating a b c"
touch a b c
echo "Creating a b c"
touch a b c                                                                                                                                                                                                                                                                    
cat a b c > output                                                                                                                                                                                                                                                             
[pavel@orianna test]$
同一配方运行3次,每个依赖项一次,以规则“输出”


有人知道它为什么这样做吗?

您的
abc:
规则告诉Make这是如何构建这些目标中的任何一个,而不是如何构建所有目标。Make不够聪明,无法分析命令并推断运行一次规则将构建所有三个命令。Make知道(从
输出
规则)它必须重建
a
b
c
,所以它就是这样做的。它为
a
运行第一条规则一次,为
b
运行一次,为
c
运行一次

如果要单独重建它们,请执行以下操作:

a b c:
    echo "Creating $@"
    touch $@
如果要一次全部重建,请执行以下操作:

a b c:
    echo "Creating a b c"
    touch a b c

output: a b c
    cat a b c > output
.PHONY: things
things:
    echo "Creating a b c"
    touch a b c

output: things
    cat a b c > output
或者更好:

THINGS = a b c
.PHONY: things
things:
    echo "Creating $(THINGS)"
    touch $(THINGS)

output: things
    cat $(THINGS) > output

a b c是三个不同的目标/指标,没有任何先决条件。i、 也就是说,只要有人要求,它就会建立目标

a b c:
    echo "Creating a b c"
    touch a b c
您要求make生成以bc作为先决条件的目标命名输出。 所以目标AB c是按顺序构建的,最后生成输出

现在,在您的例子中,当调用其中一个目标时,所有目标都会被构建。因此,为了避免冗余构建,您必须向目标a、b、c添加先决条件。仅当“a”不存在时生成目标“a”。与“b”和“c”类似

a b c: $@
    echo "Creating a b c"
    touch a b c

然而,这是不可取的。理想情况下,Makefile目标应该非常具体。

回答得很好!非常感谢。创建虚假目标是唯一的方法,还是有更干净的方法来表达“a、b和c都是根据这条规则构建的”@Pavel,我不知道有更干净的方法(无论如何,我可能会选择第一种方法)。但我仍然在试图找出AUZKamath的答案。请参阅,了解处理此场景的方法的调查,包括在gmake中指定具有多个输出的规则的唯一“正确”方法(当然是模式规则!)。这是可行的,但我看不到如何做到。Jack Kelly给你发来了吗?但是,当使用
make-j3 a b c
运行此程序时,会创建三个作业。有人能解释一下这是如何工作的吗?我无法通过阅读@krmlr@xiphi来解释它,因为诀窍是当
make
考虑
a
时,它会看到规则
a:a
。仅当目标比其任何先决条件都旧或其任何先决条件都不存在时,才重建目标。这里,第一种情况永远不成立,第二种情况只有在
a
还不存在时才成立。触摸
后,
b:b
c:c
不需要重建。(对于
-j3
,有三个过程看到了
a:a
b:b
c:c
,并在任何
触摸之前对它们进行了处理:和