bug-make
[Top][All Lists]
Advanced

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

Re: GNU make 4.2.93 release candidate available


From: John Marshall
Subject: Re: GNU make 4.2.93 release candidate available
Date: Mon, 13 Jan 2020 14:19:33 +0000

I am the OP whose seemingly innocuous bug report (40657) has led to this mess. 
Unfortunately I don't recall what I was doing back in 2013, but I suspect I had 
naively written a suffix rule with a prerequisite that didn't work as expected, 
noted that the documentation said something else again, filed a documentation 
buglet, and recoded my makefile some other way.

Having explored this further today, I now think the 4.2.1&prior behaviour is 
mostly sensible in producing both a target rule and a suffix rule, but less so 
in how it treats the prerequisite(s).

On 11 Jan 2020, at 16:12, Paul Smith <address@hidden> wrote:
> Martin had suggested some kind of warning or
> diagnostic be shown if a makefile contained an incorrectly-constructed
> suffix rule.  At the time I didn't think this would be a widespread problem
> so I didn't agree, but perhaps I was wrong.  It's a bit annoying that a
> warning would be generated for perfectly legitimate makefile (albeit
> confusing and _likely_ wrong).
> 
> I mean, it's not _illegal_ to have:
> 
>   .POSIX:
>   .SUFFIXES: .f .b
>   .f.b : prereq
> 
> it just means that ".f.b" is not a suffix rule, it's a real rule to build
> the literal target ".f.b".

The GNU Make 4.2.1&prior behaviour differs depending on whether the putative 
suffixes are listed in .SUFFIXES:

$ cat Makefile
.SUFFIXES:
.SUFFIXES: .one .two

.one.two: fred.txt
        cat $? > $@

.foo.rc: fred.txt
        cat $? > $@

make -p | grep -C5 'cat '
[snip]
%.two: %.one
#  recipe to execute (from 'Makefile', line 5):
        cat $? > $@
--
.foo.rc: fred.txt
#  Implicit rule search has not been done.
#  Modification time never checked.
#  File has not been updated.
#  recipe to execute (from 'Makefile', line 8):
        cat $? > $@
--
.one.two: fred.txt
#  Implicit rule search has not been done.
#  Modification time never checked.
#  File has not been updated.
#  recipe to execute (from 'Makefile', line 5):
        cat $? > $@

Thus as .foo and .rc are not in .SUFFIXES, Make has treated ".foo.rc: fred.txt" 
solely as an ordinary target rule. However it has considered that the .one.two 
rule could be either a suffix rule (with a non-POSIXly-blessed prerequisite) or 
a target rule, so Make has ingested it both ways (which is bogus but also very 
pragmatic!).

This means that a diagnostic could be produced when ingesting this both ways 
("warning: ignoring POSIX-prohibited prerequisite on suffix rule") but happily 
that would not be produced for legitimate target rule cases like .foo.rc. 
Hopefully most such initial-dot legitimate targets would have components that 
are not listed in .SUFFIXES so would escape the warning.

>>  .man.1: Makefile
>>          $(MANGEN) $< >$@
> 
> So it turns out to be even more bogus.  I re-read the bug and it turns out
> that the prerequisites here were ignored before.  So, these rules did not
> do at all what the author (presumably) intended.
[...]
> The only reason to use suffix rules is to be
> portable with other versions of make: if you're using GNU make then pattern
> rules are infinitely more flexible and usable.  And if there's no other
> reason to use suffix rules except to be portable then we shouldn't be
> implementing non-portable capabilities for it.

Agreed, so I did a little exploration of other makes.

For the Makefile above, OpenBSD's make (as shown by `make -p | grep -C5 'cat '` 
again) treats .one.two as a suffix rule (only) and .foo.rc as a target rule. 
However running the makefile shows that both rules have fred.txt as a 
prerequisite:

$ touch barney.one; rm fred.txt
$ make barney.two
make: don't know how to make fred.txt (prerequisite of: barney.two)
Stop in /home/johnm/test
$ make .foo.rc
make: don't know how to make fred.txt (prerequisite of: .foo.rc)
Stop in /home/johnm/test
$ touch fred.txt
$ make barney.two
cat barney.one fred.txt > barney.two
$ make .foo.rc
cat fred.txt > .foo.rc
$ make .one.two  # demonstrates not interpreted as a target rule
make: don't know how to make .one.two
Stop in /home/johnm/test

This suggests that OpenBSD's make in fact has an extension over POSIX in that 
it does treat Makefile as a prerequisite of %.1 in the .man.1 suffix rule 
quoted above.

It's unclear from Illumos's /usr/bin/make's -p output how it's treating the two 
rules. Running the makefile appears to show that it's treating .one.two as both 
a suffix rule (without a prerequisite) and a target rule (with the 
prerequisite):

$ touch barney.one; rm fred.txt
$ make barney.two
cat barney.one > barney.two
$ make .foo.rc
make: Fatal error: Don't know how to make target `fred.txt'
$ make .one.two
make: Fatal error: Don't know how to make target `fred.txt'
$ touch fred.txt
$ make .foo.rc
cat fred.txt > .foo.rc
$ make .one.two
cat fred.txt > .one.two

Illumos's /usr/xpg4/bin/make and /usr/bin/dmake behave similarly.

Presumably then Dennis's failing FreeBSD packages are all cases of "no rule to 
make foobar.1" as GNU Make 4.2.93 has removed the suffix rule interpretation of 
rules like ".man.1: Makefile", and these in fact work as intended in the BSDs' 
makes due to the extension observed above.

So it seems like there are three possible approaches:

(A) Revert to the 4.2.1&prior behaviour, and clarify the GNU Make documentation 
now that we understand what all's going on. Then these makefiles will work as 
expected when building from a clean directory (though will not rebuild foobar.1 
as intended when Makefile is touched).

(B) Consider the BSD make behaviour as sufficient precedent to implement an 
extension to POSIX to accept prerequisites on suffix rules (only in non-POSIX 
mode; when .POSIX is in the makefile, this should be a warning or even an error 
-- except that the Illumos/GNU precedent is to say "maybe this is a funny 
target name not a suffix rule"). Unfortunately this involves additional work.

(C) Revert to the 4.2.1&prior behaviour and add a warning ("ignoring 
prerequisite on suffix rule") as discussed. Then these makefiles will work as 
expected when building from a clean directory (though will not rebuild foobar.1 
as intended when Makefile is touched).

I didn't immediately find any motivation for forbidding prerequisites on 
inference rules in the POSIX description of make or in the Austin Group bug 
tracker.

If I were going to favour one of these options (without considering the work 
involved), it would be (B) silently accepting suffix rule prerequisites in 
non-POSIX mode for compatibility with BSD make, and in POSIX mode emitting a 
warning and one of accepting the prerequisite / ignoring the prerequisite / 
ingesting the rule as a target rule only.

Cheers (and apologies for the inconvenience!),

    John


reply via email to

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