bugmake - Bugs: bug #28456, Expansion of $$< is incorrect

 
 

bug #28456: Expansion of $$< is incorrect

Submitter:  Ian Lynagh <igloo>
Submitted:  Fri 01 Jan 2010 01:37:37 AM UTC
   
 
Severity:  3 - Normal Item Group:  Bug
Status:  Fixed Privacy:  Public
Assigned to:  None Open/Closed:  Closed
Component Version:  3.81 Operating System:  Any
Fixed Release:  4.3 Triage Status:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Mon 02 Jan 2023 07:29:04 PM UTC, comment #9: 

The fix for the target value appearing in $< is in GNU make 4.3.

I believe that the manual documentation of these variables is correct as of GNU make 4.4, although the behavior is not what some here are asking for: we don't recompute prerequisite variables after each word is expanded, we only recompute when a new rule is encountered.  So this:

.SECONDEXPANSION:
foo.2: foo.1 $$(info [$$<] [$$@]) ; : $@ Success

gives a result of:

[] [foo.2]
: foo.2 Success

(the value of $$< is empty) while this:

.SECONDEXPANSION:
foo.2: foo.1
foo.2: $$(info [$$<] [$$@]) ; : $@ Success

gives a result of:

[foo.1] [foo.2]
: foo.2 Success

(the value if $$< is foo.1 because it was in a previous rule)

Paul D. Smith <psmith>
Group administrator
Sat 13 Jul 2019 05:05:02 PM UTC, comment #8: 

Thanks for that fix Mike.  I've applied it.  I rewrote the tests somewhat to be a bit more specific.

As for the rest of these problems, there are real issues here which are not easily solved.  The only way to make something like this:


foo: bar $$(info $$<)


work properly would be for the automatic variables to be re-assigned anew before every expansion.  And for implicit rules like this:


%.x : %.y $$(info $$<) ; ...


it's more complicated, because we can't know what the right value of $$< is until after we've expanded the pattern.

And for things like $$^ it's even more complex, because the value cannot be complete until after the expansion.  Using info is a bit misleading because it prints values while expanding to nothing, but in real use the variables would be used to add more prerequisites.

Also, some of the manual is just wrong :-/.

Paul D. Smith <psmith>
Group administrator
Fri 12 Jul 2019 02:55:46 AM UTC, comment #7: 

I've encountered this inconsistency when trying to use secondary expansion. When a default rule is not defined, any rule without a recipe has $< overridden with $@. I've added a patch that avoids comparing null file commands and a regression test.

(file #47201, file #47202)

Mike Haboustak <haboustak>
Thu 02 Nov 2017 04:51:38 PM UTC, comment #6: 

The handling of $< under SECONDEXPANSION seems well broken as of 4.2.1.

With an implicit rule:


    $ cat Makefile
    .SECONDEXPANSION:
    %.2: %.1 $$(info [$$<] [$$@]) ; : $@ Success

    $ ls
    foo.1 Makefile

    $ make foo.2
    [foo.2] [foo.2]
    : foo.2 Success


Notice that $< expands to the target rather than a pre-requisite (!).

The situation for explicit rules is arguably worse:


    $ cat Makefile
    .SECONDEXPANSION:
    foo.2: %.2: %.1 $$(info [$$<] [$$@]) ; : $@ Success

    $ ls
    foo.1 Makefile

    $ make foo.2
    [] [foo.2]
    : foo.2 Success


$< is now empty. Can't find any syntax to change this.

Current cygwin make BTW


    $ make --version
    GNU Make 4.2.1
    Built for x86_64-unknown-cygwin
    Copyright (C) 1988-2016 Free Software Foundation, Inc.


Robert Bogomip <bobbogo>
Sat 16 Oct 2010 03:06:50 AM UTC, comment #5: 

I'm confirming the bug on a Ubuntu 9.10 i386 host.

Curiously, this particular bug also triggers circular dependencies. More surprising, the test case is simply the snippet found straight in the info page (make.info, section 3.10, "Secondary Expansion of Implicit Rules").

The snippet is (blank lines ommited):

.SECONDEXPANSION:
foo: bar
foo foz: fo%: bo%
%oo: $$< $$^ $$+ $$*

One might have to "touch bar boo f" before running make. The output is:

make: Circular foo <- foo dependency dropped.

I hope this example will draw more attention to the issue.

Cheers,
Alek

Anonymous
Mon 20 Sep 2010 05:43:06 PM UTC, comment #4: 

See also duplicate bug #31087

Paul D. Smith <psmith>
Group administrator
Wed 10 Feb 2010 04:34:42 PM UTC, comment #3: 

Update:

It seems current make behaviour is inconsisten with its manual. I quote `Secondary Expansion of Implicit Rules':

"""
As `make' searches for an implicit rule, it substitutes the stem and
then performs secondary expansion for every rule with a matching target
pattern.  The value of the automatic variables is derived in the same
fashion as for static pattern rules.  As an example:

     .SECONDEXPANSION:

     foo: bar

     foo foz: fo%: bo%

     %oo: $$< $$^ $$+ $$*

   When the implicit rule is tried for target `foo', `$$<' expands to
`bar', `$$^' expands to `bar boo', `$$+' also expands to `bar boo', and
`$$*' expands to `f'.
"""

So let's verify that:

$ cat se-manual.mk
.SECONDEXPANSION:

foo: bar

foo foz: fo%: bo%

show-vars = \
        $(info $$@ : $@)        \
        $(info $$< : $<)        \
        $(info $$^ : $^)        \
        $(info $$+ : $+)        \
        $(info $$* : $*)        \


%oo: $$(show-vars)
        touch $@


$ touch bar && make -f se-manual.mk foo
$@ : foo
$< : foo
$^ : bar boo
$+ : bar boo
$* : f
$@ : boo
$< : boo
$^ :
$+ :
$* : b
touch foo


Take a closer look to first 5 output lines starting with `$@ : foo'. The manual says "When the implicit rule is tried for
target `foo', `$$<' expands to `bar', `$$^' expands to `bar
boo', `$$+' also expands to `bar boo', and `$$*' expands to `f'"

But it seems we have $$< = foo (!= bar).


Could please anyone clarify, what is the right behaviour and how (if whether) we need to fix it.

Thanks beforehand,
Kirill

Kirill Smelkov <kirr>
Wed 10 Feb 2010 04:16:04 PM UTC, comment #2: 

Update:

$$< gets the same value as $$@ because of the following code fragment in commands.c:

   if (file->cmds == default_file->cmds)
     /* This file got its commands from .DEFAULT.
        In this case $< is the same as $@.  */
     less = at;


With the following patch ...

diff --git a/commands.c b/commands.c
index 6c941f2..992b206 100644
--- a/commands.c
+++ b/commands.c
@@ -144,10 +144,12 @@ set_file_variables (struct file *file)
         break;
       }
 
+#if 0
   if (file->cmds == default_file->cmds)
     /* This file got its commands from .DEFAULT.
        In this case $< is the same as $@.  */
     less = at;
+#endif
 
 #define        DEFINE_VARIABLE(name, len, value) \
   (void) define_variable_for_file (name,len,value,o_automatic,0,file)


... I'm getting following results ($* was obvisouly added to the testcase):

$ touch 1.c && ../make -f bug-28456.mk 1.o
$@ : 1.o
$< :
$^ :
$+ :
$? :
$* : 1
--------
$@ : 1.o
$< : 1.c
$^ : 1.c
$+ : 1.c
$? : 1.c
$* : 1


Now we see that only target name $@ and stem $* are set. Only $* is explicitely set in implicit.c:pattern_search() it seems:

              /* Update the stem value in $* for this rule.  */
              else if (!file_variables_set)
                {
                  define_variable_for_file (
                    "*", 1, file->stem, o_automatic, 0, file);
                  file_variables_set = 1;
                }


Now the questions are:

 1. is it expected behaviour that $^ $+ $? are always empty on
    second expansion? and,

 2. is it expected behaviour that $< is getting $@ for some
    on second expansion for implicit rules like this?


Thanks beforehand,
Kirill

Kirill Smelkov <kirr>
Wed 10 Feb 2010 12:53:29 PM UTC, comment #1: 

I think I was also beaten by this. Consider:

---- 8< ----

$ cat bug-28456.mk
.SUFFIXES:

all     : 1.o

show-vars = \
        $(info $$@ : $@)        \
        $(info $$< : $<)        \
        $(info $$^ : $^)        \
        $(info $$+ : $+)        \
        $(info $$? : $?)        \


.SECONDEXPANSION:

%.o : %.c $$(show-vars)
        $(info --------)
        $(show-vars)
        $(CC) $(CFLAGS) -o $@ -c $<


$ touch 1.c && make -f bug-28456.mk
$@ : 1.o
$< : 1.o
$^ :
$+ :
$? :
--------
$@ : 1.o
$< : 1.c
$^ : 1.c
$+ : 1.c
$? : 1.c
cc  -o 1.o -c 1.c

---- 8< ----


So as you can see $$< is wrongly second-expanded to 1.o (instead of 1.c), and $$^, $$+, $$? are second-expanded to empty strings (instead of 1.c too).

Tested on make 3.81 and latest CVS (3.81.90; last commit on Fri Dec 11 15:55:16 2009 +0000 by eliz)


Thanks beforehand,
Kirill

Kirill Smelkov <kirr>
Fri 01 Jan 2010 01:37:37 AM UTC, original submission:  


I was trying out the example in the "Secondary Expansion" part of the manual, and the expansion of $$< seems to be wrong in both 3.81 and CVS. For example, this Makefile:


.SECONDEXPANSION:

foo: bar q$$<

%:
        @echo This is the general rule for $@ with deps $^


Gives this output:


$ make foo
This is the general rule for bar with deps
This is the general rule for qfoo with deps
This is the general rule for foo with deps bar qfoo


i.e. $$< appears to have been expanded to "foo", whereas I would expect it to be expanded to the empty string.

Ian Lynagh <igloo>

 

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

Attach Files:
   
   
Comment:
   

Attached Files
file #47200:  se_default.mk added by haboustak (140B - text/x-makefile - Makefile that reproduces the incorrect $< value)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by haboustak (Updated the item)
  • -email is unavailable- added by bobbogo (Posted a comment)
  • -email is unavailable- added by psmith (Posted a comment)
  • -email is unavailable- added by kirr (Posted a comment)
  • -email is unavailable- added by igloo (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.

     

    Follow 6 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2023-01-02 psmith StatusNone Fixed
        Open/ClosedOpen Closed
        Fixed ReleaseNone 4.3
    2019-07-12 haboustak Attached File- Added 0001-Don-t-override-when-no-default-rule-has-been-defined.patch, #47201
        Attached File- Added 0002-Add-regression-test-for-default-rule-override.patch, #47202
    2019-07-12 haboustak Attached File- Added se_default.mk, #47200

    Back to the top

    Powered by Savane 3.13-758e.
    Corresponding source code