tech-toolchain archive

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

Re: make: avoid breaking backwards compatability



On Thu, 04 Sep 2014, Jarmo Jaakkola wrote:
So, why should subdir/foo.c be the file we're looking for?

Because that's the existing (old) behaviour, and people have come to expect it. Also, because it's useful to be also to say "this *.o file depends on that *.c file, but I don't want to write explicit commands for building it, I'd like to use the commands in the .c.o rule."

I have never seen it mentioned anywhere that a listed dependency should affect the implied source. I must admit that I have experience only from NetBSD's make, gmake and reading the POSIX standard.

Yes, the old behaviour that many of us expect seems to be undocumented.

Admittedly, gmake is a different implementation, but they do it "my way" too:

Whatever gmake does has little bearing on what people expect NetBSD's make to do.

And also admittedly, we're not slaves to POSIX, but this is exactly the same as the previously mentioned issue 10. In that issue the suffix of the source is also changed by the extra dependency, but it is still basically the same thing. It just happens to change the entire rule, not just the implied source!

   .SUFFIXES: .a .b .c
   .a.c: ; ...
   .b.c: ; ...
   test.c: test.b
   test.a:
   test.b:

.a.c should be used, not .b.c. This is completely within the realm of POSIX, and I think it would have been specified that the dependencies must affect the implied rule / source selection process, if it really should work like that.

I would expect the .b.c rule to be used, based on experience, not based on documentation or standards. POSIX is silent on this issue, because the existence of the "test.c: test.b" rule -- a rule without any commands -- takes it out of the scope of when POSIX says suffix rules should be applied (which is only when there are no explicit rules).

Much of your message seems to be about what you think should happen based on the documentation. I think you are may be right in your interpretation of the existing documentation, but the old behaviour was clearly useful, and people clearly relied on it, even if it was not documented.

And actually, it did not do it before looking at the path.
It searched and found foo.c, then it started looking at the dependency
list, noticed subdir/foo.c and made that one the implied source, but
_did_not_ remove foo.c from the list of dependencies.  And any target
whose filename part was foo.X (where there is a rule .X.o), not just
foo.c, would have been accepted.  And this was done even if subdir was
not in .PATH.

That sounds like a bug.

 > Let me turn the tables on your example.  Let us assume that make allows
 > the explicitly listed dependencies to become the implied source, instead
 > of the one found by regular suffix rule search.  Let us also assume that
 > the file subdir/foo.c contains something that is included by foo.c, so
 > foo.o naturally depends on it.  How will I then write the Makefile?
 > Exactly like you did, of course:
 >
 >     foo.o: subdir/foo.c
 >
 > Running make would compile foo.o from subdir/foo.c, which is obviously
 > incorrect and completely unexpected, because foo.c exists.

Compiling foo.o from subdir/foo.c is and entirely expected
by people familiar with the NetBSD build system.

 > Therefore,
 > the extra dependencies should not affect the suffix rule selection.

Perhaps if you were designing a new implementation of make, that should
be the case.  What you call an "extra" dependency, in addition to the
one inferred from .SUFFIX search, others might call an "explicit"
dependency, removing the necessity for a .SUFFIX search.

 > (I'd like to add that the overriding behavior was not documented in any
 > way, I only found out about it after I read the source)

Yes, it was (is) undocumented, but people relied on it. Lets fix the documentation and reimplement the desired behaviour. I'd suggest that the desired behaviour should be:

If there is an explicit dependency with commands, then the commands are performed, and no suffix search or suffix rules are relevant.

If there is no explicit dependency whatsoever, then the search implied by .SUFFIXES is performed to find an implicit source file. The suffixes found in the search select the appropriate .suffix1.suffix2 rule, and the commands in that rule are performed.

If there is an explicit dependency without commands, then the search implied by .SUFFIXES is NOT performed, but the file names are checked to see whether they end with known suffixes. (If a target explicitly depends on multiple sources, then only the first source gets this treatment.) The suffixes from the first explicit dependency select an appropriate .suffix1.suffix2 rule, if it exists, and the commands in that rule are performed. (If the files in the explicit dependency do not have known suffixes, or there is no .suffix1.suffix2 rule, then nothing happens.)

--apb (Alan Barrett)


Home | Main Index | Thread Index | Old Index