[v3,3/8] devtools: add script to flag unneeded dependencies

Message ID 6da0eb59d1967f42b612bbbaa74c6ddc3cbf7b7d.1725462264.git.anatoly.burakov@intel.com (mailing list archive)
State New
Delegated to: Thomas Monjalon
Headers
Series record and rework component dependencies |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Burakov, Anatoly Sept. 4, 2024, 3:08 p.m. UTC
From: Bruce Richardson <bruce.richardson@intel.com>

While not a serious problem, DPDK components often list more
dependencies than are actually necessary to build, due to the use of
recursive dependencies. In extreme cases, such as with core libraries,
this can lead to longer configuration times due to meson having to
deduplicate long lists of dependencies. Therefore we can add a script to
identify when a component has got unnecessary dependencies listed.

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
 devtools/find-duplicate-deps.py | 53 +++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)
 create mode 100755 devtools/find-duplicate-deps.py
  

Patch

diff --git a/devtools/find-duplicate-deps.py b/devtools/find-duplicate-deps.py
new file mode 100755
index 0000000000..b1eacf21ce
--- /dev/null
+++ b/devtools/find-duplicate-deps.py
@@ -0,0 +1,53 @@ 
+#! /usr/bin/env python3
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2024 Intel Corporation
+
+"""Identify any superfluous dependencies listed in DPDK deps graph."""
+
+import sys
+
+all_deps = {}
+
+
+class dep:
+    """Holds a component and its dependencies."""
+
+    def __init__(self, name, dep_names):
+        """Create and process a component and its deps."""
+        self.name = name.strip('" ')
+        self.base_deps = [all_deps[dn.strip('" ')] for dn in dep_names]
+        self.recursive_deps = []
+        for d in self.base_deps:
+            self.recursive_deps.extend(d.base_deps)
+            self.recursive_deps.extend(d.recursive_deps)
+        self.extra_deps = []
+        for d in self.base_deps:
+            if d in self.recursive_deps:
+                self.extra_deps.append(d.name)
+        if self.extra_deps:
+            print(f'{self.name}: extra deps {self.extra_deps}')
+
+    def dict_add(self, d):
+        """Add this object to a dictionary by name."""
+        d[self.name] = self
+
+
+def main(argv):
+    """Read the dependency tree from a dot file and process it."""
+    if len(argv) != 2:
+        print(f'Usage: {argv[0]} <build-directory>/deps.dot', file=sys.stderr)
+        sys.exit(1)
+
+    with open(argv[1]) as f:
+        for ln in f.readlines():
+            ln = ln.strip()
+            if '->' in ln:
+                name, deps = ln.split('->')
+                deps = deps.strip(' {}')
+                dep(name, deps.split(',')).dict_add(all_deps)
+            elif ln.startswith('"') and ln.endswith('"'):
+                dep(ln.strip('"'), []).dict_add(all_deps)
+
+
+if __name__ == '__main__':
+    main(sys.argv)