![Использование `[email protected]` в зависимости Makefile не будет работать](https://rvso.com/image/191962/%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%20%60%5Bemail%20protected%5D%60%20%D0%B2%20%D0%B7%D0%B0%D0%B2%D0%B8%D1%81%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D0%B8%20Makefile%20%D0%BD%D0%B5%20%D0%B1%D1%83%D0%B4%D0%B5%D1%82%20%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0%D1%82%D1%8C.png)
Попытка использовать следующее правило Makefile не сработала (GNU Make 4.0):
foo: [email protected] other.o
bar: bar.o other.o
Файл foo.c
был скомпилирован (в foo.o
), но команда компоновки была cc -o .o
.
Напротив, bar
был скомпилирован и скомпонован правильно как cc bar.o other.o -o bar
.
Кто может объяснить разницу (или проблему)?
решение1
Это рассматривается в разделеАвтоматические переменныев руководстве GNU Make:
Очень важно, чтобы вы осознавали ограниченную область, в которой доступны значения автоматических переменных: они имеют значения только в пределах рецепта. В частности, вы не можете использовать их где-либо в целевом списке правила; они не имеют там значения и будут расширяться до пустой строки. Кроме того, к ним нельзя получить прямой доступ в списке предварительных условий правила. Распространенной ошибкой является попытка использовать
$@
в списке предварительных условий; это не сработает.
Остальная часть абзаца дает одно из возможных решений, хотя и специфичное для GNU Make:вторичное расширение. Написание вашего Makefile как
.SECONDEXPANSION:
foo: [email protected] other.o
bar: bar.o other.o
позволяет $$@
присвоить соответствующее значение, а затем
$ make foo
cc -c -o foo.o foo.c
cc -c -o other.o other.c
cc foo.o other.o -o foo
делает то, на что вы надеетесь.
(По моему опыту, обычно существуют лучшие способы решения проблемы, чем прибегать к вторичному расширению, но это можно определить, только понимая общую цель того, что вы пытаетесь сделать.)