On Sat, 2022-01-22 at 13:59 +0100, Gisle Vanem wrote: > define add_c_src> > VPATH += $(1) > C_SRC += $(addprefix $(1)/, $(2)) > $(info Number of 'C_SRC': $(words $(C_SRC))) > endef > > $(eval $(call add_c_src, frmts/ceos, ceosopen.c)) > $(eval $(call add_c_src, frmts/ceos2, ceos.c ceosrecipe.c ceossar.c)) > > # ... plus a lot more > > But I'm curious about how this gets expanded
It gets expanded identically to every other variable or function: left to right, but from the inside out. In this case you have two functions: $(info ...) and inside that you have $(call ...). Since $(call ...) is the inner function it's expanded first. That means the "first level" of expansion happens before eval is invoked, and the variable is simply expanded as a text string with no knowledge of makefile constructs. Replacing $(1), running the $(addprefix ..), AND RUNNING THE $(info ...) all happens here because these are all simple references. So the info is invoked by call before any of the variables are assigned (because the assign is done by eval), then the result of that expansion is handed to eval to evaluate. You can figure out what eval will see by replacing it with info, like this: $(info $(call add_c_src, frmts/ceos, ceosopen.c)) Now this will print the text that is passed to eval to be evaluated. You probably want to escape the non-argument references, so that call will not run them and instead they will be passed to eval: define add_c_src VPATH += $(1) C_SRC += $$(addprefix $(1)/, $(2)) $$(info Number of 'C_SRC': $$(words $$(C_SRC))) endef