Calling functions to define make rules.

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Calling functions to define make rules.

Brian Cowan
All,

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:

----------------------------------------------
filelist1 = a b c d e f g h i j k l
filelist2 = aa bb cc dd ee ff gg hh ii jj kk ll
filelist3 = aaa bbb ccc ddd eee fff ggg hhh iii jjj kkk lll

define hope
$(1):
        echo $(0) $(1) make file call command

endef

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

$(foreach z,filelist1 filelist2 filelist3, $(info $(z)))

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

all: $(filelist1) $(filelist2) $(filelist3)
----------------------------------------------

When I call it using clearmake's GNU make emulation . I get make output
that shows that it is "building" all 36 "targets."

When I use GNU make 3.73, 3.78.1, or 4.2.1 (the latter under Cygwin) I get
this:
Brian@HugeLaptop /cygdrive/c/Users/Brian
$ make -f makefile.call.txt all
filelist1
filelist2
filelist3
makefile.call.txt:15: *** multiple target patterns.  Stop.

So, my question is: What, if anything, am I doing wrong here? Yes, this is
an INCREDIBLY stilted example. The actual makefile setup is horrifyingly
complex, and this is the first part I'm trying to wrap my skull around.

=============================================================
Brian Cowan
ClearCase/Licensing Software Advisory Team (SWAT)
HCL Technologies at IBM
IBM Cloud Support
550 King St
Littleton MA 01460

Phone: +1 978 899 5436
_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make
Reply | Threaded
Open this post in threaded view
|

Re: Calling functions to define make rules.

Paul Smith-20
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.

_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make
Reply | Threaded
Open this post in threaded view
|

Re: Calling functions to define make rules.

Brian Cowan
$(eval...) did the trick. Once I used that, I found that it worked the
same on both makes -- creating build scripts...

One more layer understood. Thanks!

=============================================================
Brian Cowan
ClearCase/Licensing Software Advisory Team (SWAT)
HCL Technologies at IBM
IBM Cloud Support
550 King St
Littleton MA 01460

Phone: +1 978 899 5436




From:   Paul Smith <[hidden email]>
To:     Brian Cowan/US/HCL/IDE@IBMUS, [hidden email]
Date:   10/10/2016 03:48 PM
Subject:        Re: Calling functions to define make rules.



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.



_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make