bugmake - Bugs: bug #54727, foreach variable is not visible...

 
 

bug #54727: foreach variable is not visible for a target specific variable definition in a recipe

Submitted by:  Michael Builov <mbuilov>
Submitted on:  Tue 25 Sep 2018 02:48:25 PM UTC  
 
Severity:  3 - Normal Item Group:  Enhancement
Status:  None Privacy:  Public
Assigned to:  None Open/Closed:  Open
Component Version:  4.2.1 Operating System:  Any
Fixed Release:  None Triage Status:  None

Add a New Comment (Rich Markup)
   

You are not logged in

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

 

Fri 05 Oct 2018 04:38:55 PM UTC, comment #4: 

The first version of the patch is not good, make hangs on this test:

$ echo '$(eval all: M:=$$(eval all: Q:=$$$$(eval all: T:=$$$$M)))' | ./make -f -

The second version of the patch takes into account that the target-specific context may already be in the chain.

(file #45151)

Michael Builov <mbuilov>
Thu 04 Oct 2018 01:52:41 PM UTC, comment #3: 

It also possible to step on this "foreach + eval" bug not in a recipe.

Please consider the next example:

############
# define global variable
f := g

# function for defining target-specific variables
# $1 - target
# $2 - variable
def_target_specific = $(foreach f,1,$(eval $1: $2:=$$f))

# calling in global context: M=1
$(call def_target_specific,target_X,M)

# calling in target-specific context: M=g
all: TMP := $(call def_target_specific,target_Y,M)

all: target_X target_Y
target_X target_Y:; $(info $@: M=$M)
############

result:

target_X: M=1
target_Y: M=g

As we can see, the variable M has different values for target_X and target_Y, which is not expected.

Outer foreach variables cannot be used inside the eval context, if the call comes from a target-specific variable definition.

Michael Builov <mbuilov>
Wed 26 Sep 2018 11:47:03 AM UTC, comment #2: 

> By the time we expand the recipe all target-specific variables for that recipe have already been assigned: it's not possible for the recipe to add more target-specific variables to it's target and have those take effect.


But this is works:

$ echo 'all:; $(eval $$@: x:=1)$(info $x)' | make -f -

result:
1

To ensure that the real target-specific variable is being used, please try the following makefile:

######
x:=g
all: a b
a:; $(eval $$@: x:=t)$(info $@: $x)
b:; $(info $@: $x)
######

result:
a: t
b: g

> If you try to define a new target inside a recipe you'll get a fatal error.


Yes, it is expected, and I fully agree with this behavior.

$ echo 'all:; $(eval x:)' | make -f -

result:
'*** prerequisites cannot be defined in recipes.  Stop.'

--------

Creating/assigning values to the target-specific variables in the recipes can be used to avoid pollution of the global namespace.

Let's look at an example of a rule that generates several files ('b' and 'c') at once (it can be GNU bison).

######
all: a b c
a: b c
a: done:=
b c:; $(if $(done),,$(eval a: done:=1)touch b c)
######

The command to generate the 'b' and 'c' files will only be executed once, even if make is run with the -j option.

Michael Builov <mbuilov>
Tue 25 Sep 2018 03:57:52 PM UTC, comment #1: 

This will definitely never work.  By the time we expand the recipe all target-specific variables for that recipe have already been assigned: it's not possible for the recipe to add more target-specific variables to it's target and have those take effect.

If you try to define a new target inside a recipe you'll get a fatal error.  I'm not sure how hard it would be to know whether you're defining a new target-specific variable for the current target inside it's recipe and generate an error or warning.

I'll leave this open as an enhancement request to get better messaging around this situation.

Paul D. Smith <psmith>
Project Administrator
Tue 25 Sep 2018 02:48:25 PM UTC, original submission:  

Very similar to bug #11913, but now target-specific variable is defined in a recipe:

echo 'all:;$(foreach x,1,$(eval all: K:=$$(info "$$x")))' | make -f -

result:
""

expecting:
"1"

Defining global (not a target-specific) variable in a recipe works as expected:

echo 'all:;$(foreach x,1,$(eval K:=$$(info "$$x")))' | make -f -

result:
"1"

Michael Builov <mbuilov>

 

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

Attach Files:
   
   
Comment:
   

Attached Files
file #45151:  make_bug_54727_2.patch added by mbuilov (2KiB - application/octet-stream)
file #45148:  make_bug_54727.patch added by mbuilov (892B - application/octet-stream - patch over make-4.2.1)

 

Depends on the following items: None found

Items that depend on this one: None found

 

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

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

    Only logged-in users can vote.

     

     

     

    Follow 3 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2018-10-05 mbuilov Attached File- => Added make_bug_54727_2.patch, #45151
    2018-10-05 mbuilov Attached File- => Added make_bug_54727.patch, #45148
    2018-09-25 psmith Item GroupBug => Enhancement

    Back to the top


    Powered by Savane 3.5