#makefile #gnu-make
#makefile #gnu-make
Вопрос:
У меня есть makefile, который выполняет некоторую команду оболочки, и я хочу сохранить выходные данные в глобальную переменную:
GLOBVAR = a
all:
GLOBVAR=$(shell echo 'X')
$(info $(GLOBVAR))
GLOBVAR
пусто. Что я делаю не так?
Ответ №1:
Вы смешиваете переменные make и shell. В GLOBVAR=$(shell echo 'X')
это переменная оболочки, которую вы назначаете, в то время как в $(info $(GLOBVAR))
это переменная make, которую вы расширяете.
Попробуйте это вместо:
GLOBVAR = $(shell echo 'X')
all:
$(info $(GLOBVAR))
Но есть несколько других проблем с вашим Makefile, которые вам, вероятно, следует рассмотреть.
-
Использование
$(shell...)
в рецептах не рекомендуется, поскольку рецепты уже являются сценариями оболочки. Итак, если вы хотите присвоить переменной оболочки рецепт, просто:all: GLOBVAR="$$(echo 'X')"
Обратите внимание на
$$
, чтобы избежать расширения, которое make выполняет перед передачей рецептов в оболочку. -
Разные линии рецепта выполнены в разных оболочках. Итак, если вы хотите использовать в строке переменную оболочки, которая была назначена в предыдущей строке, вы должны объединить их:
all: GLOBVAR="$$(echo 'X')"; echo $$GLOBVAR
(то же замечание, что и ранее по поводу
$$
). Вы можете использовать продолжение строки, если предпочитаете:all: GLOBVAR="$$(echo 'X')"; echo $$GLOBVAR
-
И, наконец, если вы хотите назначить переменные make в рецептах, вы можете с
eval
помощью функции make, но я настоятельно не рекомендую вам делать это, пока вы не поймете, когда make делает то, что:$ cat Makefile .PHONY: all lla all: $(eval GLOBVAR = $(shell echo 'X')) @echo all: $(GLOBVAR) lla: @echo lla: $(GLOBVAR) $ make all all: X $ make lla lla: $ make all lla all: X lla: X $ make lla all lla: all: X
И я позволяю вам представить, какие результаты могут быть с parallel make… В заключение, если вы начнете использовать функции make в рецептах, вы, вероятно, забредете в опасные области.