gmake: Как назначить глобальную переменную из команды оболочки?

#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, которые вам, вероятно, следует рассмотреть.

  1. Использование $(shell...) в рецептах не рекомендуется, поскольку рецепты уже являются сценариями оболочки. Итак, если вы хотите присвоить переменной оболочки рецепт, просто:

      all:
         GLOBVAR="$$(echo 'X')"
      

    Обратите внимание на $$ , чтобы избежать расширения, которое make выполняет перед передачей рецептов в оболочку.

  2. Разные линии рецепта выполнены в разных оболочках. Итак, если вы хотите использовать в строке переменную оболочки, которая была назначена в предыдущей строке, вы должны объединить их:

      all:
         GLOBVAR="$$(echo 'X')"; echo $$GLOBVAR
      

    (то же замечание, что и ранее по поводу $$ ). Вы можете использовать продолжение строки, если предпочитаете:

      all:
         GLOBVAR="$$(echo 'X')"; 
         echo $$GLOBVAR
      
  3. И, наконец, если вы хотите назначить переменные 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 в рецептах, вы, вероятно, забредете в опасные области.