GNU make 4.1: Missing separator when $(if ...) is true in a defined function

Viewed 789

I am trying to generate an error in a Makefile when a string is not found in the output of a shell command. The shell command depends on a parameter, therefore the whole thing is in a defined function. Here is a minimalist example:

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!

I would like this Makefile to output Hello, world! in this case, but I'd like it to output xyz not in abcdefg if I replace the call line with this one:

$(call check_in_abcdefg,xyz)

The problem is that with the def check I have this output:

Makefile:6: *** missing separator. Stop.

Where line 6 is $(call check_in_abcdefg,def)

Why does the syntax check fail when the $(if ...) condition is true since it's actually empty ?

Note that the echo command in the dummy target all is correctly preceded by a tab, not four spaces. I am running GNU make 4.1.90 built for Windows32, and it seems not to happen for newer version of GNU make. I am looking for any answer that could help me make it work with GNU make 4.1.90

2 Answers

I'm not sure why older make versions choke here, but you can make it work with one big $(eval ) like this:

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!

To answer the question about why GNU make 4.1 is throwing this error: that version of GNU make is mishandling the newline. In your example:

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

$(call check_in_abcdefg,def)

The first line of the defined macro (the eval) expands to the empty string, and so does the second line (the if). So, the call expands to a single newline character.

That version of GNU make is not correctly ignoring this newline character and instead throws an error. You can change your makefile to work in those older versions by removing the newline:

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

$(call check_in_abcdefg,def)
Related