]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Add a script that traces which other files a .cc or .h file depends on. 18367/head
authorWolfgang Bangerth <bangerth@colostate.edu>
Sat, 19 Apr 2025 03:03:07 +0000 (21:03 -0600)
committerWolfgang Bangerth <bangerth@colostate.edu>
Mon, 21 Apr 2025 16:20:47 +0000 (10:20 -0600)
contrib/utilities/find_header_dependencies.py [new file with mode: 0644]

diff --git a/contrib/utilities/find_header_dependencies.py b/contrib/utilities/find_header_dependencies.py
new file mode 100644 (file)
index 0000000..bfe5cb2
--- /dev/null
@@ -0,0 +1,72 @@
+#!/usr/bin/python3
+
+## ------------------------------------------------------------------------
+##
+## SPDX-License-Identifier: LGPL-2.1-or-later
+## Copyright (C) 2025 by the deal.II authors
+##
+## This file is part of the deal.II library.
+##
+## Part of the source code is dual licensed under Apache-2.0 WITH
+## LLVM-exception OR LGPL-2.1-or-later. Detailed license information
+## governing the source code and code contributions can be found in
+## LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
+##
+## ------------------------------------------------------------------------
+
+# Given the name of a source or header file, find all deal.II header
+# files it depends on directly or indirectly.
+#
+# Call this script via
+#   python3 contrib/utilities/find_header_dependencies.py <filename>
+# where '<filename>' is the name of the source file to be analyzed.
+
+
+from glob import glob
+import networkx as nx
+import re
+import sys
+
+source_file = sys.argv[1]
+
+match_dealii_includes = re.compile(r"# *include *<(deal.II/.*)>")
+
+
+# For a given header or source file, read through all the lines and
+# extract the ones that correspond to further #include statements. For
+# those, add a link to the graph.
+def add_includes_for_file(file, G):
+    f = open(file)
+    lines = f.readlines()
+    f.close()
+
+    for line in lines:
+        m = match_dealii_includes.match(line)
+        if m:
+            included_file = m.group(1)
+            G.add_edge(file, "include/" + included_file)
+
+
+# Create a list of all source files in the build folder
+filelist = glob("include/deal.II/**/*.h", recursive=True)
+assert filelist, "Please call the script from the top-level deal.II directory."
+if source_file not in filelist:
+    filelist.append(source_file)
+
+
+# For each header file plus the one provided on the command line, add
+# the includes as the edges of a directed graph.
+G = nx.DiGraph()
+G.add_node(source_file)  # Make sure the graph has at least one node
+for file in filelist:
+    add_includes_for_file(file, G)
+
+# Now find everything that is upstream of the module partition
+# specified on the command line:
+print(f"The dependencies of module partition '{source_file}' are:")
+for node in nx.dfs_postorder_nodes(G, source=source_file):
+    if node != source_file:
+        print(f"  {node}")
+
+n_dependencies = sum(1 for _ in nx.dfs_postorder_nodes(G, source=source_file)) - 1
+print(f"{n_dependencies} files are upstream dependencies for '{source_file}'")

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.