help-make
[Top][All Lists]
Advanced

[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

reply via email to

[Prev in Thread] Current Thread [Next in Thread]