[Top][All Lists]

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

Re: Difficulties from the combination of functions "call" and "eval"

From: Philip Guenther
Subject: Re: Difficulties from the combination of functions "call" and "eval"
Date: Sun, 18 Jan 2015 00:55:36 -0800

On Sat, Jan 17, 2015 at 11:11 PM, SF Markus Elfring
<address@hidden> wrote:
>> So that $(eval $(call GIBBERISH)) is wrong.  Exactly *how* it's wrong
>> depends on what the $(call) is supposed to return.  Currently you're
>> evaling something that doesn't look like a *STANDALONE* chunk of
>> Makefile, which results in the error *in the eval*.
> I have added another tab character to a multi-line variable definition
> which should be called for a specific evaluation.
> Now I get a bit of more "progress indication" from a different error message.

You're just trying random stuff and not paying attention!  Stop and
*think*!  $(eval) takes as its argument a *CHUNK OF STANDALONE
MAKEFILE*: a variable assignment, and rule w/ or w/o recipe, an
export, a define, and if/endif block, etc.


> Would you like to give further hints (or advices) for another excerpt
> from this build script?
> Lines 183 - 203:
>         for part in $(1); do \
> if test "x$$(< $$part)" != "x0"; then \
> $(PRINTF) "$$(TEXT3)" '$$part'; \
> exit 12; \
> fi; \
> done \
> && $$(TOUCH) '$(2)'
> endef

That looks like it expands to shell text when used with $(call), so
just call it in a recipe!

> @$(RM) '$(1)'
>         $(file >$(2)) \
> $(file >>$(2),for task in $$($(SEQ) $(PARALLEL_MAXIMUM) -1 0); \
> do $(MAKE) -f $(3) -j1 index=$$task &; \
> done) \
> $(file >>$(2),wait)
>         @cat '$(2)'
>         $$SHELL '$(2)'
>         $(eval $(call RESULT_CHECK,$(4),$(1)))
> endef

Why are you using $(eval) there?  Think: what does $(call
RESULT_CHECK,$4,$1) expand to?  Would that expansion be a valid
Makefile if you put it in its own file?  No?  It's just _part_ of a
recipe?  Then $(eval) is the Wrong Thing.

Frankly, this entire HANDLE_BACKGROUND_TASK mess seems like it's at
the wrong level.  Either you should be letting the toplevel make
handle the parallelism by expressing this all with targets and
dependencies, or push it to the shell level and just have each recipe
start with a macro that expands to a canned block of shell that
figures out whether its the first call and forks the background stuff
then.  Or even wrap make in a shell script that does the imperative
background stuff before starting make with a Makefile that doesn't
have that insanity?

Make is itself a declarative language; forcing it into an imperative
style is just going to give you ulcers, or more likely, give ulcers to
your co-worker or co-maintainer or the six-months-from-now version of
you, when they/you have to figure out how this Makefile works.  To
quote Brian Kernighan: "Everyone knows that debugging is twice as hard
as writing a program in the first place. So if you're as clever as you
can be when you write it, how will you ever debug it?"

Philip Guenther

reply via email to

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