bug-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bug #42215] secondexpansion interference


From: Patatti
Subject: [bug #42215] secondexpansion interference
Date: Sun, 27 Apr 2014 20:48:59 +0000
User-agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:28.0) Gecko/20100101 Firefox/28.0

URL:
  <http://savannah.gnu.org/bugs/?42215>

                 Summary: secondexpansion interference
                 Project: make
            Submitted by: patatti
            Submitted on: Sun 27 Apr 2014 04:48:58 PM EDT
                Severity: 3 - Normal
              Item Group: Bug
                  Status: None
                 Privacy: Public
             Assigned to: None
             Open/Closed: Open
         Discussion Lock: Any
       Component Version: 4.0
        Operating System: Any
           Fixed Release: None
           Triage Status: None

    _______________________________________________________

Details:

On Fri, 2014-04-25 at 16:08 -0400, Martin d'Anjou wrote:
> .SECONDEXPANSION:
> file_x  := f.q
> build_x := touch
>
> %.tcl: $(interference) $$(file_$$*)
>         $(build_$*) \
>   $@
>
> %.q: %.tcl
>         touch $@
>
> To run, first touch a few files so they exist:
> $ touch f.q file.txt
>
> Next, run make (this works):
> $ make x.tcl
> touch \
>   x.tcl
>
> Ok, clean up:
> $ rm x.tcl
>
> Now interfere with the process:
> $ make x.tcl interference=file.txt
> make x.tcl
> \
>   f.tcl
> make: f.tcl: Command not found
> make: *** [f.tcl] Error 127

I think there is a bug here but it's somewhat subtle, and not related to
memory issues at all.  I'm not sure why Philip is not seeing this behavior.

Here's what's happening:

In the "working" case, you ask for x.tcl to be built.  Because of
$(file_x), there is a prerequisite of f.q for this file.  f.q an be rebuilt
from f.tcl, but we can't use the %.tcl rule to build f.tcl since that would be
a pattern rule recursion (we're already using this pattern rule to build
x.tcl) so it's not allowed and we have no rule to build f.tcl.  Thus we have
no rule to build f.q, but since f.q already exists it's OK, then we build
x.tcl with $* set to "x" so $(build_$*) works as expected.  Here's some debug
output:

  Considering target file 'x.tcl'.
   File 'x.tcl' does not exist.
   Looking for an implicit rule for 'x.tcl'.
   Trying pattern rule with stem 'x'.
   Trying implicit prerequisite 'f.q'.
   Found an implicit rule for 'x.tcl'.
    Considering target file 'f.q'.
     Looking for an implicit rule for 'f.q'.
     Trying pattern rule with stem 'f'.
     Trying implicit prerequisite 'f.tcl'.
     Looking for a rule with intermediate file 'f.tcl'.
      Avoiding implicit rule recursion.
      Trying pattern rule with stem 'f'.
     Found an implicit rule for 'f.q'.
     Finished prerequisites of target file 'f.q'.
     Prerequisite 'f.tcl' of target 'f.q' does not exist.
    No need to remake target 'f.q'.
   Finished prerequisites of target file 'x.tcl'.
  Must remake target 'x.tcl'.


In the "non-working" case, you again ask for x.tcl to be built.  We depend on
file.txt (due to $(intermediate)) and make doesn't have a rule to build it but
it exists, so that's OK.  Then we try to build f.q and see it can be rebuilt
from f.tcl, as before.

Here's where the difference shows up.  f.tcl depends now on "file.txt" and
$(file_f) which is empty.  Make sees that this is a pattern rule recursion as
before, but for some reason the addition of the extra prerequisite "file.txt"
causes make to not throw away that rule; it still decides to try to build
f.tcl and because $(build_f) is not set, that fails.  Here's some debug
output:

  Considering target file 'x.tcl'.
   File 'x.tcl' does not exist.
   Looking for an implicit rule for 'x.tcl'.
   Trying pattern rule with stem 'x'.
   Trying implicit prerequisite 'file.txt'.
   Trying implicit prerequisite 'f.q'.
   Found an implicit rule for 'x.tcl'.
    Considering target file 'file.txt'.
     Looking for an implicit rule for 'file.txt'.
     No implicit rule found for 'file.txt'.
     Finished prerequisites of target file 'file.txt'.
    No need to remake target 'file.txt'.
    Considering target file 'f.q'.
     Looking for an implicit rule for 'f.q'.
     Trying pattern rule with stem 'f'.
     Trying implicit prerequisite 'f.tcl'.
     Looking for a rule with intermediate file 'f.tcl'.
      Avoiding implicit rule recursion.
      Trying pattern rule with stem 'f'.
      Trying implicit prerequisite 'file.txt'.
     Found an implicit rule for 'f.q'.
       Pruning file 'file.txt'.
     Considering target file 'f.tcl'.
      File 'f.tcl' does not exist.
       Pruning file 'file.txt'.
      Finished prerequisites of target file 'f.tcl'.
     Must remake target 'f.tcl'.
 <fails>

Note that even though we say "Avoiding implicit rule recursion" we still think
we found a rule to build f.tcl.

I think there's something wonky about implicit rule recursion and
secondary expansion.

As a workaround, define an explicit rule for it;
add:

  f.tcl: ;

and then it will work.





    _______________________________________________________

Reply to this item at:

  <http://savannah.gnu.org/bugs/?42215>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.gnu.org/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]