[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: define issues

From: Philip Guenther
Subject: Re: define issues
Date: Mon, 16 Mar 2009 16:47:16 -0700

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

reply via email to

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