Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Display the results of foreach / eval / call expansion

I'm trying to debug makefiles for a large project and I'm struggling define TEMPLATE/endef and foreach/eval/call constructs. In particular I think I'm having a hard time figuring out which variables I need to reference with $ and which I need to reference with $$.

I think would be easier for me to debug if I could see the actual results of the the eval/call expansion, before variable expansion.

For instance if we use the example in the eval documentation for gnu-make, we have the following makefile-fragment:

 PROGRAMS    = server client

 server_OBJS = server.o server_priv.o server_access.o
 server_LIBS = priv protocol

 client_OBJS = client.o client_api.o client_mem.o
 client_LIBS = protocol
...
 define PROGRAM_template =
  $(1): $$($(1)_OBJS) $$($(1)_LIBS:%=-l%)
  ALL_OBJS   += $$($(1)_OBJS)
 endef

 $(foreach prog,$(PROGRAMS),$(eval $(call PROGRAM_template,$(prog))))

I think this foreach should effectively expand to the following, before variable expansion:

server: $(server_OBJS) $(server_LIBS:%=-l%)
ALL_OBJS   += $(server_OBJS)

client: $(client_OBJS) $(client_LIBS:%=-l%)
ALL_OBJS   += $(client_OBJS)

I figured out the above expansion by hand (corrections welcome), but I'm looking for a general method to display this expansion for more complex examples. Does such a method exist?

I have looked into make -d and make -pn options, and as far as I can tell, I don't think either of these will provide this particular output.

I'm using make-3.81.

like image 562
Digital Trauma Avatar asked Oct 16 '13 20:10

Digital Trauma


2 Answers

Replace all your $(eval ...) calls with $(info ...). Actually if you're stuck with 3.81 you may have to use $(warning ...) and ignore the extra output, because I think $(info ...) might not have existed until version 3.82.

Anyway, writing:

$(foreach prog,$(PROGRAMS),$(info $(call PROGRAM_template,$(prog))))

(or warning) you'll see what make is parsing.

like image 89
MadScientist Avatar answered Nov 19 '22 08:11

MadScientist


I've written a macro to help with seeing the results of $(eval ...):

# This version prints out rules for debugging
#c = $(eval $(call $(strip $1),$(strip $2),$(strip $3),$(strip $4),$(strip $5),$(strip $6),$(strip $7),$(strip $8),$(strip $9))) $(info $(call $(strip $1),$(strip $2),$(strip $3),$(strip $4),$(strip $5),$(strip $6),$(strip $7),$(strip $8),$(strip $9)))

# This version is the production version
c = $(eval $(call $(strip $1),$(strip $2),$(strip $3),$(strip $4),$(strip $5),$(strip $6),$(strip $7),$(strip $8),$(strip $9)))

Use it like this:

$(call c,function,arg1,arg2,...)

To see what is being generated by eval, simply use the debugging version. I needed this instead of simply replacing $(eval ...) by $(info ...) because functionality later in the makefile depended on the results of the $(eval ...)

like image 1
user3324033 Avatar answered Nov 19 '22 06:11

user3324033