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:
On Wed, Sep 03, 2014 at 10:25:38PM +0000, Christos Zoulas wrote:
Well, the problem is that now "suffix rules" cannot be controlled. I.e. if I have a foo.c and a foo.S in a directory I cannot say for arch x use foo.S and for arch y use foo.c.

ITYM they can't be controlled as finely. You can still reorder the suffixes to prefer either .c or .S. If you need to decide on an object-by-object basis, then you're out of luck.

But we *do* want to control it on an object-by-object basis. The old method used to work fine. The recently modified make makes this much more difficult to use than before. Worse, it's a silent change. The meaning of a Makefile that was valid under both old and new interpretations can change, such that a file that used to be built from a *.c source is now built from a *.S source, or vice versa.

But now that the support for $(<) is consistent, one could write:

   COMPILE_C = ...
   .c.o: ; $(COMPILE_C)
   foo.o: dir/foo.c ; $(COMPILE_C)

Yes, one can rewrite the system *.mk files to provide new variables that allow user makefiles to be rewritten to work around the changed behaviour.

I would much prefer to see the old behaviour reinstated. It was changed without much discussion, and I think that was a mistake. The discussion had the superficial appearance of talking about bug fixes and improving POSIX compliance, and it was not at all clear to a casual reader that a significant incompatible change was being proposed.

The suffix rules are really two things:

1. A list of precedence rules to be used when searching for files to satisfy a dependency (.SUFFIXES);

2. A set of command rules to build files with a particular suffix from files with another suffix (.c.o, .S.o, etc.).

I think it's useful to be able to write explicit rules that to override the search part of suffix processing, while not overriding the commands. I think it's useful to be able to do that in the way that has worked in BSD make for many years, without needing new syntax or rewriting *.mk files.

I think that anybody who wants to change this long-standing behaviour should present a clear proposal explaining the pros and cons, and the required changes to user makefiles, and allow adequate time for discussion. I think that that did not happen. Instead, the change was briefly discussed as if it were a bug fix, or a small change with no adverse consequences.

Sure, this isn't using the inference rules like it used to. But this is effectively the same and has the nice feature of using inference without tricks where applicable and explicit rules where inference does not work.

But yeah, you can't force it to choose some other rule or source by putting it as an explicit dependency.

It allows you to achieve similar effects by rewriting the system *.mk files and the end user's makefiles. That's hardly the same as just continuing to work as before.

For that reason we should add back compatibility code, but leave it off by default (so that we don't end up with Makefiles that use non-portable features again; see note below).

Why should compatibility be off by default?

What use cases actually benefit from the new behaviour
of rules like

        foo.o: otherdir/foo.S # Note that foo.c might or might not exist


        bar.o: bar.c # Note that bar.S also exists


Are the new use cases so compelling that we think it's a good idea to break existing makefiles that expect that the old behaviour, which is that foo.o should be built from otherdir/foo.S using the commands in the .S.o rule, regardless of whether foo.c or foo.S exists in ${.CURDIR}; and bar.o should be built from bar.c using the commands in the .c.o rule, regardless of whether bar.S exists and regardless of the relative order of .c and .S in the .SUFFIXES list.

--apb (Alan Barrett)

Home | Main Index | Thread Index | Old Index