为什么gnu无法弄清楚这一系列规则?

问题描述 投票:1回答:1

我有这个Makefile

%: %.x
    cp $< $@

build/%: src/%
    cp $< $@

以及如下所示的目录结构:

Makefile
build/
src/
    hello.x

为什么make表现如下:

$ make build/hello
make: *** No rule to make target 'build/hello'.  Stop.

为什么不能看到这一点

  1. 它可以使用第一条规则将src/hello.x翻译成src/hello,并且
  2. 使用第二条规则将src/hello复制到build/hello
gnu-make
1个回答
2
投票

GNU make manual说,那是:

如果您没有将match-anything规则标记为终端,则它是非终端的。非终端匹配任何规则不能应用于指示特定类型数据的文件名。如果某些非匹配任何隐式规则目标与其匹配,则文件名表示特定类型的数据。

您的第一个规则是非终端匹配任何规则,因此它不能应用于指示特定类型数据的目标src/hello。使用make build/hello -d的调试日志也显示了该过程:

......
Considering target file `build/hello'.
 Looking for an implicit rule for `build/hello'.
 Trying pattern rule with stem `hello'.
 Trying implicit prerequisite `src/hello'.
 Trying pattern rule with stem `hello'.
 Trying implicit prerequisite `build/hello,v'.
 Trying pattern rule with stem `hello'.
 Trying implicit prerequisite `build/RCS/hello,v'.
 Trying pattern rule with stem `hello'.
 Trying implicit prerequisite `build/RCS/hello'.
 Trying pattern rule with stem `hello'.
 Trying implicit prerequisite `build/s.hello'.
 Trying pattern rule with stem `hello'.
 Trying implicit prerequisite `build/SCCS/s.hello'.
 Trying pattern rule with stem `hello'.
 Trying implicit prerequisite `src/hello'.
 Looking for a rule with intermediate file `src/hello'.
  Avoiding implicit rule recursion.
  Trying pattern rule with stem `hello'.
  Trying implicit prerequisite `src/hello,v'.
  Trying pattern rule with stem `hello'.
  Trying implicit prerequisite `src/RCS/hello,v'.
  Trying pattern rule with stem `hello'.
  Trying implicit prerequisite `src/RCS/hello'.
  Trying pattern rule with stem `hello'.
  Trying implicit prerequisite `src/s.hello'.
  Trying pattern rule with stem `hello'.
  Trying implicit prerequisite `src/SCCS/s.hello'.
 No implicit rule found for `build/hello'.
 Finished prerequisites of target file `build/hello'.
No need to remake target `build/hello'.
make: Nothing to be done for `build/hello'.

您应该通过用双冒号定义第一条规则将匹配任何规则标记为terminal

当规则是终端时,除非其先决条件确实存在,否则它不适用。可以使用其他隐式规则进行的先决条件不够好。换句话说,在终端规则之外不允许进一步链接。

将您的makefile更改为:

%:: %.x
        cp $< $@

build/%: src/%
        cp $< $@

make build/hello测试:

cp src/hello.x src/hello
cp src/hello build/hello
rm src/hello

下面的调试日志显示了它的工作原理:

 ......
 Looking for a rule with intermediate file `src/hello'.
  Avoiding implicit rule recursion.
  Trying pattern rule with stem `hello'.
  Trying implicit prerequisite `src/hello.x'.
 Found an implicit rule for `build/hello'.
   Considering target file `src/hello.x'.
    Finished prerequisites of target file `src/hello.x'.
   No need to remake target `src/hello.x'.
 Considering target file `src/hello'.
  File `src/hello' does not exist.
   Pruning file `src/hello.x'.
  Finished prerequisites of target file `src/hello'.
 Must remake target `src/hello'.
cp src/hello.x src/hello
Putting child 0x08a51438 (src/hello) PID 30908 on the chain.
Live child 0x08a51438 (src/hello) PID 30908
Reaping winning child 0x08a51438 PID 30908
Removing child 0x08a51438 PID 30908 from chain.
 Successfully remade target file `src/hello'.
 Finished prerequisites of target file `build/hello'.
Must remake target `build/hello'.
cp src/hello build/hello
Putting child 0x08a51438 (build/hello) PID 30909 on the chain.
Live child 0x08a51438 (build/hello) PID 30909
Reaping winning child 0x08a51438 PID 30909
Removing child 0x08a51438 PID 30909 from chain.
Successfully remade target file `build/hello'.
Removing intermediate files...
rm src/hello
© www.soinside.com 2019 - 2024. All rights reserved.