Makefile测试变量是否为空

时间:2018-07-26 09:16:34

标签: makefile

在我要创建的文件中

  • 运行shell命令并在make变量中捕获输出
  • 如果变量不为空,请执行以下操作

我已经创建了这个简化的makefile来演示我的问题。 make amake b都不执行if的正文,我不明白为什么不这样做。

.PHONY: a b

a:
    $(eval MY_VAR = $(shell echo whatever))
    @echo MY_VAR is $(MY_VAR)
    $(info $(MY_VAR))
ifneq ($(strip $(MY_VAR)),)
    @echo "should be executed"
endif
    @echo done

b:
    $(eval MY_VAR = $(shell echo ''))
    @echo MY_VAR is $(MY_VAR)
    $(info $(MY_VAR))
ifneq ($(strip $(MY_VAR)),)
    @echo "should not be executed"
endif
    @echo done

我正在使用

$ make --version
GNU Make 3.81

编辑:如前所述,var不必是make vars

4 个答案:

答案 0 :(得分:2)

如果要动态测试MY_VAR的内容,则可能必须:

a:
    $(eval MY_VAR = $(shell echo ''))
    $(if $(strip $(MY_VAR)),echo ok,echo no)

if如果echo ok不为空,则评估为MY_VAR,否则它将为echo no

答案 1 :(得分:1)

解析Makefile时,将评估ifeq及其条件句。如果要在扩展规则时使用条件作为Make变量,则需要使用$(if )函数:

.PHONY: a b

a b:
    @$(if $(strip $(MY_VAR)),echo "MY_VAR isn't empty",)
    @echo done

a: MY_VAR =
b: MY_VAR = something

答案 2 :(得分:0)

请注意,由于要进行评估,因此无法像您尝试的那样在食谱中使用条件(ifeqifneq ...)。改为使用shell条件,如下所示。

由于您的MY_VAR变量仅在配方中使用,是与目标相关的,并且您希望仅在需要时才进行计算,所以为什么不使用shell变量而不是make变量?

$ cat Makefile
.PHONY: a b

a:
    MY_VAR=$$(echo 'whatever') && \
    echo '$@: MY_VAR is $$MY_VAR' && \
    if [ -n "$$MY_VAR" ]; then \
      echo '$@: should be executed'; \
    fi && \
    echo '$@: done'

b:
    MY_VAR=$$(echo '') && \
    echo '$@: MY_VAR is $$MY_VAR' && \
    if [ -n "$$MY_VAR" ]; then \
      echo '$@: should not be executed'; \
    fi && \
    echo '$@: done'

$ make a
a: MY_VAR is whatever
a: should be executed
a: done

$ make b
b: MY_VAR is
b: done

如果您绝对需要MY_VAR作为特定于目标的make变量,但只想执行一次(每个目标)产生其值的shell命令,则MadScientist会提供一个wonderful trick应该看一下。应用于您的案例,它应该类似于:

$ make --version
GNU Make 4.1
...

$ cat Makefile
a: MY_VAR = $(eval a: MY_VAR := $$(shell echo 'whatever'))$(MY_VAR)
b: MY_VAR = $(eval b: MY_VAR := $$(shell echo ''))$(MY_VAR)

a:
    @echo '$@: MY_VAR is $(MY_VAR)' && \
    if [ -n "$(MY_VAR)" ]; then \
      echo '$@: should be executed'; \
    fi && \
    echo '$@: done'

b:
    @echo '$@: MY_VAR is $(MY_VAR)' && \
    if [ -n "$(MY_VAR)" ]; then \
      echo '$@: should not be executed'; \
    fi && \
    echo '$@: done'

$ make a
a: MY_VAR is whatever
a: should be executed
a: done

$ make b
b: MY_VAR is
b: done

$ make b a
b: MY_VAR is
b: done
a: MY_VAR is whatever
a: should be executed
a: done

它看起来很奇怪,但是它保证只有在调用目标MY_VARa的情况下才计算b,每个目标最多只能调用一次。请查看MadScientist's post以获得详细说明。走,那太棒了。

答案 3 :(得分:0)

字段左边,但是在我的情况下很有用,因此我认为值得分享:使用xargs选项将值传递到--no-run-if-empty

echo $(POSSIBLY_EMPTY) | xargs --no-run-if-empty echo

请注意,这将在OSX上有效。有关xargs --no-run-if-empty

的更多详细信息,请参见How to ignore xargs commands if stdin input is empty?