tech-toolchain archive

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

Re: make: avoid breaking backwards compatability

On Mon, Sep 01, 2014 at 12:15:58PM -0700, Simon Gerraty wrote:
> A target that has a \ at the end of the last line of its script now breaks.
> Such targets were valid until recently and the practice is not uncommonn
> since it reduces noise in diff's when additional commands added
> (eg. great log sed commands)

Your example did not work for me, I got "1 open conditional".  I did try
however with the following Makefile:

        sed < Makefile \
            -e 's,sed,SED,' \

Yes, this seems to fail, but this was in now way intentional
breakage on my part.  The issue seems to be that the final newline is
not passed to the shell: the command line ends with "\<EOF>" instead of
"\<newline>".  This seems to make the backslash a regular character
instead of any sort of escape.  Looks like Christos has committed a fix
for /bin/sh related to this.  IIRC someone in this thread objected to
that, but I'd think that it is proper as in sh a backslash is supposed
to preserve the literal value of following character (unless you want to
debate on whether EOF is a character or not).

However, I think that "where did the final newline go in the first
place" is a good question to ask.  If anyone knows, please tell me.

> The other case I hit was where SRCS contains sub/file.c 
> sometimes adding the dir where sub/file.c lives to .PATH isn't an option
> because of other files present that are not the desired ones.
> Until recently
> foo.o: subdir/foo.c
> worked, but now even after subdir/foo.c has been correctly found
> a search for foo.c is made and overrides the previous result - which can
> cause the wrong foo.c to be compiled.
> Sometimes this can all be sorted out by tweaking .PATH, but again only
> if you have access to the makefile that needs fixing.

No, this works exactly as suffix rules should work, in my opinion.
The problem here is not that subdir/foo.c is overridden, it is that you're
expecting some random extra dependency to become the implied source in
a suffix rule.  And that is what you've written: you're asking make to
use suffix rules to make foo.o and merely told that the object file also
happens to depend on some other C file too.  This is no different from
"foo.o: subdir/bar.c" and nobody would expect subdir/bar.c to become
the implied source in that case.  In your example subdir/foo.c just
would be eligible to become the implied source with a proper value of

I understand that before my changes the extra dependencies used
to affect the implied source selection for suffix rules.  This, however,
is IMO completely wrong and was listed in PR 49086 as issue 10.

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.  Therefore, the extra dependencies
should not affect the suffix rule selection.  (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)

Now here is what I would do instead now that make makes $(<) be
the first dependency in explicit rules (assuming you cannot rename
either foo.c or subdir/foo.c):

    foo.o: subdir/foo.c
        $(CC) -o $(@) $(<)

Or if you have multiple files:

    $(SRCS): subdir/$(*).c
        $(CC) -o $(@) $(<)

Jarmo Jaakkola

Home | Main Index | Thread Index | Old Index