Можно ли отображать переменные вне правил с помощью GNU Make?
Рассмотрим следующий Makefile:
x = foo bar baz
ifdef x
@echo $(x)
endif
Это приводит кMakefile:4: *** commands commence before first target. Stop.
Однако если я добавлю правило, оно сработает:
x = foo bar baz
ifdef x
t:
@echo $(x)
endif
Действительно ли необходимо добавлять правила вывода переменных для отладки и т.п.?
Бонус:
Почему удаление ifdef
приводит к Makefile:3: *** missing separator. Stop.
?
x = foo bar baz
@echo $(x)
решение1
эм, возможно, но бесполезно.
Вы должны понимать, что Makefile не похож на скрипт оболочки. Makefile определяет цели и то, что должно быть сделано для создания этих целей. Если вы помните об этом, выполнение ложной команды в Makefile становится концептуальной проблемой. Когда эта команда будет выполнена? Нет цели, которая бы запускала эту команду.
Вы могли бы:
MY_VAR := $(shell ls)
all:
@echo MY_VAR IS $(MY_VAR)
Обратите внимание, что я предполагал GNU make
. Это выполнится ls
за вас и поместит вывод в MY_VAR
. Но это хак, которого следует избегать.
Вы также можете попробовать дополнительную цель
extra:
@echo $(x)
и добавьте это как предварительное требование для всех остальных целей.
Что касается бонуса: это потому, что строка @echo $(x)
не имеет разделителя. В этом месте файла, make
ожидалось бы цель с а :
, а на этой строке нет :
. (есть и другие возможности, например, новое назначение переменной и т. д., конечно)
решение2
GNU make
есть функция, которая делает именно это, и она называется $(info ....)
.
Вы можете поместить следующую строку вне a, rule
и GNU make выполнит ее:
$(info variable x = $x))
А если вы обнаружите, что выполняете подобную задачу неоднократно, вы можете абстрагировать ее в macro
и вызывать при необходимости:
make -f - <<\eof
dumpvar = $(info variable `$1' value is >>>$($1)<<<)
ssl_enable = NO
$(call dumpvar,ssl_enable)
.PHONY: all
all:;@:
eof
На Stout будет отображаться следующее:
variable `ssl_enable' value is >>>NO<<<