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

Pav*_*vel 28 makefile gnu-make

可能重复:
GNU Makefile规则从单个源文件生成一些目标

如果我有这样的Makefile规则:

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

output: a b c
    cat a b c > output
Run Code Online (Sandbox Code Playgroud)

然后我运行make -j9输出

make看到3个依赖项(a,b,c),查找如何生成它们:(上面的"ab c"规则),但接下来会发生什么?如果没有意识到"ab c"规则只需要运行一次来​​创建所有3个目标吗?

这就是实际做的事情:

[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]$
Run Code Online (Sandbox Code Playgroud)

相同的配方运行3次,每次依赖一次以规则"输出"!

有谁知道它为什么会这样?

Bet*_*eta 30

您的a b c:规则告诉Make这是如何构建任何这些目标,而不是如何构建所有这些目标.Make不够聪明,无法分析命令,并推断一旦运行规则将构建所有三个命令.让(从output规则中)知道它必须重建a,b并且c这就是它的作用.它运行第一个规则一次a,一次为b一次,一次为c.

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

a b c:
    echo "Creating $@"
    touch $@
Run Code Online (Sandbox Code Playgroud)

如果您想一次重建它们,请执行以下操作:

.PHONY: things
things:
    echo "Creating a b c"
    touch a b c

output: things
    cat a b c > output
Run Code Online (Sandbox Code Playgroud)

或者更好的是:

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

output: things
    cat $(THINGS) > output
Run Code Online (Sandbox Code Playgroud)

  • 有关处理此业务情景的方法调查,请参见http://www.cmcrossroads.com/ask-mr-make/12908-rules-with-multiple-outputs-in-gnu-make,包括唯一的"正确"方式在gmake中指定具有多个输出的规则(模式规则,当然!). (13认同)
  • 很棒的答案!谢谢.创造一个虚假的目标是唯一的方式,还是有一种更清晰的方式来表达"这个规则建立了**和**b**和**c"? (2认同)

Kam*_*ath 9

abc是三个不同的目标/目标,没有任何先决条件.我想说它会在被要求时建立目标.

a b c:
    echo "Creating a b c"
    touch a b c
Run Code Online (Sandbox Code Playgroud)

您要求make构建具有abc作为先决条件的目标命名输出.因此,目标abc按顺序构建,最后构建输出.

现在,在你的情况下,当调用任何一个目标时,所有目标都会被构建.因此,为避免冗余构建,您必须向目标a,b,c添加先决条件.仅当'a'不存在时才构建目标'a'.同样对于'b'和'c'

a b c: $@
    echo "Creating a b c"
    touch a b c
Run Code Online (Sandbox Code Playgroud)

但是这不可取.理想情况下,Makefile目标应该非常具体.

  • 这有效,但我看不出怎么样.杰克凯利送你了吗? (2认同)
  • 谁能解释一下这是如何工作的?我无法通过阅读https://www.gnu.org/software/make/manual/make.html#index-_0024_0040来解释它 (2认同)