[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: define issues
From: |
Appleton, R. (Rick) |
Subject: |
RE: define issues |
Date: |
Tue, 17 Mar 2009 09:01:01 +0100 |
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:address@hidden]
Sent: Tue 3/17/2009 12:47 AM
To: Appleton, R. (Rick)
Cc: address@hidden
Subject: Re: define issues
2009/3/16 Appleton, R. (Rick) <address@hidden>:
> 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 $(address@hidden) -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