Skip to content

tobiaskaestner/dep-analyzer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

dep-analyzer

Builds and visualises directed #include dependency graphs from CMake/Ninja builds. It re-runs each compilation unit with -H -fsyntax-only to obtain the exact include hierarchy the compiler sees — no preprocessing guesswork — then merges all per-TU trees into a single deduplicated graph.

  • Python 3.10+

  • uv (or pip)

  • A CMake/Ninja build directory containing compile_commands.json

    Enable it in CMake with -DCMAKE_EXPORT_COMPILE_COMMANDS=ON, or add set(CMAKE_EXPORT_COMPILE_COMMANDS ON) to your CMakeLists.txt.

  • cloc (optional) — used for lines-of-code metrics in the HTML view. Install with your package manager (apt install cloc, brew install cloc, etc.).

git clone https://github.com/tobiaskaestner/dep-analyzer.git
cd dep-analyzer
uv sync

After uv sync the dep-analyzer command is available inside the project's virtual environment:

uv run dep-analyzer --help

Or activate the environment first:

source .venv/bin/activate
dep-analyzer --help
# Open the interactive graph in your browser (builds on the fly)
dep-analyzer serve build/blinky

# Generate a self-contained HTML file instead
dep-analyzer build --html --out graph.html build/blinky

Runs the include-graph extraction and emits output in the requested format.

dep-analyzer build [BUILD_DIR] [FORMAT] [--out FILE]
                   [--exclude PREFIX]... [--only PREFIX]...
                   [-j N] [--cluster-depth N]
BUILD_DIR
Path to the Ninja build directory (the folder containing compile_commands.json). Defaults to auto-detection: tries the current directory, then <script-dir>/build/blinky.
--out FILE
Write output to FILE instead of stdout.

Output formats (mutually exclusive, default: --json):

Filtering:

--exclude PREFIX
Drop any edge where either endpoint starts with PREFIX. Repeatable. Useful for removing SDK or system headers from the graph.
--only PREFIX
Keep only edges where the source node starts with PREFIX. Repeatable. Useful to focus on a specific subsystem.

Performance:

-j N / --jobs N
Number of parallel compiler invocations (default: CPU count).

Visualisation:

--cluster-depth N
Controls how many leading path components are used to group nodes into compound clusters in the HTML view (default: 3). Increase for finer-grained grouping, decrease for a flatter layout.

Builds the graph (or loads a pre-built payload) and starts a local Flask server. Open the printed URL in any browser.

dep-analyzer serve [BUILD_DIR] [--elements FILE]
                   [--host HOST] [--port PORT]
                   [--exclude PREFIX]... [--only PREFIX]...
                   [-j N] [--cluster-depth N]

Accepts the same BUILD_DIR, --exclude, --only, -j, and --cluster-depth options as build, plus:

--elements FILE
Skip the build step and load a pre-built elements JSON produced by a previous dep-analyzer build --html run or saved payload. Useful to avoid recompiling when iterating on the visualisation.
--host HOST
Network interface to bind to (default: 127.0.0.1). Use 0.0.0.0 to expose the server on all interfaces.
--port PORT
TCP port (default: 8421).
# Live server — graph builds on the fly, open http://127.0.0.1:8421/
dep-analyzer serve build/blinky

# Self-contained HTML for sharing (no server needed)
dep-analyzer build --html --out graph.html build/blinky

# Expose the server to the local network on port 9000
dep-analyzer serve --host 0.0.0.0 --port 9000 build/blinky

# Two-phase workflow: build once, serve repeatedly without recompiling
dep-analyzer build --html --out /tmp/payload.html build/blinky
dep-analyzer serve --elements /tmp/payload.html
# Only show edges that originate inside the application source tree
dep-analyzer build --html --out app-only.html \
    --only /path/to/workspace/app build/blinky

# Exclude the Zephyr SDK toolchain headers
dep-analyzer build --stats \
    --exclude /path/to/zephyr-sdk build/blinky

# Combine: show app sources, excluding generated files
dep-analyzer serve \
    --only /path/to/workspace/app \
    --exclude /path/to/workspace/build \
    build/blinky
# Shallow clusters (2 levels) — less nesting, faster layout
dep-analyzer serve --cluster-depth 2 build/blinky

# Deep clusters (5 levels) — mirrors directory structure closely
dep-analyzer build --html --cluster-depth 5 --out deep.html build/blinky
# Limit parallelism to 4 compiler processes
dep-analyzer build --stats -j 4 build/blinky

# Use all available CPUs (default — explicit here for clarity)
dep-analyzer serve -j 0 build/blinky
# JSON adjacency list to stdout
dep-analyzer build --json build/blinky

# JSON saved to a file
dep-analyzer build --json --out graph.json build/blinky

# CSV edge list
dep-analyzer build --csv --out edges.csv build/blinky

# GraphViz DOT — render to SVG
dep-analyzer build --dot --out graph.dot build/blinky
dot -Tsvg graph.dot -o graph.svg

# Per-category statistics summary
dep-analyzer build --stats build/blinky

# Cycle / SCC analysis
dep-analyzer build --cycles build/blinky

The HTML view (both --html and serve) provides:

Graph

  • Compound nodes group files by directory (depth controlled by --cluster-depth).
  • Node colour encodes category (app / zephyr / modules / sdk / generated / other) and file type (light = .h, dark = .c/.S).
  • Click any file node to highlight it and its neighbours. Click again to clear. Click the background to clear.

Sidebar — Interaction panel

  • grab nodes / grab compounds — toggle drag for file nodes and cluster boxes independently.
  • edges interactive — when off (default), edges are invisible to the mouse so they cannot be accidentally grabbed.
  • highlight incoming / highlight outgoing — choose which edge directions are shown when a node is selected.
  • transitive closure — available when exactly one direction is chosen; follows edges recursively instead of showing only direct neighbours.
  • max depth — limits transitive traversal to N hops (empty = unlimited).
  • Space-bar hold or right-mouse-drag to pan the canvas.

Sidebar — Layout settings

All fcose layout parameters (inner/outer edge length, node repulsion, separation, iterations, tiling padding, randomise seed) are exposed as live sliders. Click Run layout to re-run with the current values.

Sidebar — Node weight

Map any per-file metric to node size:

  • File size (bytes)
  • Lines of code / total lines / comment lines / blank lines (via cloc)
  • Incoming edges (fan-in) / outgoing edges (fan-out)

Supports linear and log scale, plus min/max clamp inputs to handle outliers without distorting the rest of the graph.

Search

Type in the search box to highlight all nodes whose filename or path contains the query string.

src/dep_analyzer/
├── cli.py          — argument parsing, subcommand dispatch
├── build.py        — GCC -H invocation, include-edge extraction
├── graph.py        — Tarjan SCC, DAG longest path, adjacency list
├── classify.py     — file categorisation, colours, edge filtering
├── metrics.py      — file size and lines-of-code collection (cloc)
├── cluster.py      — compound-node hierarchy builder
├── server.py       — Flask dev server
├── formats/
│   ├── elements.py — Cytoscape element-list builder (shared by html + serve)
│   ├── html.py     — standalone HTML output (inlines web assets)
│   ├── dot.py      — GraphViz DOT
│   ├── json_.py    — JSON adjacency list
│   ├── csv_.py     — CSV edge list
│   ├── stats.py    — per-category statistics
│   └── cycles.py   — SCC / cycle report
└── web/
    ├── index.html  — page shell (no inline content)
    ├── style.css   — Catppuccin Mocha dark theme
    └── app.js      — Cytoscape.js graph, all interaction logic

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors