From a4f4f88fd128a1807db3b8575e14d4e178579e71 Mon Sep 17 00:00:00 2001 From: Sergey Kosukhin Date: Fri, 26 Apr 2024 16:32:45 +0200 Subject: [PATCH] deplist.py: support pattern dependency hints. --- mkhelper.mk.in | 2 +- mkhelper/deplist.py | 77 +++++++++++++++++++++++++++++++++++++++------ 2 files changed, 69 insertions(+), 10 deletions(-) diff --git a/mkhelper.mk.in b/mkhelper.mk.in index fe6e64c..07f38cb 100644 --- a/mkhelper.mk.in +++ b/mkhelper.mk.in @@ -193,7 +193,7 @@ sanitize-mod-proxies: extra_f90.d: mkhelper.mk $(silent_DEPGEN):;{ \ echo '#-hint src/program/main.o: src/program/implicit_external.o'; \ - echo '#-hint src/program/main.o: src/modules/submo_test_submodule.o'; \ + echo '#-hint <*.o: $(moddir)/mo_test_submodule.@FC_MOD_FILE_EXT@.proxy>.targets: src/modules/submo_test_submodule.o'; \ } >$@ # Configure delayed bundled libraries: diff --git a/mkhelper/deplist.py b/mkhelper/deplist.py index c796b52..2aa1a59 100755 --- a/mkhelper/deplist.py +++ b/mkhelper/deplist.py @@ -47,14 +47,38 @@ import re import sys -_re_rule = re.compile( - r"^(?P#-hint )?" - # targets - r"[ ]*(?P[-+\w./]+(?:[ ]+[-+\w./]+)*)[ ]*" - # normal prerequisites - r":[ ]*(?P[-+\w./]+(?:[ ]+[-+\w./]+)*)?[ ]*" - # order-only prerequisites - r"(?:\|[ ]*(?P[-+\w./]+(?:[ ]+[-+\w./]+)*))?" +_re_hint = r"^#-hint[ ]+" +_re_targets_or_prereqs = r"[-+\w./]+(?:[ ]+[-+\w./]+)*" + +_repat_rule_or_plain_hint = re.compile( + r"^(" + _re_hint + r")?[ ]*" + r"(?P" + _re_targets_or_prereqs + ")" + r"[ ]*:[ ]*" + r"(?P" + _re_targets_or_prereqs + ")?" + r"[ ]*(?:\|[ ]*" + r"(?P" + _re_targets_or_prereqs + ")" + r")?" +) + +# Supported pattern hints: +# 1) .targets: X - all targets that match shell-like wildcard p1 and +# have a prerequisite that matches shell-like +# wildcard p2 depend on X + +PatternHint = collections.namedtuple( + "Hint", ["target_pattern", "prereq_pattern", "extra_prereqs"] +) + +_repat_pattern_hint = re.compile( + _re_hint + r"<[ ]*" + r"(?P.*[^ ])" + r"[ ]*:[ ]*" + r"(?P.*[^ ])" + r"[ ]*>" + r"\.(?Ptargets)" + r"[ ]*:[ ]*" + r"(?P" + _re_targets_or_prereqs + ")" + r"[ ]*$" ) _meta_root = 0 @@ -207,9 +231,29 @@ def convert_arg_line_to_args(self, arg_line): return args +def apply_pattern_hints(graph, hints): + extra_rules = collections.defaultdict(list) + + for hint in hints: + for target, prereqs in graph.items(): + if fnmatch.fnmatch(target, hint.target_pattern) and fnmatch.filter( + prereqs, hint.prereq_pattern + ): + extra_prereqs = [ + prereq for prereq in hint.extra_prereqs if prereq != target + ] + if extra_prereqs: + extra_rules[target].extend(extra_prereqs) + + for target, extra_prereqs in extra_rules.items(): + graph[target].extend(extra_prereqs) + + def read_makefiles(makefiles, inc_order_only): result = collections.defaultdict(list) + pattern_hints = [] + for mkf in makefiles: if mkf == "-": stream = sys.stdin @@ -228,7 +272,7 @@ def read_makefiles(makefiles, inc_order_only): except StopIteration: break - match = _re_rule.match(line) + match = _repat_rule_or_plain_hint.match(line) if match: targets = set(match.group("targets").split()) prereqs = [] @@ -244,8 +288,23 @@ def read_makefiles(makefiles, inc_order_only): for target in targets: result[target].extend(prereqs) + continue + + match = _repat_pattern_hint.match(line) + if match: + pattern_hints.append( + PatternHint( + match.group("target_pattern"), + match.group("prereq_pattern"), + match.group("extra_prereqs").split(), + ) + ) + continue stream.close() + + apply_pattern_hints(result, pattern_hints) + return result