Finding second route through rules

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Finding second route through rules

Steven Simpson
Hi,

Just noticed a change in behaviour between 3.81 and 4.1:

%.foo: %.bar
        @echo from bar

%.foo: %.baz
        @echo from baz

%.baz: %.qux
        @echo from qux

%.bar: %.quux
        @echo from quux

gwonk: a.bar


So there is a route from a.quux -> a.bar -> a.foo, and from a.qux ->
a.baz -> a.foo.  The first is preferred, as implied by the ordering of
the first two rules, AIUI.

Create a.qux, and ensure no other a.* files exist, so the second route
ought to be chosen.  Then [make a.foo].

$ ls
a.qux  Makefile
$ make a.foo
from qux
from baz
$ make -v
GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program built for x86_64-pc-linux-gnu


So Make has chosen the second route, because the first is incomplete.



$ ls
a.qux  Makefile
$ make a.foo
make: *** No rule to make target 'a.bar', needed by 'a.foo'. Stop.
$ make -v
GNU Make 4.1
Built for x86_64-unknown-linux-gnu
Copyright (C) 1988-2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later<http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.


It seems that Make 4.1 is fixated on the first route, just because the
intermediate step a.bar is mentioned as a prerequisite.  Disable the
gwonk line, and it's fine again.

Just tried on the latest in git, and it is there too.

Is this intended?

Thanks,

Steven

_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make
Reply | Threaded
Open this post in threaded view
|

Re: Finding second route through rules

Steven Simpson
Hi!

Did this slip under the radar?

Thanks!

On 09/12/15 17:25, Steven Simpson wrote:

> Just noticed a change in behaviour between 3.81 and 4.1:
>
> %.foo: %.bar
>     @echo from bar
>
> %.foo: %.baz
>     @echo from baz
>
> %.baz: %.qux
>     @echo from qux
>
> %.bar: %.quux
>     @echo from quux
>
> gwonk: a.bar
>
>
> So there is a route from a.quux -> a.bar -> a.foo, and from a.qux ->
> a.baz -> a.foo.  The first is preferred, as implied by the ordering of
> the first two rules, AIUI.
>
> Create a.qux, and ensure no other a.* files exist, so the second route
> ought to be chosen.  Then [make a.foo].
>
> $ ls
> a.qux  Makefile
> $ make a.foo
> from qux
> from baz
> $ make -v
> GNU Make 3.81
> Copyright (C) 2006  Free Software Foundation, Inc.
> This is free software; see the source for copying conditions.
> There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
> PARTICULAR PURPOSE.
>
> This program built for x86_64-pc-linux-gnu
>
>
> So Make has chosen the second route, because the first is incomplete.
>
>
>
> $ ls
> a.qux  Makefile
> $ make a.foo
> make: *** No rule to make target 'a.bar', needed by 'a.foo'. Stop.
> $ make -v
> GNU Make 4.1
> Built for x86_64-unknown-linux-gnu
> Copyright (C) 1988-2014 Free Software Foundation, Inc.
> License GPLv3+: GNU GPL version 3 or
> later<http://gnu.org/licenses/gpl.html>
> This is free software: you are free to change and redistribute it.
> There is NO WARRANTY, to the extent permitted by law.
>
>
> It seems that Make 4.1 is fixated on the first route, just because the
> intermediate step a.bar is mentioned as a prerequisite. Disable the
> gwonk line, and it's fine again.
>
> Just tried on the latest in git, and it is there too.
>
> Is this intended?

_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make
Reply | Threaded
Open this post in threaded view
|

Re: Finding second route through rules

Luke T. Shumaker
Hi Steven,

I had to work through this several times to convince myself that this
wasn't a simple misunderstanding of trying to apply ≤3.81 pattern
rules in a post-3.82 world.

Having to keep track of the bar's, baz's, qu+x's didn't help either :)
Here is an "improved" makefile that I think demonstrates the situation
more clearly.

        default: a.foo
       
        %.foo: %.correct
                @echo $@ from $<
       
        %.foo: %.mislead
                @echo $@ from $<
       
        %.correct: %.correct_src
                @echo $@ from $<
       
        %.mislead: %.mislead_src
                @echo $@ from $<
       
        a.correct_src:
                @echo touch $@
       
        # Note that there is no rule to make a.mislead_src
       
        # If the misleading_target line is commented out, 'default' succeeds:
        # > a.correct from correct_src
        # > a.foo from a.correct
        # If the line isn't commented out, 'default' fails:
        # > make: *** No rule to make target 'a.mislead', needed by 'a.foo'.  Stop.
        misleading_target: a.mislead

Besides changing names, I also moved the "correct" branch up, to
remove the possibility that it was choosing the "mislead" branch
simply because it was listed first, which is what make does if
everything else ties.

I believe that this is a bug, but I'm not Paul.

Without looking at the source, this feels a lot like the
.DELETE_ON_ERROR: bug that was in either 3.81 or 3.82 (I can't
recall which).

--
Happy hacking,
~ Luke Shumaker
_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make
Reply | Threaded
Open this post in threaded view
|

Re: Finding second route through rules

Steven Simpson
Hi Luke,

On 01/02/16 21:29, Luke Shumaker wrote:
> Having to keep track of the bar's, baz's, qu+x's didn't help either :)

Sorry; I realised after posting that it might be a burden.

> Here is an "improved" makefile that I think demonstrates the situation
> more clearly.

[Snip an improved makefile]

> Besides changing names, I also moved the "correct" branch up, to
> remove the possibility that it was choosing the "mislead" branch
> simply because it was listed first, which is what make does if
> everything else ties.

I understood that it shouldn't matter anyway, because they're not
branches from the same point, i.e., they don't have the same target.

Cheers!

_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make
Reply | Threaded
Open this post in threaded view
|

Re: Finding second route through rules

Luke T. Shumaker
On Tue, 02 Feb 2016 06:56:19 -0500,
Steven Simpson wrote:
> > Besides changing names, I also moved the "correct" branch up, to
> > remove the possibility that it was choosing the "mislead" branch
> > simply because it was listed first, which is what make does if
> > everything else ties.
>
> I understood that it shouldn't matter anyway, because they're not
> branches from the same point, i.e., they don't have the same target.

You're right that it doesn't matter to Make, but it might matter to
humans trying to understand it :) I just wanted there to be one fewer
thing for someone looking at it to have to think about.

--
Happy hacking,
~ Luke Shumaker


_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make
Reply | Threaded
Open this post in threaded view
|

Re: Finding second route through rules

Steven Simpson
In reply to this post by Luke T. Shumaker
Hi again!

On 01/02/16 21:29, Luke Shumaker wrote:

> Here is an "improved" makefile that I think demonstrates the situation
> more clearly.
>
> default: a.foo
>
> %.foo: %.correct
> @echo $@ from $<
>
> %.foo: %.mislead
> @echo $@ from $<
>
> %.correct: %.correct_src
> @echo $@ from $<
>
> %.mislead: %.mislead_src
> @echo $@ from $<
>
> a.correct_src:
> @echo touch $@
>
> # Note that there is no rule to make a.mislead_src
>
> # If the misleading_target line is commented out, 'default' succeeds:
> # > a.correct from correct_src
> # > a.foo from a.correct
> # If the line isn't commented out, 'default' fails:
> # > make: *** No rule to make target 'a.mislead', needed by 'a.foo'.  Stop.
> misleading_target: a.mislead

> I had to work through this several times to convince myself that this
> wasn't a simple misunderstanding of trying to apply ≤3.81 pattern
> rules in a post-3.82 world.
> Without looking at the source, this feels a lot like the
> .DELETE_ON_ERROR: bug that was in either 3.81 or 3.82 (I can't
> recall which).

A little more info which might be pertinent...  In moving to a newer
Kubuntu (14.04 to 16.04), I've implicitly switched from GNU Make 3.81 to
4.1.  Having hit what is likely the same problem, I had to try out some
other versions.  Both the code I'm working on now and Luke's test above
manifest a problem in 3.82, 4.1 and 4.2.1, but not in 3.81.

Cheers,

Steven

_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make