我有这个Makefile
:
%: %.x
cp $< $@
build/%: src/%
cp $< $@
以及如下所示的目录结构:
Makefile
build/
src/
hello.x
为什么make
表现如下:
$ make build/hello
make: *** No rule to make target 'build/hello'. Stop.
为什么不能看到这一点
src/hello.x
翻译成src/hello
,并且src/hello
复制到build/hello
?据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