Makefile 测试变量是否为空

cer*_*ros 6 makefile

在生成文件中,我正在尝试

  • 运行 shell 命令并在 make 变量中捕获输出
  • 如果变量不为空,做一些事情

我创建了这个简化的 makefile 来演示我的问题。无论是make amake b执行的身体,如果,我不明白为什么不能。

.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
Run Code Online (Sandbox Code Playgroud)

我正在使用

$ make --version
GNU Make 3.81
Run Code Online (Sandbox Code Playgroud)

编辑:正如所指出的,vars 不需要 make vars

Ren*_*let 1

请注意,由于评估时间的原因,make 条件语句 ( ifeq, ifneq...) 无法按照您尝试的方式在配方中使用。请改用 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
Run Code Online (Sandbox Code Playgroud)

如果您绝对需要MY_VAR成为特定于目标的 make 变量,但只想(每个目标)执行一次产生其值的 shell 命令,MadScientist 有一个精彩的技巧,您可能应该看看。应用于您的案例,它应该如下所示:

$ 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
Run Code Online (Sandbox Code Playgroud)

它可能看起来非常奇怪,但它保证MY_VAR当且仅当目标ab被调用时才计算 ,并且每个目标最多只计算一次。请参阅MadScientist 的帖子以获取详细解释。去吧,太棒了。