Hi, Paul Smith, the GNU make maintainer, gives this recommendation how to disable built-in rules and thus speed up make's processing [1]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - My recommendation has been to disable the built-in rules directly, if you don't need them. For example you can use: .SUFFIXES: to disable most of the built in rules (this is a POSIX standard facility so it's helpful even for other versions of make). Unfortunately that doesn't fix all problems because GNU Make also has a few built-in rules that are defined using pattern rules (because suffix rules are not powerful enough). So a full list of "turn it all off" would be this: .SUFFIXES: %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GNU Automake already emits the '.SUFFIXES:' line. To optimize things for GNU make, it should also emit the remaining part. It has no effect with non-GNU make [2]. The effect, for example in gettext's gettext-runtime/src directory, is that - The output of "make -n -d" shrinks from 11028 lines to 4928 lines. - The number of 'stat()' calls made by "make -n" shrinks from 188 to 178. (make no longer tests whether various directories have an 'RCS' or 'SCCS' subdirectory.) Patch is attached. Bruno [1] https://lists.gnu.org/archive/html/bug-make/2023-07/msg00063.html [2] https://lists.gnu.org/archive/html/bug-make/2023-07/msg00067.html
>From c8ca5b95a0c322177ba0fb55ddabc1c92fa04f10 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Thu, 20 Jul 2023 11:50:51 +0200 Subject: [PATCH] Speed up GNU make's internal processing. Based on a recommendation by Paul Smith in <https://lists.gnu.org/archive/html/bug-make/2023-07/msg00063.html>. * lib/am/footer.am: Disable GNU make's internal pattern rules. * lib/Automake/Rule.pm (_conditionals_for_rule): Add special handling for these pattern rules from footer.am. (define): Likewise. * t/nodep.sh: Update test. --- lib/Automake/Rule.pm | 39 +++++++++++++++++++++++---------------- lib/am/footer.am | 11 +++++++++++ t/nodep.sh | 2 +- 3 files changed, 35 insertions(+), 17 deletions(-) diff --git a/lib/Automake/Rule.pm b/lib/Automake/Rule.pm index 9f72d2728..52ee3be4a 100644 --- a/lib/Automake/Rule.pm +++ b/lib/Automake/Rule.pm @@ -695,6 +695,9 @@ sub _conditionals_for_rule ($$$$) return $cond if !$message; # No ambiguity. + # Don't coalesce the several pattern rules from footer.am into a single one. + return $cond if $target eq "%:" && $where->get =~ /\/am\/footer\.am$/; + if ($owner == RULE_USER) { # For user rules, just diagnose the ambiguity. @@ -764,23 +767,27 @@ sub define ($$$$$) my $tdef = _rule_defn_with_exeext_awareness ($target, $cond, $where); - # A GNU make-style pattern rule has a single "%" in the target name. - msg ('portability', $where, - "'%'-style pattern rules are a GNU make extension") - if $target =~ /^[^%]*%[^%]*$/; - - # See whether this is a duplicated target declaration. - if ($tdef) + # The pattern rules in footer.am look like duplicates, but really aren't. + if ($source !~ /\/am\/footer\.am$/) { - # Diagnose invalid target redefinitions, if any. Note that some - # target redefinitions are valid (e.g., for multiple-targets - # pattern rules). - _maybe_warn_about_duplicated_target ($target, $tdef, $source, - $owner, $cond, $where); - # Return so we don't redefine the rule in our tables, don't check - # for ambiguous condition, etc. The rule will be output anyway - # because '&read_am_file' ignores the return code. - return (); + # A GNU make-style pattern rule has a single "%" in the target name. + msg ('portability', $where, + "'%'-style pattern rules are a GNU make extension") + if $target =~ /^[^%]*%[^%]*$/; + + # See whether this is a duplicated target declaration. + if ($tdef) + { + # Diagnose invalid target redefinitions, if any. Note that some + # target redefinitions are valid (e.g., for multiple-targets + # pattern rules). + _maybe_warn_about_duplicated_target ($target, $tdef, $source, + $owner, $cond, $where); + # Return so we don't redefine the rule in our tables, don't check + # for ambiguous condition, etc. The rule will be output anyway + # because '&read_am_file' ignores the return code. + return (); + } } my $rule = _crule $target; diff --git a/lib/am/footer.am b/lib/am/footer.am index 9715c826c..388defb14 100644 --- a/lib/am/footer.am +++ b/lib/am/footer.am @@ -17,3 +17,14 @@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +## This reduces make's internal processing. +## Recommended by Paul Smith in +## <https://lists.gnu.org/archive/html/bug-make/2023-07/msg00063.html>. +## These rules have no effect on non-GNU make implementations. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff --git a/t/nodep.sh b/t/nodep.sh index 4201c8ead..0174b838e 100644 --- a/t/nodep.sh +++ b/t/nodep.sh @@ -37,6 +37,6 @@ $ACLOCAL $AUTOMAKE sed 's/printf .*%s//' Makefile.in > Makefile.tmp -grep '%' Makefile.tmp && exit 1 +grep -v '^%::' Makefile.tmp | grep '%' && exit 1 : -- 2.34.1