Jeenu
Jeenu

Reputation: 2231

Missing separate error from makefile

With this Makefile, I'm not sure why I'm thrown a missing separator error.

define foo
$(eval a := $(1))
$(eval b := $(1))
endef

$(call foo,hello)

$(info $(a))
$(info $(b))

all: ;

If I however replaces the first eval with this,

$(eval a := $(1)) \

then the error goes away. eval expands to nothing, and it's happy with only one eval inside the define. But I'm not sure why it's complaining in this case, nor why the trailing back slash solves it.

Upvotes: 0

Views: 366

Answers (2)

MadScientist
MadScientist

Reputation: 100781

The call expansion results in a single newline (because, as you say, both the eval's expand to the empty string. When make tries to parse that, it doesn't understand it and throws this error.

The important thing to understand is that make will break the input into logical lines before it tries to run expansion. So after the expansion is complete, make expects to see a single line of output and it doesn't understand newlines existing in that single line.

Probably this could be handled better, if you wanted to file a bug at https://savannah.gnu.org/bugs/?func=additem&group=make

ETA Actually I checked and this has already been fixed in GNU make 4.2:

$ make-4.1
Makefile:5: *** missing separator.  Stop.

$ make-4.2
make: *** No targets.  Stop.

Upvotes: 1

Alexey Semenyuk
Alexey Semenyuk

Reputation: 704

define foo
$(eval a := $(1))
$(eval b := $(1))
endef

bar:=$(call foo,hello)

$(info $(a))
$(info $(b))
$(info bar=[$(bar)])

all: ;

Running this makefile outputs:

$ make -f Makefile.sample
hello
hello
bar=[
]
make: 'all' is up to date.

So $(foo) function outputs new line character. It should either output nothing or value should be captured in variable or trapped with $(eval) or $(strip).

$(eval a := $(1)) \ results in no new line output from $(foo) that is why it fixes the problem.

Alternatives to adding backslashes to your $(foo) are:

#1:

define fooBody
$(eval a := $(1))
$(eval b := $(1))
endef
foo = $(strip $(call fooBody,$1,$2))

#2

define fooBody
$(eval a := $(1))
$(eval b := $(1))
endef
foo = $(eval $(call fooBody,$1,$2))

#3

$(strip $(call foo,hello))

#4

$(eval $(call foo,hello))

#5

.:=$(call foo,hello)

My personal choice is #1.

Upvotes: 1

Related Questions