Согласно GNU make manual , то есть:
Если вы не помечаете правило соответствия чему-либо как терминальное, то оно не является терминальным.Нетерминальное правило сопоставления чего-либо не может применяться к имени файла, которое указывает конкретный тип данных.Имя файла указывает на конкретный тип данных, если ему соответствует какое-то неявное целевое правило без совпадений.
Ваше первое правило - это нетерминальное правило для поиска совпадений, поэтому оно не может применяться к цели 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'.
Ваше первое правило для правила match-any следует пометить как terminal
, определив его двойным двоеточием.
Когда правило является терминальным, оно не применяется, если его предпосылки не существуют.Предпосылки, которые могут быть сделаны с другими неявными правилами, недостаточно хороши.Другими словами, дальнейшее связывание не допускается, кроме терминального правила.
Измените ваш make-файл на:
%:: %.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