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

 
 

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

Submitter:  Alex Maystrenko <technic93>
Submitted:  Thu 19 Feb 2015 11:35:05 AM UTC
   
 
Severity:  3 - Normal Item Group:  Enhancement
Status:  None Privacy:  Public
Assigned to:  None Open/Closed:  Open
Component Version:  4.0 Operating System:  POSIX-Based
Fixed Release:  None Triage Status:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Sun 22 Feb 2015 06:42:48 PM UTC, 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 21 Feb 2015 10:02:16 PM UTC, 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>
Group administrator
Fri 20 Feb 2015 10:30:16 PM UTC, 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 20 Feb 2015 07:29:41 PM UTC, 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>
Group administrator
Thu 19 Feb 2015 11:35:05 AM UTC, 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 Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

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

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only logged-in users can vote.

     

    No changes have been made to this item

    Back to the top

    Powered by Savane 3.13-f8d8.
    Corresponding source code