Reputation: 209
What is the problem with the dep2 function in the sample code below?
dep1 = $(eval makefile_list_$1 := $(MAKEFILE_LIST))$(eval -include $1.mk)$(eval MAKEFILE_LIST := $(makefile_list_$1))
define dep2
$(eval makefile_list_$1 := $(MAKEFILE_LIST))
$(eval -include $1.mk)
$(eval MAKEFILE_LIST := $(makefile_list_$1))
endef
$(call dep1,test)
$(call dep2,test)
.DEFAULT_TARGET: all
.PHONY: all
all:
@echo $@
GNU make 3.81 and 3.82 produce Makefile:10: *** missing separator. Stop.
which points to the dep2 call, dep1 is run without errors. The only difference between the two variants is the newlines in dep2 (and the whole point why I'd like to use define).
Upvotes: 20
Views: 25647
Reputation: 11
You can do as the below line to kill the error:
FOO := $(call dep2, test)
I guess the reason is the early version of gcc (3.8.1/2) can only accept nothing as the return of expression.
eg $(info string)
returns nothing, but $(call dep2, test)
returns 2 newlines charaters.
Upvotes: 0
Reputation: 151401
I would move the $(eval ...)
calls outside of dep2
. By doing it this way, there's no need for semicolons in dep2
. This means doubling the $
signs of some expansions to avoid expansion being done too early. So:
define dep2
makefile_list_$1 := $$(MAKEFILE_LIST)
-include $1.mk
MAKEFILE_LIST := $$(makefile_list_$1)
endef
$(eval $(call dep2,test))
# Quick checks for testing, to be removed from the final code...
$(info $(makefile_list_test))
$(info $(MAKEFILE_LIST))
.DEFAULT_TARGET: all
.PHONY: all
all:
@echo $@
I've tested the code above and it works with Gnu Make 4.0. I would expect it to work back to Gnu Make 3.8x. The $(eval $(call ...))
pattern is what I always do to execute my custom functions, and I've used it for quite a while now.
Upvotes: 3
Reputation: 1
There is much that can be improved in what you are doing. For one thing you really want to factor the eval calls to a single call at the top.
Your particular problem, however, stems from not understanding that the multiline recursive string the make's define command uses never includes the lady new line. The most natural convention for writing evalable functions is
define Foo Line1 Line2
endef
You can look at the string eval is seeing and see what this does via the info command, e.g. $(info $(call Foo,x) $(call Foo,y)).
Upvotes: -1
Reputation: 99094
You forgot the =
:
define dep2 =
EDIT:
Put a semicolon at the end of each line. I've tested this and it works (in GNUMake 3.81).
define dep2
$(eval makefile_list_$1 := $(MAKEFILE_LIST));
$(eval -include $1.mk);
$(eval MAKEFILE_LIST := $(makefile_list_$1));
endef
Why these semicolons are necessary I don't know, but in the documentation define
seems to be used for multi-line "variables" only when defining sequences of shell commands to be used in recipes, not Make commands, so maybe the rules are a little different.
Upvotes: 11