GNU make隐式规则中的drop目标?

时间:2013-06-17 21:28:04

标签: makefile implicit rule

如果我在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 states"什么都不做":

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'

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

提前致谢。

迈克尔

1 个答案:

答案 0 :(得分:2)

你对文件说你说的没有区别。如果您有一个包含多个目标的模式规则(并且您确实如此),make假设两个目标都将在一次执行中完成。

来自GNU make manual

  

模式规则可能有多个目标。与普通规则不同,这并不会使用相同的先决条件和配方来执行许多不同的规则。如果模式规则具有多个目标,则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.