gmake:如何从shell命令分配全局变量?

问题描述

我有一个执行一些shell命令的makefile,我想将输出存储到全局变量中:

GLOBVAR = a

all:
    GLOBVAR=$(shell echo 'X')
    $(info $(GLOBVAR))

GLOBVAR为空。我在做什么错了?

解决方法

您正在混合make和shell变量。在GLOBVAR=$(shell echo 'X')中,它是您分配的shell变量,而在$(info $(GLOBVAR))中,它是您扩展的make变量。

尝试以下方法:

GLOBVAR = $(shell echo 'X')

all:
    $(info $(GLOBVAR))

但是您的Makefile可能还有其他一些问题,您应该考虑。

  1. 不建议在配方中使用$(shell...),因为配方已经是Shell脚本。因此,如果要在配方中分配外壳变量,只需:

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

    请注意,$$会在将配方传递到外壳之前避免make进行的扩展。

  2. 配方的不同行在不同的shell中执行。因此,如果要在一行中使用在上一行中分配的shell变量,则必须将它们加入:

     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
    

    我想让您想象一下并行make的结果是什么...总之,如果您开始在配方中使用make函数,您可能会徘徊在危险区域中。