2

如果我在 GNU Make 3.81 / RHEL5 下运行以下 makefile:

all: A1B/C A1B/D A2B/C A2B/D

A%B/C A%B/D: E.%
        @echo "Creating '$@' from '$^' with stem '$*'"

E.1 E.2:
        @echo "Generate '$@'"

我得到以下输出:

Generate 'E.1'
Creating 'A1B/C' from 'E.1' with stem '1'
Generate 'E.2'
Creating 'A2B/C' from 'E.2' with stem '2'

为什么没有生成文件 A1B/D 和 A2B/D?(我的测试用例中不存在具有此类名称的文件)

如果我通过命令行指定目标,则显示“无事可做”:

make A1B/C A1B/D A2B/C A2B/D
Generate 'E.1'
Creating 'A1B/C' from 'E.1' with stem '1'
make: Nothing to be done for `A1B/D'.
Generate 'E.2'
Creating 'A2B/C' from 'E.2' with stem '2'
make: Nothing to be done for `A2B/D'.

如果我将隐式规则复制到他们的目标中,它会起作用:

all: A1B/C A1B/D A2B/C A2B/D

A%B/C: E.%
        @echo "Creating '$@' from '$^' with stem '$*'"

A%B/D: E.%
        @echo "Creating '$@' from '$^' with stem '$*'"

E.1 E.2:
        @echo "Generate '$@'"
Generate 'E.1'
Creating 'A1B/C' from 'E.1' with stem '1'
Creating 'A1B/D' from 'E.1' with stem '1'
Generate 'E.2'
Creating 'A2B/C' from 'E.2' with stem '2'
Creating 'A2B/D' from 'E.2' with stem '2'

根据文档,这不应该有所作为。

提前致谢。

迈克尔

4

1 回答 1

2

您对文档说没有区别的说法不太正确。如果您有一个包含多个目标的模式规则(并且您确实这样做了),make则假设这两个目标都将在配方的一次执行中完成。

来自GNU make 手册

模式规则可能有多个目标。与普通规则不同,这不会像许多具有相同先决条件和配方的不同规则一样起作用。如果模式规则有多个目标,make 知道规则的配方负责生成所有目标。该配方仅执行一次以生成所有目标。

您可以为您的案例确认此行为:

$ make -r -d
GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program built for i386-apple-darwin11.3.0
Reading makefiles...
Reading makefile `Makefile'...
Updating makefiles....
 Considering target file `Makefile'.
  Looking for an implicit rule for `Makefile'.
  No implicit rule found for `Makefile'.
  Finished prerequisites of target file `Makefile'.
 No need to remake target `Makefile'.
Updating goal targets....
Considering target file `all'.
 File `all' does not exist.
 Looking for an implicit rule for `all'.
 No implicit rule found for `all'.
  Considering target file `A1B/C'.
   File `A1B/C' does not exist.
   Looking for an implicit rule for `A1B/C'.
   Trying pattern rule with stem `1'.
   Trying implicit prerequisite `E.1'.
   Found an implicit rule for `A1B/C'.
    Considering target file `E.1'.
     File `E.1' does not exist.
     Finished prerequisites of target file `E.1'.
    Must remake target `E.1'.
Putting child 0x7fcad3c08440 (E.1) PID 34127 on the chain.
Live child 0x7fcad3c08440 (E.1) PID 34127 
Generate 'E.1'
Reaping winning child 0x7fcad3c08440 PID 34127 
Removing child 0x7fcad3c08440 PID 34127 from chain.
    Successfully remade target file `E.1'.
   Finished prerequisites of target file `A1B/C'.
  Must remake target `A1B/C'.
Putting child 0x7fcad3c08710 (A1B/C) PID 34128 on the chain.
Live child 0x7fcad3c08710 (A1B/C) PID 34128 
Creating 'A1B/C' from 'E.1' with stem '1'
Reaping winning child 0x7fcad3c08710 PID 34128 
Removing child 0x7fcad3c08710 PID 34128 from chain.
  Successfully remade target file `A1B/C'.
  Considering target file `A1B/D'.
  File `A1B/D' was considered already.
  Considering target file `A2B/C'.
   File `A2B/C' does not exist.
   Looking for an implicit rule for `A2B/C'.
   Trying pattern rule with stem `2'.
   Trying implicit prerequisite `E.2'.
   Found an implicit rule for `A2B/C'.
    Considering target file `E.2'.
     File `E.2' does not exist.
     Finished prerequisites of target file `E.2'.
    Must remake target `E.2'.
Putting child 0x7fcad3c08cd0 (E.2) PID 34129 on the chain.
Live child 0x7fcad3c08cd0 (E.2) PID 34129 
Generate 'E.2'
Reaping winning child 0x7fcad3c08cd0 PID 34129 
Removing child 0x7fcad3c08cd0 PID 34129 from chain.
    Successfully remade target file `E.2'.
   Finished prerequisites of target file `A2B/C'.
  Must remake target `A2B/C'.
Putting child 0x7fcad3c08cd0 (A2B/C) PID 34130 on the chain.
Live child 0x7fcad3c08cd0 (A2B/C) PID 34130 
Creating 'A2B/C' from 'E.2' with stem '2'
Reaping winning child 0x7fcad3c08cd0 PID 34130 
Removing child 0x7fcad3c08cd0 PID 34130 from chain.
  Successfully remade target file `A2B/C'.
  Considering target file `A2B/D'.
  File `A2B/D' was considered already.
 Finished prerequisites of target file `all'.
Must remake target `all'.
Successfully remade target file `all'.

注意这些行:

File `A1B/D' was considered already.
File `A2B/D' was considered already.
于 2013-06-17T21:43:53.703 回答