Skip to content

Looking to create a program to help me graph out C/C++ include dependencies. This seems to be needed super often for me.

License

Notifications You must be signed in to change notification settings

andy31415/igraph

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

189 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Include dependendcy viewer

This program generates dot graph descriptions for include headers for c/c++.

The intent is to visualize dependencies among files.

Functionality

  • select what files to parse
  • define how to group to viewed files
  • abiltiy to compile database files to figure out imports. These files can be generated by gn/cmake/other tools.
  • abiltiy to use gn to auto-group headers

Examples

Here is an example complex include graph:

Include dependencies

Here is an example of how a complex zoomed-in dependency group looks like:

Include dependencies

Building

This is a standard rust binary:

  • cargo build --release will generate an output in target/release/include-graph
  • cargo run -- <args-here> can be used to run in-place (and debug)
  • cargo test or cargo nextest run will execute some the integrated unit tests (increasing test coverage is still a work in progress)

Usage

# Simple run using a configuration database
# if no `output` is provided, the output will go to standard out
include-graph -c configfile.txt -o outfile.dot

# You should generate the graph using graphviz/dot
# For example for the above `outfile.dot`:
dot -T svg -o outfile.svg outfile.dot

# If you install watchexec, you can setup a pipeline like:
watchexec -e txt -- "include-graph -c cfg.txt -o out.dot && dot -Tsvg -o out.svg out.dot"

Configuration file format

Here is an example configuration file with comments

# Comments start with `#` and last to the end of the line

# Variables are declared first and you can nest variables
# Expansion is specifically `${name}` (this is not shell, so `$name` will not work)
SOURCE_ROOT=/some/path/to/source
OUTPUT_ROOT=${SOURCE_ROOT}/build/out

# The input section describes what files are to be parsed.
#   - what include path  should be searched for `#include "foo.h"`
#   - what files to be parsed using glob rules
input {
    # You may include a compile_commands database which will parse
    # includes (find `-I` arguments to a compiler) or sources.
    #
    # Note that compildb may not include all sources in a directory
    # in which case you should use GLOB for full coverage
    from compiledb ${OUTPUT_ROOT}/compile_commands.json load include_dirs
    from compiledb ${OUTPUT_ROOT}/other_compile_commands.json load sources
    from compiledb ${OUTPUT_ROOT}/third.json load sources, include_dirs
    
    # You may also manually include single directories
    include_dir ${SOURCE_ROOT}/includes/test
    include_dir /third/party/lib

    # Globs are generally including all files. program filters
    # out based on extensions (h, hpp, c, cpp, cxx, cc)
    glob ${SOURCE_ROOT}/src/lib1/**/*
    glob ${SOURCE_ROOT}/src/lib2/**/*
}

# The graph section defines how to setup the graph.
graph {
   # The tool works with absolute paths when parsing includes
   # the `map` section describes how to shorten typically long
   # absolute paths like `/home/user/devel/some/path/....`
   map {
      # Replace some long poath with a short prefix
      ${SOURCE_ROOT}/src/lib1 => first::
      ${SOURCE_ROOT}/src/lib2 => second::

      # This defines what items to actually keep in the output. Not
      # all includes are kept as they would be generally too large.
      #
      # Only prefix-paths are used here
      keep first::
      keep second::

      # Explicitly remove some of the kept items
      drop first::tests/
      drop second::support/library
   }

   # The group section defines how the graph should place
   # things together for easy dependency view.
   # Group logic:
   #   - they must be in order of application
   #   - first group wins (a file belongs to one group only)
   group {
      # This loads build targets from GN:
      #  - compile_root is where the `gn` too will be pointed to
      #  - target defines what GN target to grab `sources` from
      #  - sources will translate gn paths of `//foo` into absolute
      #    system paths
      gn root ${OUTPUT_ROOT} target //src/app/* sources ${SOURCE_ROOT}

      # Groups can be manually defined to group some files
      manual group-name-here {
         # Grouping is done by mapped names
         first::platform/Header.h
         first::platform/Src.cpp
         first::Something.cc
       }

      # Manual groups may have an optional color
      manual group-name-here color lightblue {
        # Grouping is done by mapped names
        first::some/other_header.h
      }
      
      # Optional instructions to ensure headers and sources
      # are grouped together (as they are generally included in
      # the same compilation unit)
      group_source_header
   }

   # you can optionally provide instructions for edge coloring
   color edges {
     from some_group_name red

     # color may be prefixed with "bold" for a bold edge coloring
     to other_group_name bold blue
   }

   # If zoom is non-empty it generates a separate area
   # with the specified "groups" expanded and viewing individual
   # members and dependencies
   zoom {
     # The zoom takes the group name argument, which could
     # be the GN group name or the manual group name
     //src/library:support
     group-name-here
     
     # Focus prefix means to focus on determining dependencies
     # in and out of the specified group(s).
     #
     # Dependences from other zoomed items will only be show
     # if internal or they start/end in a focused zoo group
     focus: //src/library:foo
     focus: //src/something/else:else
   }
}

Debug logging

The program uses env_logger for log configuration.

You can set RUST_LOG environment variable to control some more verbose loggin. Note that it can be very verbose.

Include processing

Use RUST_LOG=include-extract=info to print out all parsed include information

Use RUST_LOG=full-file-list=info to print out all files found by globbing for sources

Use RUST_LOG=gn-path=info to print out all files found by globbing for sources

Use RUST_LOG=compile-db=info to print out information parsed from the compilation database Use RUST_LOG=compile-db=debug to debug parsing of the compilation database

Releasing

Use cargo-smart-release via cargo install cargo-smart-release and then cargo smart-release.

Use cargo smart-release -h for smart release flags.

About

Looking to create a program to help me graph out C/C++ include dependencies. This seems to be needed super often for me.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •  

Languages