Update of bug #66011 (group make):

                  Status:                    None => Not A Bug              
             Open/Closed:                    Open => Closed                 

    _______________________________________________________

Follow-up Comment #4:

Indeed the prerequisite did attach to the pattern rule, just as the
documentation said that it did.  If it hadn't attached to the pattern rule,
then your pattern rule would have matched.

You are mistaken about what you see when you use "make -d".  The issue is not
that the items after nonexisting.h are ignored.  The issue is that once make
sees nonexisting.h, the pattern rule doesn't match and make goes looking for a
_different_ pattern rule.  Here is some sample output:

 File 'foo.o' does not exist.
 Looking for an implicit rule for 'foo.o'.
  Trying pattern rule '%.o: %.c a.h nonexisting.h c.h Makefile' with stem
'foo'.
  Trying implicit prerequisite 'foo.c'.
  Found 'foo.c'.
  Trying rule prerequisite 'a.h'.
  Found 'a.h'.
  Trying rule prerequisite 'nonexisting.h'.
  Not found 'nonexisting.h'.
  Trying pattern rule '%.o: %.c' with stem 'foo'.
  Trying implicit prerequisite 'foo.c'.
  Found 'foo.c'.
 Found implicit rule '%.o: %.c' for 'foo.o'.

Note carefully that after "Not found 'nonexisting.h'", GNU Make looks at a
completely different rule: the built-in rule to build object files from source
files.  You can run *make -r* to disable the built-in rules, then maybe the
output will be more clear.

Some people think of pattern rules like a C preprocessor macro, where you
expand it and you get a static rule.

But this concept is wrong: a pattern rule is much more like a C++ overloaded
method, where IF all the types match up with the caller then the method is
used, else the compiler will continue looking for some other method to be
used.  If there is no method where the types match up with the caller, then
you have a compiler error.

That's exactly what happens here: make looks for a pattern rule where BOTH (a)
the target matches the pattern, AND (b) _all_ the prerequisites listed in the
rule either exist, or make can discover a way to build them.

If either one of (a) or (b) is not satisfied then the pattern rule does not
match and make continues looking for another pattern rule that will match.  If
make cannot find any pattern rule that matches, then make gives an error
saying it doesn't know how to build the target.

There can be, and often are, many pattern rules for how to build a given
target.  For example you can build an object file from a C source file, C++,
Fortran, assembly, etc.  So make can't just complain about every non-matching
rule.  And by the time make discovers that no rules have matched, it has
forgotten about all the rules that it tried.

Of course it could be possible, with a lot of effort, to remember all the
rules that were tried so that, if everything fails, they could be printed as
part of the error messages, but that effort has not been made and it's not
clear it's worth the effort.

The output of the --debug option should be sufficient to show what happens,
although it does require concentration and/or familiarity to parse it.

Dmitry recommends this formulation:

hello.o: $(HEADERS) Makefile
%.o : %.c
        $(CC) $(CFLAGS) -c $<

not because this will work: it will still fail.  He recommends it because in
this situation the error message that make prints will be more understandable.
 This happens because the pattern rule does match (as all the prerequisites
_of the pattern rule_ exist or can be built), but when make goes to try to
build a specific prerequisite of the target nonexisting.h and can't, it will
print a message about that prerequisite not being built, not that there's no
rule to build the object file.

I'm going to close this issue as "Not a Bug" but you can feel free to continue
to discuss things here if the behavior is not clear.  You can also use the
mailing lists such as help-m...@gnu.org if you prefer (that list has a wider
audience).


    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?66011>

_______________________________________________
Message sent via Savannah
https://savannah.gnu.org/

Attachment: signature.asc
Description: PGP signature

Reply via email to