Thank you Philip for your response. I've been using this construct in a top-level Makefile for a non-recursive make system (inspired by http://blogs.designingpatterns.com/urban-jungle/category/build-systems/make-build-systems/). The example I posted was just me trying to get a better understanding of how the system could/would be used. After sending the mail I spent more time with the actual system (rather than the sample I posted), and got a better understanding of eval. This morning I was able to spot the error in the sample as well, so the time spent on the system has definately helped.
I do agree with you that the eval function is quite difficult to parse for someone new to it, and the manual (I've been using http://www.gnu.org/software/make/manual/make.html#Top) could definately be clearer about it. Thanks again for your help, Rick -----Original Message----- From: Philip Guenther [mailto:[email protected]] Sent: Tue 3/17/2009 12:47 AM To: Appleton, R. (Rick) Cc: [email protected] Subject: Re: define issues 2009/3/16 Appleton, R. (Rick) <[email protected]>: > I'm having issues using defines in a Makefile. > The following makefile: > > ===================== > PROGRAMS = server client > > .PHONY: all > all: $(PROGRAMS) > > server_LIBS := priv protocol > client_LIBS := protocol > > define PROGRAM_template > > $(1): > cc $($(1)_LIBS) -o $$@ > > endef > > $(foreach prog,$(PROGRAMS),$(eval $(call PROGRAM_template,$(prog)))) > ===================== > > generates this output > cc priv protocol -o server > cc protocol -o client Could you elaborate on why you choose to use $(eval) for that? I ask because 1) $(eval) has proven to be difficult for people to understand and reason about, and 2) the problem given can be solved without using $(eval): ----- PROGRAMS = server client .PHONY: all all: $(PROGRAMS) server_LIBS := priv protocol client_LIBS := protocol $(PROGRAMS): cc $($...@_libs) -o $@ ----- Practically all the uses of $(eval) that I've seen posted here have been buggy, unnecessary, or both. > yet the following file ... > generates this (unexpected) output > cc -o server > cc protocol -o client > > Does anyone have an idea why it might be doing this? Makes perfect sense to me. You just have to think about when the various variable references are being expanded (_before_ $(eval) is getting the text to evaluate, _during_ that evaluation, or _afterwards_ when the rule is being processed) versus when the various variable settings are actually being performed. <soapbox> Let me apologize in advance if my next statement appears to be a personal insult. It's not meant as such, as I hope I'll make clear. To be blunt, $(eval) should be relegated to the "EXPERTS ONLY" section of the manual...and if you don't understand what I meant by "before vs during vs afterwards", then you're not an expert and should not use it. This isn't meant to be a slam on you or the others that have tried to use $(eval) and been tripped up by how it works. I think $(eval) was not documented with enough warnings about how non-intuitive it is, so that it looks like a simple way for people to write more 'procedural' makefile. In my experience, most users are slightly uncomfortable with make's declarative operation, so the option to write a makefile as if it was a procedural language is seductive. The problem is that $(eval) was designed for the complex cases, where double expansion is critical, and not for the simple cases, where double expansion is a trap to drive users insane. Perhaps you get all the above and my mention of "before/during/afterwards" was all it took for you to see how to solve your problem. That good, but I strongly suggest you reconsider your use of $(eval) and whether it's actually necessary or just an attempt to jam make into a different paradigm of expression. Similarly, I suggest to the GNU make maintainers to think *real hard* about what they can do to ease the support burden that has been created by $(eval) being freely used by people that think it simpler than it is, perhaps starting with a pile of warnings and cookbook examples in the info pages...but I'll leave that to someone who actually likes $(eval). </soapbox> Philip Guenther This e-mail and its contents are subject to the DISCLAIMER at http://www.tno.nl/disclaimer/email.html
_______________________________________________ Help-make mailing list [email protected] http://lists.gnu.org/mailman/listinfo/help-make
