Paul Smith via austin-group-l at The Open Group <[email protected]>
wrote:
> On Thu, 2020-11-05 at 19:36 +0100, Joerg Schilling wrote:
> > .SUFFIXES:
> > .SUFFIXES: .o .c
> > .c.o:
> > echo foo
> >
> > In other words, a users makefile has full control over the "builtin"
> > default rules even without a need to use "make -r".
>
> Sure, it's easy to redefine a suffix rule. The issue in question was
> that Geoff wanted to not use the .c.o rule at all. He wanted to use
> other rules to build .o files in other ways, but the .c.o rule was
> interfering with it. There's no way to DELETE that .c.o rule other
> than -r.
Well, this indeed is a problem with the suffix rules. You need to be careful to
understand their working method correctly. But I expect people to either not
touch these rules at all or to learn how to use them first.
smake in former times had simple suffix rules this way:
.o: .c .s .l
$(CC) -c $(CFLAGS) $(CPPFLAGS) $<
$(AS) -o $*.o $(ASFLAGS) $<
$(LEX) $(LFLAGS) $<;$(CC) -c $(CFLAGS) lex.yy.c;rm lex.yy.c;mv lex.yy.o
$@
which is easier to understand, but I stopped to define them 21 years ago
because three methods for implicit rules (simple suffix, suffix and pattern)
most
likely are too much for users.
> In fact, GNU make allows users to disable built-in rules completely
> WITHOUT having to require users to add -r to the make command line,
> because it allows users to add this to their makefile:
>
> MAKEFLAGS += -r
I would not call this an advantage, since it is in conflict with all other
make implementations and people that may have seen this to work (how ever) in
gmake, will realize that this cannot work if you follow the lines of POSIX and
first read the internal rules and then the external makefiles. If a make
implementation reads the external makefile, it is thus too late to disable the
internal rules unless you introduce dirty tricks that are not compatible to the
POSIX definitions.
> and it does the right thing. Of course this is problematic as well
> because that is now passed to sub-make invocations which may not be
> what you want. However, in practice it is rarely a problem.
This is true, if you pass this to sub-makes, it is not too late...
> In fact, most of the built-in rules in GNU make ARE defined as suffix
> rules; see this from default.c:
>
> ".c.o",
> "$(COMPILE.c) $(OUTPUT_OPTION) $<",
I cannot confirm this, gmake at the same time defines
%.o: %.c
# recipe to execute (built-in):
$(COMPILE.c) $(OUTPUT_OPTION) $<
whis is a rule with precedence before suffix rules.
> However, GNU make also provides a number of built-in rules that cannot
> be expressed as suffix rules, such as these:
>
> /* RCS. */
> { "%", "%,v",
> "$(CHECKOUT,v)" },
> { "%", "RCS/%,v",
> "$(CHECKOUT,v)" },
> { "%", "RCS/%",
> "$(CHECKOUT,v)" },
Classical make implementation (and in this special case, this also applies to
SunPro Make) implement this hardcoded in C. This is why I so far have been
hesitant to define similar rules in smake. RCS is non-standard, dead and slower
than SCCS anyway, so this does not seem to be a problem ;-)
> > - pattern matching rules have precedence over suffix rules and may
> > themselves not be overwritten
> >
> > - pattern matching rules match in the order of their apperance to the
> > parser. The first pattern rule that matches a specific pattern is
> > used. Later specifying a replacement rule for a specific pattern is
> > impossible.
> >
> > - The built in default rules must to be "read" by make before the
> > users makefiles are parsed in order to allow them (the suffix
> > rules) to be overwritten. Any pattern matching rule that appears
> > in the builtin default rules thus would have precedence over
> > anything else and cannot be overwritten.
>
> Maybe these are problems in SunOS make / smake, but they are certainly
> not problems in GNU make.
>
> I'm not sure where the idea that pattern rules are immutable comes
> from: in GNU make any pattern rule can be overwritten at any time,
> including the default pattern rules.
This is how pattern rules have been defined when they appeared in SunPro Make
in January 1986.
If this was a problem, people could have made a bug report at that time but
this did not happen.... Given that pattern rules are not (neither in SunPro
Make, nor in smake) used in the built in rules, there is no need to have a
method to remove them later, since they are only used by the user makefiles.
Since I tend to avoid a hard coded implementation for SCCS support in smake, I
tend to introduce SCCS checkout support in a future version of smake using
pattern rules. This would introduce the need to be able to withdraw existing
pattern rules selectively.
The fact that gmake overwrites existing pattern rules is not sufficient (as it
does not permit to remove them) and it is a non-compliance related to the
original definition so this modification from gmake causes unpredictable
behavior.
> Also, pattern rules can be completely canceled without overwriting
> them, including as well the default pattern rules. It's just annoying
> to have to do it by hand, and make sure you get them all, so something
> like MAKEFLAGS += -r is much more robust.
Well after some searching (documentation could be better), I discovered that
gmake seems to disable (not to delete) pattern rules if a rule with the same
pattern but no command is defined. This is not compliant to the definition of
how pattern rules work.
> Also, user-defined pattern rules are always added to be searched before
> built-in pattern rules so the first one will always be a user-defined
> pattern, if such exists.
This is non-compliant behavior....
> And finally, it's not actually true that the first pattern rule that
> matches is used. That used to be the case but quite a while ago the
> pattern matcher was changed so that the rule with the shortest matching
> stem is chosen first. If multiple pattern rules have stems with the
> same length then the first one is chosen.
This is non-compliant behavior as well....
> This algorithm change is a little controversial and I'm not sure about
> it, but it seems to be acceptable in practice and it does avoid
> worrying about the order in which patterns are defined.
There seems to be a possible way to enhance the way pattern rules work without
becomming fully non-commpliant:
The series:
%.o: %.c
echo some command
%.o: %.c
could be defined to require to completely remove the first definition from the
chain of pattern rules.
As a result, the series:
%.o: %.c
echo some command
%.o: %.c
%.o: %.c
echo some new command
could be defined as to first define a pattern rule, then to completely remove
it from the chain of pattern rules and to finaly add a new rule with a
different command to the current end of the pattern rule chain, without being
completely incompatible to the existing pattern rule specs.
There are still two problems with this change:
- There may be another pattern rule that also matches a specific target
and that would be searched first
- Disabling all preexisting pattern rules would require the need to know
all their patterns explicitly.
To fix this problem, the nonsense pattern with no command definition:
%: %
could be defined as the method to completely remove all existing pattern rules
from the current chain of pattern rules.
Jörg
--
EMail:[email protected] (home) Jörg Schilling D-13353 Berlin
Blog: http://schily.blogspot.com/
URL: http://cdrecord.org/private/ http://sf.net/projects/schilytools/files/'