added missing files to MANIFEST
[deps.git] / README
blob96551bf009ee6fbea36246261a193fe28e3faff1
2                 graph-includes toolkit
3                 ======================
5 IN SHORT
6 --------
8 Graph-includes creates a graph of dependencies between source-files
9 and/or groups of source-files, with an emphasis on getting readable
10 and usable graphs even for large projects.
12 Usability of the dependency graphs are currently improved by:
13 - customizable grouping of several source files into a single node
14 - transitive reduction of the graph
16 It currently supports graphing the C/C++ #include relationship, using
17 graphviz.
20 IMPORTANT NOTICE
21 ----------------
23 This tool has evolved from a 50-line script written for a particular
24 project (Battle for Wesnoth).  Although it has been generalized much,
25 there are still somewhat ad-hoc heuristics harcoded here and there,
26 especially in the default project class (see class descriptions below).
28 Although work is under way to make this tool as generic as possible,
29 work still has to be done at all levels.  It is still under
30 development, and may not suit your needs (at least, not yet).
33 INSTALLATION INSTRUCTIONS
34 -------------------------
36 Like standard perl packages.  Eg:
38 $ perl Makefile.PL prefix=/usr/local
39 $ make
40 $ su
41 # make install
44 New versions can be found at http://ydirson.free.fr/soft/graph-includes/.
47 HOW TO TAKE ADVANTAGE OF THIS TOOL TO IMPROVE YOUR CODE
48 -------------------------------------------------------
50 1. on the spirit of dependency cleanup
52 When developping a project of medium size (we'll talk mostly C/C++
53 here, but that will apply to most languages), expecially with many
54 people writing code, it is quite easy to get to a point where each
55 file (out of several tens of hundreds of files) depends on too many
56 other files.
58 The most obvious relation is the #include one.  The more #includes a
59 file has, the more time it takes to build - especially when those
60 included files #include themselves a bunch of other files.  For a
61 project of about 100 files, just producing a graph of all those files,
62 with arrows representing the #include dependencies, will usually give
63 an unreadable graph, and will show very little about possible
64 improvements.
66 A less obvious relation appears more clearly when you consider not
67 files by themselves, but the set of files made of an interface and the
68 matching implementation.  Let's consider two such sets, made of the
69 files a.h, a.c, b.h, b.c.  a.c includes b.h, and b.c includes a.h, and
70 each implementation, following good practice, includes its own
71 interface.  A simple dependency graph as described above would show
72 such a graph:
74         a.c -> b.h              
75            \  /|
76             \/
77             /\
78            /  \|
79         b.c -> a.h
81 If OTOH we represent those sets of files instead of the files
82 themselves, we now have something like:
84         a <--> b
86 This shows much more clearly that those two modules are intrinsicately
87 related.  In many cases, this will express that whenever you use the
88 a.o file resulting from the build of a.c, you'll need to link b.o as
89 well, and vice versa.  This will be the case when each file uses the
90 headers to get function prototypes.  Then hunting for abusive
91 dependencies will allow, for example, to select with finer grain which
92 of those modules of code will need to go into which executable, thus
93 producing lighter executables.
95 In other cases, headers would just have been used to access a type
96 definition from b.h, and the associated b.o would not be needed.  In
97 such cases, you may want to consider splitting such "low-level"
98 declarations into their own headers.  Not only this would simplify the
99 graph, allowing you to get a better grasp on your source code, but it
100 can also lead to faster compilations, since each file will be able
101 include less unrelated definitions.
104 2. possible strategies to help locating abusive dependencies
106 More to be written.
110 COMMAND-LINE USAGE
111 ------------------
113 See "graph-includes --help".
115 1. output type
117 The default output is a .dot file on standard output, suitable for
118 formatting by dot (from the graphviz toolkit), or interactive editing
119 by dotty (also from graphviz).
121 You can ask graph-includes to do the formatting for you, eg. using
122 "--output=<file>.<suffix>".  It will run "dot -T<suffix>", so that
123 "--output=mydeps.ps" or "--output=mydeps.jpg" will have the expected
124 behaviour.  If your suffix is not known to dot, it will complain
125 itself, so asking for --output=foo.bar will cause a message like:
127 Warning: language bar not recognized, use one of: canon cmap cmapx dia dot fig gd gd2 gif hpgl imap ismap jpeg jpg mif mp pcl pic plain plain-ext png ps ps2 svg svgz vrml vtx wbmp xdot
129 If you intend to print the result on paper, the default layout will
130 likely be too large.  You can use --paper=a4 to select parameters that
131 will produce a smaller graph and spilt it into pages.  This flag also
132 changes the default output format to postscript.  Be warned that dot
133 may not honor the page-splitting parameter for all output formats.
135 Since the transitive reduction can take time, you may like the
136 --verbose switch, which will show a progress bar.
139 2. what to draw
141 The files to be analyzed are given as non-option arguments, and are
142 typically generated by a "find" command.  Eg:
144         $ graph-includes `find src -name '*.[ch]'`
146 In order to tell the #include resolver where to look for included
147 files, you can use the cpp-like -I (aka. --Include) flag.  Eg:
149         $ graph-includes -I src `find src -name '*.[ch]'`
151 Dependencies not found in the project (ie. files appearing in #include
152 but not given on command-line) are listed as "not found" in the
153 graph-includes.report file for diagnostics purposes, unless they are
154 found in a system directory.  System directories are declared in a
155 similar fashion, with the --sysInclude option.  Eg:
157         $ graph-includes -I src -sysI /usr/include `find src -name '*.[ch]'`
159 To avoid having useless information on the graph,
160 --prefixstrip=<prefix> can be used to avoid repeating a given prefix
161 in all node labels.  Typically:
163         $ graph-includes --prefixstrip=src/ `find src -name '*.[ch]'`
165 Files will be grouped in a hierarchy of groups, level 0 groups
166 typically containing just one file.  Groups are defined by the
167 selected project class, selected by the --class=<class> option.  See
168 below for descriptions of the project classes available by default,
169 and for instructions to write customized project classes.
171 The range of group levels to be drawn is selected with
172 --group=<min>-<max>, which defaults to 1-1.  Eg, for class "default",
173 whose group levels are defined as:
175 0: one file per group
176 1: what/ever.* go into a "what/ever" group (usually interface + implementation)
177 2: what/* go into a "what" group, supposing directories denote modules of some sort
179 Group levels below "min" or above "max" are not displayed as nodes.
180 Groups of level "min" are drawn as nodes of the graph.  If "max" is
181 strictly greater than "min", then groups of levels "min+1" through
182 "max" are drawn as box clusters containing lower-level groups.
184 Since such a way of grouping nodes will not improve the readability in
185 projects where the inter-groups dependencies have not been cleaned up
186 yet, higher-level groups can instead be colored, using a class-defined
187 color scheme, possibly modified by "--color <n>:<label>=<color>[,<label>=<color>...]"
188 options, where <n> is the group level in which the group name <label> will
189 receive a background of the specified color, which can be defined
190 either by a named X11 color (like "blue" or "palegreen"), or by a RGB
191 color using the standard X11 "#RRGGBB" syntax.
194 For those wanting to see what edges the transitive reduction dropped,
195 the --showdropped will add them to the graph in a different color.  Be
196 prepared for your computer room to get a noticeable temperature
197 increase for anything else than a small set of files with only few
198 dependencies.
200 OTOH, --focus=<node-label> will do the same, but only for the
201 dependencies of a specified node.  That should prevent the nasty
202 effects described above, and will be useful for various purposes,
203 including debugging the transitive reducer.  The node-label refers to
204 a node in the lowest group-level drawn, ie. the "min" argument to
205 --group.
207 People still getting cold may also like to circumvent the
208 transitive-reduction engine completely, using --alldeps.  The author
209 assumes no responsibility for losses of mental health induced by
210 trying to make any serious use of the resulting graph.
213 EXISTING PROJECT CLASSES
214 ------------------------
216 1. class "default"
218 As implied by its name, it is the one which will be used unless you
219 use the --class option.  Although it is the default one, it may still
220 be quite rough at the moment, still using some ad-hoc heuristics, and
221 will be improved in the near future.  Here are its main
222 characteristics:
224  - looks at C-style #include lines
225  - creates level-1 groups for all files sharing the same path and
226    (disregarding the suffix) filename.  Eg, files "foo/bar.c" and
227    "foo/bar.h" would be grouped in a "foo/bar" level-1 group.
228    In clear, it won't connect include files if they are all located
229    in an include/ directory.
230  - creates by-directory level-2 groups.  Eg. in the above example, a
231    group "foo" would exist at level-2.
234 2. class "uniqueincludes"
236 Built on top of the default class, it is meant for projects where file
237 names are kept unique across all directories.  If the ad-hoc #include
238 processing of the default class does not suit your project, it is the
239 only out-of-the-box alternative available today.  Here are its main
240 characteristics:
242  - provides a single grouping level based on filenames, disregarding
243    all the directory hierarchy.
245 Note that it is not meant for general use, as:
247  - it will group any files with the same name in the same level-0
248    group, possibly causing confusion.
249  - it does not make any directory name appear in the node names
252 DEFINING YOUR OWN PROJECT CLASS
253 -------------------------------
255 See graphincludes::project::wesnoth in the examples/ dir as an example.
257 Keep in mind that the API is not frozen yet, and will probably be
258 overhauled more than once before an official API gets blessed.
261 CAVEATS
262 -------
264 - this script only handles explicitely-declared dependencies, it
265   won't detect it if eg. a prototype cut'n'paste was used instead of
266   using the correct #include, but you shouldn't do that anyway :)
269 TODO
270 ----
272 - misc improvements
273  - automate --help production (see Pod::Usage ?)
274  - make default project-class consider multiple levels of directories
275    as group levels, but only if they (consistently ?) have multiple
276    subgroups ?
277  - write more documentation
278  - continue merging the verbose/debug behaviour into the global report file.
279  - write a linux-kernel class as example :)
280  - use an existing source of paper formats (libpaper, LC_PAPER, whatever)
281  - find out how to use this damn Exporter mechanism for
282    graphincludes::params, or find another way of getting rid of those
283    "used only once" warnings.
284  - maybe use graphviz' tred(1) to check our transitive reductions.
285  - write a testsuite.
286 - modularization (finish the restructuring into a cleaner and more modular design)
287   + allow coloring other things than just level 2
288   - write a perl extractor
289   - graph output syntax (allow to generate tulip graphs)
290   - provide a simple hash-based filelabel implementation
291   + find the accessory classes as easily as possible (like nagios-plugins ?)
292   - separate styling from project classes
293   - allow to define several views in a project-class, several of which
294     can be generated by default.
295   - find out whether we can declare protocols/pure-virtual-classes in
296     some way, to cleanup the class graph
297   - generalize --prefix-strip
298   - give consistent access to all commonly-needed features through
299     command-line and class customization
300   - ensure in the testsuite that all provided non-abstract classes are
301     self-contained
302 - write an openc++-based dependency extractor
303  - extract more fine-grained dependency (depending on a header does
304    not necessarily imply depending on code)
305  - handle (warn about) the case where the declarations for a given
306    implementation file are scattered in more than one header
307  - detect undeclared dependencies (eg. manually inserted prototypes)
308  - check necessity of declared includes
309 - presentation
310   - generalize the special_edge() mechanism (use a hash of edge attributes ?)
311   - allow different node shapes when mixing high-level nodes with
312     lower-level ones through the default singleton groups
313     (special_node mechanism similar to the special_edge one ?)
314   + optionally show labels or count for files (subnodes) in a node and
315     color arcs according to them
316   - optionally show external deps (deps on files not on command-line)
317   - limit graph to one or more given group(s) of files (specified by <level>:<label>)
318   - draw cycles in a given color
319   - draw a specific path
320   - allow setting fg color for a specific group level
321   - provide automatic coloring schemes
322   - color intra-group edges with the same color as nodes (post-processing ?)
323   - allow to request drawing of who in a high-level node points to
324     another node (ie. violates some constraint)
325   + label edges with the number of explicit inclusions flowing through them
326   - propagate excuses in some way when they are dropped by the transitive reducer
327   - provide tools for automatic grouping (eg. using cycles, or selected external deps)
328   - investigate candidate tools for hyperbolic layout ?
329 - CLI improvements
330   + recursive directory search to avoid long command-lines
331   - provide an initial list of system directories to avoid repeating them (ask compiler)
332 - provide an interactive tool to help understanding a project's
333   structure.  Maybe with graphviz' lefty, or as a specialized tulip
334   gui ?
335 - bugs
336   - --showdropped mode draws too many edges as dropped (ie. does not
337     consider marked edges as dropped when deciding whether to consider
338     subsequent edges as dropped)
339   - when showing only 3-3, colors from level 2 get propagated to level-3 groups
340   - transitive reduction may not be complete, some more edges could
341     possibly be dropped - wesnoth tree at 2005-03-25 exhibits the problem
342     with the "display -> builder -> animated -> image" path
345 LICENSE
346 -------
348     Copyright (c) 2005 Yann Dirson <ydirson@altern.org>
350     This program is free software; you can redistribute it and/or modify
351     it under the terms of the GNU General Public License, version 2,
352     as published by the Free Software Foundation.
354     This program is distributed in the hope that it will be useful,
355     but WITHOUT ANY WARRANTY; without even the implied warranty of
356     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
357     GNU General Public License for more details.