[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 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 could definately be clearer about it.

Thanks again for your help,

-----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

        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.


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

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).


Philip Guenther

This e-mail and its contents are subject to the DISCLAIMER at

reply via email to

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