From a15cc895abfc9b426af75051d069fd625391b618 Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Wed, 29 Nov 2023 10:30:21 -0800 Subject: [PATCH v1 2/2] meson: Add test checking if there are conflicting target names Author: Reviewed-by: Discussion: https://postgr.es/m/703110e4-b495-e409-26a5-28e9fca8f3a5@dunslane.net Backpatch: --- meson.build | 8 ++++++ src/tools/check_meson | 67 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100755 src/tools/check_meson diff --git a/meson.build b/meson.build index 0095fb183af..e0895f41f78 100644 --- a/meson.build +++ b/meson.build @@ -3320,6 +3320,14 @@ if meson.version().version_compare('>=0.57') endif +# Tests verifing that source code follows certain rules +test('meson-check', + files('src/tools/check_meson'), + args: ['--srcdir', meson.source_root(), '--builddir', meson.build_root()], + suite: 'source', + priority: 10) + + ############################################################### # Pseudo targets diff --git a/src/tools/check_meson b/src/tools/check_meson new file mode 100755 index 00000000000..060ccd269ff --- /dev/null +++ b/src/tools/check_meson @@ -0,0 +1,67 @@ +#!/usr/bin/env python3 + +# Script to perform some consistency checks on the meson build. + +from collections import defaultdict +import argparse +import json +import os +import sys + + +def check_target_names(args): + """ + Check that the target names for run_target() and alias_target() do + not conflict with other target types like + custom_target(). alias_target()/run_target() targets are intended to + be invoked at the top-level, but "meson compile $target" complains + about conflicts if another name of the same target exists. + """ + targets_info_path = os.path.join( + args.builddir, 'meson-info/intro-targets.json') + targets_info = json.load(open(targets_info_path)) + + targets_info_byname = defaultdict(list) + + for r in targets_info: + targets_info_byname[r['name']].append(r) + + have_conflicts = False + + for name, v in targets_info_byname.items(): + if len(targets_info_byname[name]) > 1: + dirs = set() + types = set() + have_target_conflict = False + for t in v: + dirs.add(t['defined_in']) + types.add(t['type']) + if len(dirs) < len(v) and ('alias' in types or 'run' in types): + have_target_conflict = True + + if have_target_conflict: + have_conflicts = True + print(f'Global target "{name}" has conflicting target names:', + file=sys.stderr) + for t in v: + fname = os.path.relpath(t['defined_in'], args.srcdir) + print(f'\t"{t["name"]}:{t["type"]}", defined in "{fname}"', + file=sys.stderr) + print(file=sys.stderr) + + if have_conflicts: + print("Please rename conflicting targets", + file=sys.stderr) + return False + return True + + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('--builddir', type=str, required=True) + parser.add_argument('--srcdir', type=str, required=True) + args = parser.parse_args() + + all_ok = True + all_ok &= check_target_names(args) + sys.exit(not all_ok) -- 2.38.0