help-make
[Top][All Lists]
Advanced

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

Re: Calling functions to define make rules.


From: Paul Smith
Subject: Re: Calling functions to define make rules.
Date: Mon, 10 Oct 2016 15:48:09 -0400

On Mon, 2016-10-10 at 14:54 -0400, Brian Cowan wrote:
> I'm dealing with some odd behavior differences between make tools that are 
> supposed to be compatible with GNU make and need to know if this is a 
> valid construct in a makefile:

Since GNU make gives a syntax error, it's clearly not a valid construct
if by "valid" you mean results in a working make invocation :).

> define hope
> $(1):
>         echo $(0) $(1) make file call command
> 
> endef
> 
> hope1 = $(foreach x,$(value $(1)),$(call hope,$(x)))

This will definitely not do what you want to do.  Let's examine what happens.

> $(foreach z,filelist1 filelist2 filelist3, $(call hope1,$(z)))

So the first time through this list z is set to filelist1, so we get:

  $(call hope1,filelist1)

That expands to:

  $(foreach x,$(value filelist1),$(call hope,$(x)))

then:

  $(foreach x,a b c d e f h i j k l,$(call hope,$(x)))

The first time through this, x is set to a, so we have:

  $(call hope,a)

which expands to:

  a:\n\techo hope a make file call command

then we loop back around again and this time x is b.  We're still
expanding so the expansion of this is appended to the end of the
previous expansion, so we now have:

  a:\n\techo hope a make file call commandb:\n\techo hope b make file call 
command

The next time through we append the expansion of $(call hope,c):

  a:\n\techo hope a make file call commandb:\n\techo hope b make file call 
commandc:\n\techo hope c make file call command

etc.  You can see where this is going.  By the time you get done the
expansion will be one long logical string containing the entire
expansion of the various "hope" calls for each value in filelist1.  Then
make will try to parse that as a single logical line, and of course
that's a syntax error.

The important thing to understand is that GNU make is line-oriented, and
line splitting happens BEFORE expansion.  So after expansion is
complete, the entire result of the expansion will be considered by make
to be a single logical line, even if it contains newline characters
(they will be treated as whitespace, just like a space character).

This is why you need the eval function.  Eval will re-parse text as if
it were a make construct, re-running the line splitting.  You probably
want this:

  hope1 = $(foreach x,$(value $(1)),$(eval $(call hope,$(x))))

To learn more about this you might consider reading these blog posts:

  http://make.mad-scientist.net/category/metaprogramming/


> When I call it using clearmake's GNU make emulation

I haven't used clearmake in over 10 years but the last time I used it,
it had very anemic support for GNU make features.  Hopefully they've
improved it but you should examine the clearmake manual: there should be
a list of things that are and are not supported.



reply via email to

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