tech-toolchain archive

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

Re: make: avoid breaking backwards compatability

On Fri, Sep 05, 2014 at 12:16:21AM +0200, Alan Barrett wrote:
> On Thu, 04 Sep 2014, Jarmo Jaakkola wrote:
> 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).

I must admit that after looking at the standard again, you seem to be
correct that it is not allowed by the text.

Quoting POSIX:
    There are two types of rule:
      1. Inference rules, [...]
      2. Target rules, [...]

  Target Rules

    target [target...]: [prerequisite...][;command]

    A target that has prerequisites, but does not have any commands,
    can be used to add to the prerequisite list for that target.
    Only one target rule for any given target can contain commands.

  Inference Rules

    When no target rule is found to update a target, the inference
    rules shall be checked.

According to this, a dependency line without associated commands is
still a "target rule" and then the inference rules should never be
checked.  I can hardly believe that the people who wrote the standard
intended this.  There could never be any dependencies other than
the implied source.  Effectively any makefile ever written to use suffix
rules would not be POSIX compliant:

    foo.o: foo.h  # Oops, can't use inference rules anymore.

The practice of adding extra dependencies to targets made by inference
must surely have been there since the invention of suffix rules.
Clearly it should say something like this:
    A target that has prerequisites, but does not have any commands,
    can be used to add to the prerequisite list for that target.
    Such a target is not considered a target rule for the purposes
    of inference rule applicability.

I have to submit a bug report against the POSIX definition then. :)

>> 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
   ^ On testing this part turned out to not actually be true.  I confused
it with another case where the dependency was actually forced.  In this
case the dependency was correctly removed.  Other parts of the described
behavior do hold.

> 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.

I partly agree.  I'd say: take the name of the target (dir/target.x),
then take all suffixes .y from which .x can be made (in .SUFFIXES order)
and see if the first dependency is "[prefix/]dir/target.y".  If it is, use
that one.  Otherwise do a normal suffix rule search.

Then the question is if "prefix" should be in .PATH for the dependency
to be approved.  I.e. is this "choose one eligible candidate explicitly"
or "use this file regardless of if it could normally be used".

Also, do we want multi-stage transformations:

    foo.z: foo.x # foo.x -> foo.y -> foo.z

I'd say no, because now you're saying that foo.z depends on foo.x, while
in reality foo.z depends on foo.y, which depends on foo.x.  Not to mention
that it would probably necessitate implementing the suffix search in
reverse.  And you could still write:

    foo.z: foo.y
    foo.y: foo.x

Just like you would when a multi-stage search gives the wrong result.

> (If the files in the explicit dependency do not have 
> known suffixes, or there is no .suffix1.suffix2 rule, then nothing 
> happens.)

I strongly disagree.  This will break approximately all makefiles ever
written.  Consider:

    foo.o: foo.h other.h

Surely what this means is that foo.o is to be made from foo.c, but
the object file also depends on the headers foo.h and other.h and
must be recompiled when they change.

Jarmo Jaakkola

Home | Main Index | Thread Index | Old Index