bug-make
[Top][All Lists]

## Re: Recursive \$(call)

 From: Paul D. Smith Subject: Re: Recursive \$(call) Date: Mon, 25 Feb 2002 23:22:23 -0500

```%% Philip Guenther <address@hidden> writes:

pg> It would greatly increase the expressiveness of GNU make's macro
pg> expansion if it was possible to define recursive macro functions.
pg> For example, here's a function that performs calculates the
pg> transitive closure of a set of dependencies:

pg> # If \$(firstword) is car, this is cdr:
pg> rest = \$(wordlist 1,\$(words \${1}),\${1})

pg> tclose = \$(if \${1},\$(firstword \${1}) \
pg>              \$(call tclose,\$(sort \${DEP_\$(firstword \${1})} \
pg>                              \$(call rest,\${1}))))

Heh.  I see your point, but I have to say that your example proves
exactly the amount of danger involved with allowing this: your
definition of "rest" has a bug which causes this series to loop
infinitely! :)

In wordlist, etc., words are numbered from one, not zero, so you really
want:

rest = \$(wordlist 2,\$(words \${1}),\${1})

otherwise your loop will never end.

pg> You could then define variables ala:

pg> DEP_foo = bar baz quux
pg> DEP_baz = quux blarp

pg> and expect \$(sort \$(call tclose,foo)) to expand to "bar baz blarp quux"

ITYM "bar baz blarp foo quux", right?
^^^

pg> Unfortunately, the restriction on recursive macros not referencing
pg> themselves includes references via \$(call).  I would argue that
pg> GNU make should not try to protect someone from themself if the
pg> write a recursive \$(call).  Yes, you can trivially write infinite
pg> loops if it's allowed, but the increase in expressiveness is
pg> substantial.

OK, I buy this argument.  As a test I removed the restriction on
recursive variable definitions and (with the above fix) your example
did work as you intended.  Neat.

However, I think the restriction is valid for normal variable
expansions, and most if not all builtin functions.  Are there any other
builtins you think would benefit from loosening this restriction?

I'll think about how this can be done correctly.

--
-------------------------------------------------------------------------------
Paul D. Smith <address@hidden>          Find some GNU make tips at:
http://www.gnu.org                      http://www.paulandlesley.org/gmake/