GNU make 4.1:在定义的函数中$(if ...)为true时缺少分隔符

时间:2017-11-22 08:26:17

标签: makefile gnu-make

当在shell命令的输出中找不到字符串时,我试图在Makefile中生成错误。 shell命令取决于参数,因此整个过程都在一个已定义的函数中。这是一个极简主义的例子:

define check_in_abcdefg
$(eval TMP := $(shell echo abcdefg))
$(if $(findstring $(1),$(TMP)),,$(error $(1) not in $(TMP)))
endef

$(call check_in_abcdefg,def)

all:
    @echo Hello, world!

我希望这个Makefile在这种情况下输出Hello, world!,但如果我用这个替换调用行,我希望输出xyz not in abcdefg

$(call check_in_abcdefg,xyz)

问题是通过def检查我得到了这个输出:

  

Makefile:6:***缺少分隔符。停止。

第6行是$(call check_in_abcdefg,def)

为什么$(if ...)条件为真时语法检查失败,因为它实际上是空的?

请注意,虚拟目标all中的echo命令前面有一个制表符,而不是四个空格。我正在运行GNU make 4.1.90 built for Windows32,似乎没有更新版本的GNU make。我正在寻找可以帮助我使用GNU make 4.1.90

的任何答案

2 个答案:

答案 0 :(得分:1)

我不确定为什么年龄较大的make版本会在这里窒息,但是您可以使用这样一个$(eval )这样的版本:

define check_in_abcdefg
$(eval
  TMP := $$(shell echo abcdefg)
  ifeq ($$(findstring $$(1),$$(TMP)),)
      $$(error $$(1) not in $$(TMP))
  endif
)
endef

$(call check_in_abcdefg,def)

all:
        @echo Hello, world!

答案 1 :(得分:1)

回答有关为什么GNU make 4.1会抛出此错误的问题:GNU make版本错误处理换行符。在您的示例中:

define check_in_abcdefg
$(eval TMP := $(shell echo abcdefg))
$(if $(findstring $(1),$(TMP)),,$(error $(1) not in $(TMP)))
endef

$(call check_in_abcdefg,def)

定义的宏的第一行(eval)扩展为空字符串,第二行(if)也是如此。因此,call扩展为单个换行符。

该版本的GNU make无法正确忽略此换行符,而是抛出错误。您可以通过删除换行符来更改您的makefile以适用于那些旧版本:

define check_in_abcdefg
$(eval TMP := $(shell echo abcdefg))$(if $(findstring $(1),$(TMP)),,$(error $(1) not in $(TMP)))
endef

$(call check_in_abcdefg,def)