The following shell script can be executed in the root directory of DCMTK's source code. It uses Graphviz and some common unix tools to generate the following output image:

This image represents the dependencies between the individual modules of the DCMTK. As such, the dependencies of the individual apps are ignore and only the libraries are analyzed.

What you can see is, for example, that the module dcmsr depends on the modules dcmdata, oflog, ofstd and config. On the other hand, the module dcmpstat needs dcmsr.

#!/bin/sh

# List of modules to parse
MODS="ofstd oflog dcmdata dcmimgle dcmimage dcmjpeg dcmjpls dcmtls dcmnet dcmsr dcmsign dcmwlm dcmqrdb dcmpstat"

# List of dependencies to ignore. This is necessary because e.g. oftest.h in
# ofstd/ includes a header from dcmdata, but only if some define is set first,
# which it never is in ofstd.
# This works by ignoring a dependency from A to B if "A B" is in this list
IGNORE="ofstd dcmdata|ofstd oflog|dcmnet dcmtls"

DOT=$(mktemp)
trap 'rm $DOT' EXIT

graph()
{
    echo "$@" >> $DOT
}

graph "digraph deps {"
graph " concentrate=true;"

DIRS=""
for x in ${MODS}
do
    DIRS="${DIRS} ${x}/libsrc/ ${x}/include/"
done

echo "Parsing includes..."

for x in $(find ${DIRS} -name '*.cc' -or -name '*.h')
do
        grep -H '#include ["<]\(\.\./\.\./[d]\|dcmtk\)' "${x}" | \
        sed -e 's_\([a-z0-9]*\)/[^:]*:#include .dcmtk/\([a-z0-9]*\)/.*$_\1 \2_' | \
        sed -e 's_\([a-z0-9]*\)/[^:]*:#include .\.\./\.\./\([a-z0-9]*\)/.*$_\1 \2_'
done | sort -u | grep -vE "$IGNORE" | \
    awk '
        {
            if ($1 != $2)
                deps[$1] = deps[$1] " " $2
        }
        END {
            for (moda in deps) {
                split(deps[moda], dep, " ")
                for (modb in dep) {
                    # Ok, moda depends on dep[modb], but does some other module
                    # moda depends on depend on dep[modb] too...
                    need = 1
                    for (modc in dep) {
                        if (modb == modc)
                            continue
                        split(deps[dep[modc]], d, " ")
                        for (modd in d) {
                            if (d[modd] == dep[modb]) {
                                # moda depends on dep[modb]
                                # moda depends on dep[modc]
                                # dep[modc] depends on dep[modb]
                                # -> Another module pulls this in
                                # (Or we have a cyclic graph and not a DAG)
                                print "# " moda " needs " dep[modb] " but " dep[modc] " already pulls it in"
                                need = 0
                                break
                            }
                        }
                        if (!need)
                            break
                    }
                    if (need)
                        print "    \"" moda "\" -> \"" dep[modb] "\";"
                }
            }
        }' >> $DOT

graph "}"

cat $DOT

echo "Generated input, now generating output"

#EXT=svgz
EXT=png
OUT=deps.$EXT
dot -o "$OUT" -T$EXT < $DOT && echo "Generated $OUT"
 
dcmtk/modules/dependency-script.txt · Last modified: 2011/10/21 11:04 by schlachter
 
Except where otherwise noted, content on this wiki is licensed under the following license:Public Domain
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Run by Debian Driven by DokuWiki