bugmake - Bugs: bug #44308, combination of $(call ...) and...

 
 

bug #44308: combination of $(call ...) and $(value ...) functions

Submitted by:  Alex Maystrenko <technic93>
Submitted on:  Thu Feb 19 11:35:05 2015  
 
Severity: 3 - NormalItem Group: Enhancement
Status: NonePrivacy: Public
Assigned to: NoneOpen/Closed: Open
Component Version: 4.0Operating System: POSIX-Based
Fixed Release: NoneTriage Status: None

Add a New Comment (Rich MarkupRich Markup):
   

You are not logged in

Please log in, so followups can be emailed to you.

 

Sun Feb 22 18:42:48 2015, comment #4:

Your example reminded me similar constructions I use a lot in my own Makefiles.

I use a technique which I call the eval/value style which allows me to generate parametric Make code without having to deal with annoying levels of $ quoting.

Here's how I would write your example:
{{{

code = $(eval $(value code.mk))

define code.mk
x_$1 = some value
y_$1 = $(x_$1) append value
echo-$1: 1 := $1
echo-$1:
@echo x = $(x_$1)
@echo y = $(y_$1)
endef
$(call code,foo)
$(call code,bar)
all: echo-foo echo-bar

}}}

It then works as you expected.

Well, I actually won't recommend the `1 := $1` hack, use rather some expressive name here ;-)

A better example:
{{{

x_foo = some FOO value
x_bar = some BAR value

code = $(eval $(value code.mk))

define code.mk
y_$1 = $(x_$(param)) append value
echo-$1: param := $1
echo-$1:
@echo x = $(x_$(param))
@echo y = $(y_$(param))
endef

$(call code,foo)
$(call code,bar)
all: echo-bar

}}}

Gives:
{{{
$ make all
x = some FOO value
y = some FOO value append value
x = some BAR value
y = some BAR value append value
}}}

That being said, you have to be extra careful about where you place your numerical parameters.
If you don't want to rely on the fact that your `$(y_$1)` variable gets only used within rules where `$(param)` is defined, then you should use an `:=` assignment (e.g. `y_$1 := $(x_$1) append value`).

So having a special kind of variable which would expand only the numerical parameters like Paul suggested would avoid the need to think too hard about what happens when that code is executed, as the parameters would no longer be there at this point.

Since these variables would probably only be useful when defining Make code, it wouldn't be a big limitation to reserve them to multiline variable definition, something like:

{{{
defmacro code
x_$1 = some value
y_$1 = $(x_$1) append value
echo-$1:
@echo x = $(x_$1)
@echo y = $(y_$1)
endef
$(call code,foo)
$(call code,bar)
all: echo-foo echo-bar
}}}

Christian Boos <cboos>
Sat Feb 21 22:02:16 2015, comment #3:

You should also consider multiple digits like $(10), $(11), etc. Could happen.

Yes, a switch in the C code. Not a big deal.

Definitely there's no possible way we can make a backward-incompatible change. Whatever solution was found, would HAVE TO be backward-compatible (so existing macros worked the same way). The new-style expansion macros would have to be marked in some way... that's the tricky part.

Paul D. Smith <psmith>
Project Administrator
Fri Feb 20 22:30:16 2015, comment #2:

1. ${1} and $(1) - it is possible
2. "switch" in C code or where?

3. Yes it is hard. I think it is better to leave both function so old style and new style variables would be possible.

Alex Maystrenko <technic93>
Fri Feb 20 19:29:41 2015, comment #1:

This is an interesting idea. I have the following concerns:

A small one: you should handle ${1} and $(1) as well as simple $1 (etc.) Also you'll probably get measurable speedup using switch statements instead of if/else, for any makefile that uses this function extensively.

A larger one: it forces an unpleasant co-dependency between the way you write the variable and which function you use to expand it. In other words, if you take a variable written to be used with $(call ...) and invoke it with $(callv ...) instead, it will break. Similarly if you take a variable written to be used with $(callv ...) and invoke it with $(call ...) instead, it will break. I don't like that: too much action at a distance and opportunities for breakage.

It seems like it would be better to figure out a way to make the method of expansion be a feature of the variable, rather than of the function used, so that using $(call ...) would do the right thing on both "styles" of function definition. However I admit that offhand I'm not coming up with a nice way to do this. And of course this would require changes to base GNU make; it can't be done with just custom function creation.

Hm.

Paul D. Smith <psmith>
Project Administrator
Thu Feb 19 11:35:05 2015, original submission:

There is a well-known make feature. If you want to define some piece of code to call it with different parameters, for example:

define code
x_$1 = some value
y_$1 = $(x_$1) append value
do-$1:
@echo x = $(x_$1)
@echo y = $(y_$1)
endef
$(eval $(call code,foo))
$(eval $(call code,bar))
all: echo-foo echo-bar

You can't do it like this, you must escape evaluation during $(call ...) and type $$(x_$1) and $$(y_$1) instead. I don't think this is cool I've seen Makefiles with four or five dollars in a row.

So since make 4.x added support for writing custom functions I've add $(callv ...) and I want to share it with you:

https://github.com/technic/make-callv

usage: $(callv var,x1,x2,...,x9)
It simply calls $(value var) and than replaces $1,$2,...,$9 with x1,x2,...x9 properly. But $$1 stays untouched.

Alex Maystrenko <technic93>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach File(s):
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -unavailable- added by cboos (Posted a comment)
  • -unavailable- added by psmith (Posted a comment)
  • -unavailable- added by technic93 (Submitted the item)
  •  

    Do you think this task is very important?
    If so, you can click here to add your encouragement to it.
    This task has 0 encouragements so far.

    Only logged-in users can vote.

     

    Please enter the title of George Orwell's famous dystopian book (it's a date):

     

     

    No Changes Have Been Made to This Item

    Back to the top


    Powered by Savane 3.1-cleanup1