Canonicalize path names to prevent issues with ./
[deps.git] / doc / README.dbk.xml
blob791dc8607d6b6fbfcbf968bc05aeb3532d44c768
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
4 <article id="deps" lang="en">
5   <articleinfo>
6     <title>DEPS</title>
7     <subtitle>Dependency Extraction and Processing System</subtitle>
8     <subtitle>Formerly <emphasis>graph-includes
9         toolkit</emphasis></subtitle>
11     <author>
12       <firstname>Yann</firstname>
13       <surname>Dirson</surname>
14       <email>ydirson@altern.org</email>
15     </author>
17     <legalnotice>
18       <simpara>This program is free software; you can redistribute it
19       and/or modify it under the terms of the GNU General Public
20       License, version 2, as published by the Free Software
21       Foundation.</simpara>
23       <simpara>This program is distributed in the hope that it will be
24       useful, but WITHOUT ANY WARRANTY; without even the implied
25       warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
26       See the GNU General Public License for more details.</simpara>
27     </legalnotice>
29     <copyright>
30       <year>2005</year>
31       <year>2006</year>
32       <holder>Yann Dirson</holder>
33     </copyright>
34   </articleinfo>
36   <section>
37     <title>In short</title>
39     <simpara>DEPS is a set of perl libraries which allows to extract
40     dependency information from arbitrary material (eg. program source
41     files), apply various transformations on this graph to make it
42     more readable or put emphasis on one aspect of it, and draw
43     it.</simpara>
45     <simpara>The <command>graph-includes</command> tool is the current
46     command-line interface to DEPS.  It is quite limited, in that it
47     only extracts dependency information from files, and applies
48     predefined transformations, on which the user has limited
49     influence through flags.  A more generic tool is planned, but will
50     probably wait until various aspects of the DEPS design
51     gets finalized.</simpara>
53     <para>Currently available graph transformations are:
54       <itemizedlist>
55         <listitem><simpara>multi-level grouping of source
56         files</simpara></listitem>
58         <listitem><simpara>consolidation of groups of different
59         levels, effectively allowing to show eg. files not in any
60         group</simpara></listitem>
62         <listitem><simpara>transitive reduction, drastically reducing
63         the number of edges to be drawn</simpara></listitem>
65       </itemizedlist>
66     </para>
68     <simpara>It currently supports graphing the C/C++ #include
69     relationship, and to a certain extent perl inter-module
70     dependencies, using graphviz or tulip.</simpara>
72   </section>
74   <section id="notice">
75     <title>Important notice</title>
77     <simpara>This tool has evolved from a 50-line script written for a
78     particular project (<ulink url="http://wesnoth.org/">Battle for
79     Wesnoth</ulink>).  Although it has been generalized much, there
80     are still somewhat ad-hoc heuristics harcoded here and there,
81     especially in the default project class (see class descriptions
82     below).</simpara>
84     <simpara>Although work is under way to make this tool as generic
85     as possible, work still has to be done at all levels.  It is still
86     under development, and may not suit your needs (at least, not
87     yet).</simpara>
89   </section>
91   <section id="install">
92     <title>Installation instructions</title>
94     <simpara>Be sure you have a recent version of Perl installed.  At
95     least List::Util is missing from versions earlier than 5.8.  You
96     can also just fetch this additional package from CPAN if you
97     cannot upgrade.  If you notice that another package is missing
98     from your installation, please report it, so it can be listed
99     here.</simpara>
101     <simpara>Other required perl modules:</simpara>
102     <itemizedlist>
103       <listitem>
104         <simpara><ulink
105         url="http://search.cpan.org/~samv/Set-Object/">Set::Object</ulink></simpara>
106       </listitem>
107     </itemizedlist>
109     <para>Installation is like many other perl packages:</para>
110     <example>
111       <title>Sample install session</title>
112       <literallayout><prompt>$</prompt> perl Makefile.PL prefix=/usr/local
113 <prompt>$</prompt> make
114 <prompt>$</prompt> su
115 <prompt>#</prompt> make install</literallayout>
116     </example>
118     <simpara>Be sure that the directory in which the library modules
119     got installed is in your perl library path.  Eg, if
120     <command>graph-includes --version</command> does not give the
121     expected result, try setting the <envar>PERL5LIB</envar>
122     environment variable to (in the above example)
123     <filename>/usr/local/share/perl/5.8.4/</filename>.</simpara>
125     <simpara>New versions can be found at
126     <uri>https://alioth.debian.org/projects/deps/</uri>.</simpara>
128     <simpara>A darcs repository is available at <uri
129     type="darcs">http://deps.alioth.debian.org/darcs/deps/</uri
130     >.</simpara>
132     <simpara>To be able to format the produced graphs, you will need
133     one of <ulink url="http://www.graphviz.org/">graphviz</ulink> and
134     <ulink url="http://www.tulip-software.org/"
135     >tulip</ulink></simpara>
137   </section>
139   <section id="howto">
140     <title>How to take advantage of this tool to improve your code</title>
142     <simpara>Graph-includes is only a supporting tool for a
143     refactoring effort.  It can be useful in helping a developper to
144     see where he should put its efforts in order to get cleaner and
145     saner dependencies in a project.</simpara>
147     <simpara>In this respect, it is quite similar to a microscope: if
148     you don't look at the right place, you won't see anything
149     interesting.  But if you start with a small magnifying factor, you
150     can locate regions of interest, and then zoom on those to get to
151     the interesting stuff.</simpara>
153     <section>
154       <title>On the spirit of dependency cleanup</title>
156       <section>
157         <title>First look at a dependency graph</title>
159         <simpara>When developping a project of medium size (we'll talk
160         mostly C/C++ here, but that will apply to most languages),
161         expecially with many people writing code, it is quite easy to
162         get to a point where each file (out of several tens of
163         hundreds of files) depends on too many other files.</simpara>
165         <simpara>The most obvious relation is the #include one.  The
166         more #includes a file has, the more time it takes to build -
167         especially when those included files #include themselves a
168         bunch of other files.  For a project of about 100 files, just
169         producing a graph of all those files, with arrows representing
170         the #include dependencies, will usually give an unreadable
171         graph, and will show very little about possible improvements.
172         This is why this tool has been written: to make it possible to
173         get to the useful information hidden in this unusable
174         dependency graph.</simpara>
175       </section>
177       <section>
178         <title>Looking further</title>
180         <simpara>A less obvious relation appears more clearly when you
181         consider not files by themselves, but the set of files made of
182         an interface and the matching implementation.  Let's consider
183         two such sets, made of the files a.h, a.c, b.h, b.c.  a.c
184         includes b.h, and b.c includes a.h, and each implementation,
185         following good practice, includes its own interface.  A simple
186         dependency graph as described above would show such a
187         graph:</simpara>
189         <literallayout class="monospaced"
190 >a.c -&gt; b.h
191    \  /|
192     \/
193     /   
194    /  \|
195 b.c -&gt; a.h</literallayout>
197         <para>If OTOH we represent those sets of files instead of
198         the files themselves, we now have something like:</para>
200         <literallayout class="monospaced"
201           >a &lt;--&gt; b</literallayout>
203         <para>This shows much more clearly that those two modules are
204         intrinsicately related.  In many cases, this will express that
205         whenever you use the a.o file resulting from the build of a.c,
206         you'll need to link b.o as well, and vice versa.  This will be
207         the case when each file uses the headers to get function
208         prototypes.  Then hunting for abusive dependencies will allow,
209         for example, to select with finer grain which of those modules
210         of code will need to go into which executable, thus producing
211         lighter executables.</para>
213         <simpara>Note that such a reciprocal dependency may not be
214         pathological.  Many projects tend to split a large module into
215         several files for clarity, even when those files are
216         inter-dependant.  It is much often in cycles of unidirectional
217         dependencies that we find dependencies that should not be
218         there.</simpara>
220         <simpara>In other cases, headers would just have been used to
221         access a type definition from b.h, and the associated b.o
222         would not be needed.  In such cases, you may want to consider
223         splitting such "low-level" declarations into their own
224         headers.  Not only this would simplify the graph, allowing you
225         to get a better grasp on your source code, but it can also
226         lead to faster compilations, since each file will be able
227         include less unrelated definitions.</simpara>
229       </section>
230     </section>
232     <section>
233       <title>Tuning the "files" and "includes" parameters</title>
235       <simpara>Your first run will surely looks somewhat
236       like:</simpara>
238 <literallayout class="monospaced">graph-includes -o project.ps src/ lib/</literallayout>
240       <simpara>You will take care of specifying all directories or
241       individual source files that make up your project.</simpara>
243       <simpara>In addition to an initial graph in the project.ps file,
244       which is quite likely to be incomplete by far, you will find a
245       file named project.ps.graph-includes.report.  It is a text file,
246       which will help us to finetune ou command-line.  Its first
247       section will look something like:</simpara>
249       <literallayout class="monospaced"
250 >General statistics:
251 -------------------
253 412 files, 353 nodes (14% dropped)
254 245 dependencies, 137 edges (44% dropped)
255 225 leaf node(s)
257 280 dependencies not found
258 0 dependencies identified as system headers</literallayout>
260       <simpara>As you can see, many dependencies are declared as "not
261       found".  What happens is quite similar to running a C compiler
262       without any -I flags: most header files are not
263       located.</simpara>
265       <simpara>We have in graph-includes two different flags to
266       specify paths where to look for the dependencies.  -I (aka
267       -Include) specifies directories that are part of the project,
268       and will allow to find all of our include-style dependencies.
269       OTOH, -sysI (aka -sysInclude) specifies system directories;
270       included files found in such a directory will of course not
271       result in an intra-project dependency, and will add no edge to
272       our graph, but will stop being displayed as part of the
273       "dependencies not found" count.  Thus, they will help us to see
274       how far we are from specifying all the -I flags.</simpara>
276       <simpara>Now you will most likely require several iterations of
277       adding -I/-sysI flags and checking the results.  But that alone
278       may not be sufficient to reach the ultimate "0 dependencies not
279       found":</simpara>
281       <itemizedlist>
282         <listitem>
283           <simpara>multi-platform source often have conditional
284           #include directives, and eg. win32 headers will probably not
285           be located on a Un*x box.</simpara>
286         </listitem>
287         <listitem>
288           <simpara>some generated files will require the source tree
289           to be configured in some way, or even to be partly or
290           completely built (eg. config.h generated by a "configure"
291           script, or Qt source generated by the meta-object
292           compiler)</simpara>
293         </listitem>
294       </itemizedlist>
296       <simpara>When you are confident that those remaining missing
297       dependencies are system headers for other platforms, you can go
298       on and look at the graph.</simpara>
300     </section>
302     <section>
303       <title>Possible strategies to help locating abusive
304       dependencies</title>
306       <simpara>Keeping in mind that we are essentially looking for
307       dependency loops, we expect to obtain in then end a graph that
308       will be wihout cycles, that is, with all (or, at least, most of)
309       arrows pointing from left to right in our graph.</simpara>
311       <simpara>Then we will look for those arrows pointing backwards,
312       as a sure sign for a cycle.  Remember that if the cycle is not a
313       long one, it may be legitimate; only if you judge that some of
314       the modules in this cycle are really unrelated, should your
315       consider it pathological.  Those backward arrows are not
316       necessarily directly pointing to the abusive dependency, but
317       they can surely be used to locate the culprit: by finding the
318       various cycles of which our backward arrows are part of, and
319       checking one by one all the dependencies in those cycles, you
320       can bet at least one that, with some work, could be
321       cleared.</simpara>
323       <simpara>Then, the way to modifications to do are really
324       dependant on your code.  Some possibilities include:</simpara>
326       <itemizedlist>
327         <listitem>
328           <simpara>removing an #include which is not necessary,
329           perhaps remaining from a revious code
330           reorganization</simpara>
331         </listitem>
332         <listitem>
333           <simpara>splitting a file in two parts, when you can easily
334           split the components of the file into distinct sets.  One
335           productive distinction to look for is to find a couple of
336           really high-level parts, that not all the parts depending on
337           this module would need.  This will most probably be related
338           to the dependency that you found abusive when looking at the
339           cycle in the graph.</simpara>
340         </listitem>
341       </itemizedlist>
342     </section>
343   </section>
345   <section id="arch">
346     <title>Tool architecture</title>
348     <section>
349       <title>Overview:</title>
351       <simpara>Graph-includes was initially developped with only a
352       handful of ideas, and then started to grow as I noticed where
353       useful things were missing.  That initial phase was useful for
354       me to get a grasp on the domain of dependency graphing, and
355       provided the ground for a (hopefully) decent design, which still
356       has to be completely implemented.</simpara>
358       <simpara>Together with blocking issues marked
359       <emphasis>+</emphasis> in the TODO list, the implementation of
360       this design shall be the goal for a 1.0 release.</simpara>
362       <simpara>The planned design is architectured as successive
363       layers, all of which should be pluggable to allow a high degree
364       of customization.</simpara>
366       <literallayout class="monospaced"
367 >   source locator
368          |
369          v
370   language selector
371          |
372          v
373 dependency extractor
374          |
375          v
376 graph transformations
377          |
378          v
379       styling
380          |
381          v
382    layout engine
383          |
384          v
385      rendering</literallayout>
387       <simpara>We will then be able to consider DEPS as being made of
388       a number of parts:</simpara>
390       <itemizedlist>
391         <listitem>
392           <simpara>core classes and glue, implementing the above
393           design</simpara>
394         </listitem>
395         <listitem>
396           <simpara>standard or third-party classes, doing the real
397           work</simpara>
398         </listitem>
399         <listitem>
400           <simpara>command-line and gui tools to allow easy use of the
401           whole</simpara>
402         </listitem>
403       </itemizedlist>
405       <simpara>This will hopefully make it easy for anyone to plug
406       their own work at any place in the architecture.</simpara>
408     </section>
410     <section>
411       <title>State of things</title>
413       <simpara>Currently, only the extractor, transformations, styling
414       and the renderer are properly customizable.</simpara>
416       <simpara>Language selectors are intermixed with extractors.  The
417       current source locator is a local-tree one (alternatives would
418       include SCM-aware locators), and takes parameters from
419       per-language extractors to find files.</simpara>
421       <simpara>Proper graph transformations were implemented for
422       transitive reduction, and for grouping using a compatibility
423       API.</simpara>
425       <simpara>Only node styling has been done for now, and a single
426       styler exists to set style attributes according to the group(s)
427       a node belongs to.  Edge labelling and the old "special edge"
428       mechanism have to be reimplemented in the form of edge
429       stylers.</simpara>
431       <simpara>There is no distinction (yet ?) between the layout
432       engine and the renderer.  In fact, it may not be easy to do
433       this, since most layout engines are tied to a particular
434       renderer.</simpara>
436     </section>
437   </section>
439   <section id="usage">
440     <title>Command-line usage</title>
442     <simpara>See "graph-includes --help".</simpara>
444     <section>
445       <title>output type</title>
447       <simpara>The default output is a .dot file on standard output,
448       suitable for formatting by dot (from the graphviz toolkit), or
449       interactive editing by dotty (also from graphviz).
450       Alternatively, a graph file for the Tulip graph visualizer can
451       be generated instead using "--renderer=tulip".</simpara>
453       <simpara>You can ask graph-includes to do the formatting for
454       you, eg. using "--output=&lt;file&gt;.&lt;suffix&gt;".  It will
455       run "dot -T&lt;suffix&gt;", so that "--output=mydeps.ps" or
456       "--output=mydeps.jpg" will have the expected behaviour.  If your
457       suffix is not known to dot, it will complain itself, so asking
458       for --output=foo.bar will cause a message like:</simpara>
460       <simpara>Warning: language bar not recognized, use one of: canon
461       cmap cmapx dia dot fig gd gd2 gif hpgl imap ismap jpeg jpg mif
462       mp pcl pic plain plain-ext png ps ps2 svg svgz vrml vtx wbmp
463       xdot</simpara>
465       <simpara>If you intend to print the result on paper, the default
466       layout will likely be too large.  You can use --paper=a4 to
467       select parameters that will produce a smaller graph and spilt it
468       into pages.  This flag also changes the default output format to
469       postscript.  Be warned that dot may not honor the page-splitting
470       parameter for all output formats.</simpara>
472       <simpara>Since the transitive reduction can take time, you may
473       like the --verbose switch, which will show a progress
474       bar.</simpara>
476     </section>
478     <section>
479       <title>what to draw</title>
481       <simpara>The files to be analyzed are given as non-option
482       arguments, and can be explicitely specified, or found by
483       recursing in directories.  Eg, to analyse foo.c in current
484       directory, as well as all C/C++ files in the src/ directory,
485       use:</simpara>
487 <literallayout class="monospaced">$ graph-includes foo.c src/</literallayout>
489       <simpara>When an directory argument is specified, it is searched
490       for files whose name matches a specific regexp pattern, whose
491       default value depends on the specified language (see --language
492       below).  This pattern can be overriden using the --fileregexp
493       option.  Eg, to match in addition to .c and .h files, those with
494       an additional .tmpl suffix, you could write:</simpara>
496 <literallayout class="monospaced">$ graph-includes -I src -fileregexp '\.[ch](\.tmpl)?$' src/</literallayout>
498       <simpara>How dependencies get extracted from the source files
499       depend on the language used in those files.  You can specify it
500       with the --language flag.  Default value is C (which should also
501       be used for other languages based on the C preprocessor, like
502       C++).  There is also some partial support for perl - see
503       comments in lib/graphincludes/extractor/perl.pm for more
504       details.</simpara>
506       <simpara>In order to tell the #include resolver where to look
507       for included files, you can use the cpp-like -I (aka. --Include)
508       flag.  Eg:</simpara>
510 <literallayout class="monospaced">$ graph-includes -I src src/</literallayout>
512       <simpara>Dependencies not found in the project (ie. files
513       appearing in #include but not given on command-line) are listed
514       as "not found" in the graph-includes.report file for diagnostics
515       purposes, unless they are found in a system directory.  System
516       directories are declared in a similar fashion, with the
517       --sysInclude option.  Eg:</simpara>
519 <literallayout class="monospaced">$ graph-includes -I src -sysI /opt/foo/include src/</literallayout>
521       <simpara>Language extractor have some knowledge about default
522       system include dirs: the C extractor knows about /usr/include,
523       and the Perl extractor asks perl itself.</simpara>
525       <simpara>To avoid having useless information on the graph,
526       --prefixstrip=&lt;prefix&gt; can be used to avoid repeating a
527       given prefix in all node labels.  Typically:</simpara>
529 <literallayout class="monospaced">$ graph-includes --prefixstrip=src/ src/</literallayout>
531     </section>
533     <section>
534       <title>how to draw</title>
536       <simpara>Files and their inter-dependency build up the first of
537       all graphs, named <emphasis>files</emphasis>.  Transformations
538       can then be applied to such graphs, producing new graphs.
539       Production of those new graphs define a <emphasis>transformation
540       graph</emphasis>, whose nodes are our graphs, and whose edges
541       denotes which graphs were used in producing which other
542       graphs.</simpara>
544       <simpara>Typically, files will be grouped in a hierarchy of
545       groups.  "Level 0 groups" typically containing just one file,
546       are the nodes of the <emphasis>files</emphasis> graph.  Groups
547       hierarchies are defined by the selected project class, selected
548       by the --class=&lt;class&gt; option.  See below for descriptions
549       of the project classes available by default, and for
550       instructions to write customized project classes.</simpara>
552       <note>
553         <simpara>In graph-includes 0.11 and earlier, when a given node
554         of level <emphasis>n</emphasis> is not part of a group at
555         level <emphasis>n+1</emphasis>, it still appears at that
556         level, as if it was the only member of a group.  This is not
557         the case any more.  To achieve a similar result in DEPS 0.12,
558         the relevant graphs must be merged using the
559         <emphasis>consolidate</emphasis> transformation.</simpara>
560       </note>
562       <simpara>The range of group levels to be drawn is selected with
563       --consolidate=&lt;min&gt;-&lt;max&gt;, which defaults to 1-1.
564       Eg, for class "default", whose group levels are defined
565       as:</simpara>
567       <glosslist>
568         <glossentry>
569           <glossterm>0</glossterm>
570           <glossdef>
571             <simpara>one file per group</simpara>
572           </glossdef>
573         </glossentry>
574         <glossentry>
575           <glossterm>1</glossterm>
576           <glossdef>
577             <simpara><filename>what/ever.*</filename> go into a
578             <filename>what/ever</filename> group (usually interface +
579             implementation)</simpara>
580           </glossdef>
581         </glossentry>
582         <glossentry>
583           <glossterm>2</glossterm>
584           <glossdef>
585             <simpara><filename>what/*</filename> go into a
586             <filename>what</filename> group, supposing top-level
587             directories denote modules of some sort</simpara>
588           </glossdef>
589         </glossentry>
590       </glosslist>
592       <simpara>Group levels below "min" or above "max" are not
593       displayed as nodes.  If a file is not a member of any group
594       between "min" and "max" levels, it will simply not be
595       represented.</simpara>
597       <simpara>Another way of using the grouping feature is to color
598       nodes according to the group(s) they belong to, using a
599       class-defined color scheme, possibly modified by
600       <userinput>--color
601       &lt;n&gt;:&lt;label&gt;=&lt;color&gt;[,&lt;label&gt;=&lt;color&gt;&#8230;]</userinput>
602       options, where &lt;n&gt; is the group level in which the group
603       name &lt;label&gt; will receive a background of the specified
604       color, which can be defined either by a named X11 color (like
605       "blue" or "palegreen"), or by a RGB color using the standard X11
606       "#RRGGBB" syntax.</simpara>
608       <simpara>The number of grouping levels to be colored is limited
609       by the renderer to be used.  As of 0.11, the dot renderer only
610       supports coloring 2 group levels.  Groups of a lower level than
611       the minimal level requested to --consolidate cannot be colored, for
612       obvious reasons.</simpara>
614       <simpara>For those wanting to see what edges the transitive
615       reduction dropped, the --showdropped will add them to the graph
616       in a different color.  Be prepared for your computer room to get
617       a noticeable temperature increase for anything else than a small
618       set of files with only few dependencies.</simpara>
620       <simpara>OTOH, <option
621       >--focus=<replaceable>node-label</replaceable ></option> will do
622       the same, but only for the dependencies of a specified node.
623       That should prevent the nasty effects described above, and will
624       be useful for various purposes, including debugging the
625       transitive reducer.</simpara>
627       <simpara>People still getting cold may also like to circumvent
628       the transitive-reduction engine completely, using --alldeps.
629       The author assumes no responsibility for losses of mental health
630       induced by trying to make any serious use of the resulting
631       graph.</simpara>
633     </section>
634   </section>
636   <section id="classes">
637     <title>Existing project classes</title>
639     <section>
640       <title>class "default"</title>
642       <simpara>As implied by its name, it is the one which will be
643       used unless you use the --class option.  Although it is the
644       default one, it may still be quite rough at the moment, still
645       using some ad-hoc heuristics, and will be improved in the near
646       future.  Here are its main characteristics:</simpara>
648       <itemizedlist>
649         <listitem>
650           <simpara>looks at C-style #include lines</simpara>
651         </listitem>
652         <listitem>
653           <simpara>creates level-1 groups for all files sharing the same
654             path and (disregarding the suffix) filename.  Eg, files
655             "foo/bar.c" and "foo/bar.h" would be grouped in a "foo/bar"
656             level-1 group.  In clear, it won't connect include files if
657             they are all located in an include/ directory.</simpara>
658         </listitem>
659         <listitem>
660           <simpara>creates by-directory level-2 groups.  Eg. in the
661             above example, a group "foo" would exist at level-2.</simpara>
662         </listitem>
663       </itemizedlist>
664     </section>
666     <section>
667       <title>class "uniqueincludes"</title>
669       <simpara>Built on top of the default class, it is meant for
670         projects where file names are kept unique across all directories.
671         If the ad-hoc #include processing of the default class does not
672         suit your project, it is the only out-of-the-box alternative
673         available today.  Here are its main characteristics:</simpara>
675       <itemizedlist>
676         <listitem>
677           <simpara>provides a single grouping level based on filenames,
678             disregarding all the directory hierarchy.</simpara>
679         </listitem>
680       </itemizedlist>
682       <simpara>Note that it is not meant for general use, as:</simpara>
684       <itemizedlist>
685         <listitem>
686           <simpara>it will group any files with the same name in the
687             same level-0 group, possibly causing confusion.</simpara>
688         </listitem>
689         <listitem>
690           <simpara>it does not make any directory name appear in the
691             node names</simpara>
692         </listitem>
693       </itemizedlist>
695     </section>
696   </section>
698   <section id="examples">
699     <title>Examples of use</title>
701     <section>
702       <title>Pure command-line examples</title>
704       <section>
705         <title>Graphing graph-includes itself:</title>
707         <literallayout>$ ./graph-includes -lang perl -I lib -prefixstrip lib/ -o deps.ps     graph-includes lib/</literallayout>
709         <simpara>graph-includes does not know in advance which classes
710           it will use</simpara>
711       </section>
713       <section>
714         <title>Rather clean ones:</title>
716         <simpara>a rather clean dependency graph</simpara>
718         <literallayout>Maelstrom-3.0.6$ graph-includes -v -sysI /usr/include/SDL     -I . -I ./netlogic -I ./maclib -I ./screenlib -o deps.ps .</literallayout>
720         <simpara>more work has to be put in the wesnoth example class:</simpara>
722         <literallayout>wesnoth-0.9.1$ graph-includes -v --class wesnoth --consolidate 1-1     -sysI /usr/include/c++/3.3 -sysI /usr/include/SDL     --prefixstrip src/ -I src -o deps.ps src/</literallayout>
724       </section>
726       <section>
727         <title>Examples only here as a reminder to write proper project
728           classes for them</title>
730         <para>needs supporting features for multi-arch source trees:</para>
732         <literallayout>qemu-0.7.0$ graph-includes -v -sysI /usr/include/SDL     $(find -name CVS -prune -o -type d -printf <emphasis>-I %p\n</emphasis>) -o deps.ps .</literallayout>
734         <para>needs proper file-grouping:</para>
736         <literallayout>mesag-6.2.1$ graph-includes -o -I ./include -I ./include/GL     -I ./src/mesa -I ./src/mesa/main -I ./src/glu/sgi/include     -I ./src/glu/sgi/libnurbs/internals -I ./src/mesa/glapi -o deps.ps .</literallayout>
738       </section>
739     </section>
741     <section>
742       <title>Customization examples</title>
744       <simpara>See graphincludes::project::wesnoth in the examples/
745       dir as an example of a custom project class.</simpara>
747       <simpara>Keep in mind that the API is not frozen yet, and will
748       probably be overhauled more than once before an official API
749       gets blessed.</simpara>
751     </section>
752   </section>
754   <section id="caveats">
755     <title>Caveats</title>
757     <itemizedlist>
758       <listitem>
759         <simpara>this script only handles explicitely-declared
760         dependencies, it won't detect it if eg. a prototype was
761         cut'n'pasted instead of using the correct #include, but you
762         shouldn't do that anyway :)</simpara>
763       </listitem>
764     </itemizedlist>
765   </section>
767   <section id="related">
768     <title>Related tools</title>
770     <simpara>A couple of tools may prove useful to be integrated with
771     DEPS.  Here are some ideas.</simpara>
773     <itemizedlist>
774       <listitem>
775         <itemizedlist>
776           <title>Through DEPS plugins</title>
777           <listitem>
778             <simpara>openc++ (http://opencxx.sourceforge.net/), which
779               provides a C++ parser library (still bad support for templates
780               in 2.8, IIRC)</simpara>
781           </listitem>
782           <listitem>
783             <simpara>synopsys (http://synopsis.fresco.org/), a
784               multi-language source code introspection tool</simpara>
785           </listitem>
786           <listitem>
787             <simpara>sparse
788               (http://kernel.org/git/?p=devel/sparse/sparse.git;a=summary),
789               Linux Torvald's C semantic parser</simpara>
790           </listitem>
791         </itemizedlist>
792       </listitem>
793       <listitem>
794         <simpara>OpenDX (http://www.opendx.org/), IBM's Visualization
795         Data Explorer</simpara>
796       </listitem>
797     </itemizedlist>
799     <simpara>I finally found a couple of tools out there, from which I
800     may borrow ideas some day.  I'd be happy to hear about more of
801     them.</simpara>
803     <itemizedlist>
804       <listitem>
805         <simpara>cinclude2dot, originally from Darxus
806         (http://www.chaosreigns.com/code/cinclude2dot/), then taken
807         over by F. Flourish (http://www.flourish.org/cinclude2dot/) is
808         a GPL C/C++-only tool, which apparently has support for
809         grouping, but not for transitive reduction.  Should I have
810         searched better, and found it a couple of months ago, maybe
811         graph-includes would have never been developped :)
812         </simpara>
813       </listitem>
814       <listitem>
815         <simpara>http://www.tarind.com/depgraph.html has a dependency
816         grapher for python, without transitive reduction as well.  It
817         does however allow customisation of project classes, somewhat
818         similar to graph-includes.</simpara>
819       </listitem>
820       <listitem>
821         <simpara>OptimalAdvisor
822         (http://javacentral.compuware.com/pasta/) is a refactoring
823         tool, which goes far beyond simple dependency analysis, but is
824         non-free/libre/open-source (also they have a
825         functionally-limited free/gratis edition) and seems to support
826         only java.</simpara>
827       </listitem>
828       <listitem>
829         <simpara>codeproject.com has some VisualStudio(tm) plugins
830         targetting C++, which I cannot test, but appear to scale badly
831         for large projects
832         (http://www.codeproject.com/csharp/DependencyGraph.asp).</simpara>
833       </listitem>
834     </itemizedlist>
835   </section>
837   <section id="todo">
838     <title>TODO</title>
839       <section>
840         <title>general</title>
842       <itemizedlist>
843         <listitem>
844           <simpara>consider using Set::Object instead of hashes for
845           sets</simpara>
846         </listitem>
847         <listitem>
848           <simpara>continue merging the verbose/debug behaviour into
849           the global report file</simpara>
850         </listitem>
851         <listitem>
852           <simpara>change case of class names when the API gets
853           stabilized</simpara>
854         </listitem>
855         <listitem>
856           <simpara>finalize filename portability support, using
857           File::Spec volume information (or, possibly better but using
858           non-core module, using Path::Class)</simpara>
859         </listitem>
860       </itemizedlist>
861     </section>
863     <section>
864       <title>core engine</title>
866       <itemizedlist>
867         <listitem>
868           <simpara>allow to associate attributes to files (eg. an ARCH
869           attribute for multi-architecture trees, like kernels,
870           development tools and emulators)</simpara>
871         </listitem>
872         <listitem>
873           <simpara>modularization (finish the restructuring into a
874           cleaner and more modular design)</simpara>
875         </listitem>
876         <listitem override="+">
877           <simpara>rework the recording of
878           edges to make them apply to files, not to graph nodes, since
879           more advanced features will need more flexibility</simpara>
880         </listitem>
881         <listitem>
882           <simpara>allow passing options to modules (-O param=value
883           ?)</simpara>
884         </listitem>
885         <listitem>
886           <simpara>separate styling from project classes</simpara>
887         </listitem>
888         <listitem>
889           <simpara>allow to define several views in a project-class,
890           several of which can be generated by default.</simpara>
891         </listitem>
892         <listitem>
893           <simpara>find out whether we can declare
894           protocols/pure-virtual-classes in some way, to cleanup the
895           class graph</simpara>
896         </listitem>
897         <listitem>
898           <simpara>generalize --prefix-strip
899           </simpara>
900         </listitem>
901         <listitem>
902           <simpara>give consistent access to all commonly-needed
903           features through command-line and class
904           customization</simpara>
905         </listitem>
906         <listitem>
907           <simpara>generalize the special_edge() mechanism (use a hash
908           of edge attributes ?)</simpara>
909         </listitem>
910         <listitem>
911           <simpara>Maybe allow to use as nodes other objects than
912           files (eg. URI objects ?), for ultimate
913           generalization.</simpara>
914         </listitem>
915       </itemizedlist>
916     </section>
918     <section>
919       <title>graph-includes tool</title>
921       <itemizedlist>
922         <listitem>
923           <simpara>allow to run from a build directory</simpara>
924         </listitem>
925         <listitem>
926           <simpara>--class does not allow to find the project file
927           (need to set PERL5LIB)</simpara>
928         </listitem>
929         <listitem>
930           <simpara>caller must prepend path to source tree to
931           --prefixstrip and all relative -I flags</simpara>
932         </listitem>
933         <listitem override="+">
934           <simpara>find the accessory classes as easily as possible
935           (like bugzilla ?)</simpara>
936         </listitem>
937         <listitem>
938           <simpara>better robustness to incorrect arguments
939           (eg. --consolidate 1:2)</simpara>
940         </listitem>
941         <listitem>
942           <simpara>automate --help production (see Pod::Usage
943           ?)</simpara>
944         </listitem>
945         <listitem override="+">
946           <simpara>multi-sheet paper support may be broken</simpara>
947         </listitem>
948         <listitem>
949           <simpara>use an existing source of paper formats (libpaper,
950           LC_PAPER, whatever)</simpara>
951         </listitem>
952         <listitem>
953           <simpara>maybe use graphviz' tred(1) to check our transitive
954           reductions.</simpara>
955         </listitem>
956         <listitem>
957           <simpara>some autodetection of the language to use based on
958           filenames ?</simpara>
959         </listitem>
960         <listitem>
961           <simpara>provide an initial list of system directories to
962           avoid repeating them (ask compiler)</simpara>
963         </listitem>
964       </itemizedlist>
965     </section>
967     <section>
968       <title>extractors</title>
969       <itemizedlist>
970         <listitem override="+">
971           <simpara>allow -I syntax for programs using eg. -I. from
972           source subdirectory</simpara>
973         </listitem>
974         <listitem>
975           <simpara>consider using Cwd::realpath or so, for correct
976           "../" handling</simpara>
977         </listitem>
978         <listitem>
979           <simpara>write other extractors (java, python,
980           &#8230;)</simpara>
981         </listitem>
982         <listitem>
983           <itemizedlist>
984             <title>C-like extractor</title>
985             <listitem>
986               <simpara>some support for CPP symbol conditionals
987               (mostly #ifdef), perhaps coupling this with
988               attributes</simpara>
989             </listitem>
990             <listitem>
991               <itemizedlist>
992                 <title>write an openc++-based dependency
993                 extractor</title>
994                 <listitem>
995                   <simpara>extract more fine-grained dependency
996                   (depending on a header does not necessarily imply
997                   depending on code)</simpara>
998                 </listitem>
999                 <listitem>
1000                   <simpara>handle (warn about) the case where the
1001                   declarations for a given implementation file are
1002                   scattered in more than one header</simpara>
1003                 </listitem>
1004               </itemizedlist>
1005             </listitem>
1006           </itemizedlist>
1007         </listitem>
1008         <listitem>
1009           <simpara>detect undeclared dependencies (eg. manually
1010           inserted prototypes)</simpara>
1011         </listitem>
1012         <listitem>
1013           <simpara>check necessity of declared includes</simpara>
1014         </listitem>
1015         <listitem>
1016           <itemizedlist>
1017             <title>perl extractor</title>
1018             <listitem>
1019               <simpara>remove arbitrary limitations</simpara>
1020             </listitem>
1021             <listitem>
1022               <simpara>report use/require lines we could not
1023               completely parse</simpara>
1024             </listitem>
1025             <listitem>
1026               <simpara>do some invariant analysis when importing a
1027               module using a variable name.  Investigate drawing 1->n
1028               links in this case.</simpara>
1029             </listitem>
1030           </itemizedlist>
1031         </listitem>
1032       </itemizedlist>
1033     </section>
1035     <section>
1036       <title>project classes</title>
1038       <itemizedlist>
1039         <listitem>
1040           <simpara>proper way to define include paths in project
1041           class</simpara>
1042         </listitem>
1043         <listitem>
1044           <simpara>make default project-class consider multiple levels
1045           of directories as group levels, but only if they
1046           (consistently ?) have multiple subgroups ?</simpara>
1047         </listitem>
1048         <listitem>
1049           <simpara>write a linux-kernel class and others as examples
1050           :)</simpara>
1051         </listitem>
1052         <listitem>
1053           <simpara>provide a simple hash-based filelabel
1054           implementation</simpara>
1055         </listitem>
1056       </itemizedlist>
1057     </section>
1059     <section>
1060       <title>grouping</title>
1062       <itemizedlist>
1063         <listitem>
1064           <simpara>Abstract the grouping process into GroupSet
1065           objects, computed independently from other
1066           processes, and customizable</simpara>
1067         </listitem>
1068         <listitem>
1069           <simpara>Provide a regexp-based grouper, useful from
1070           command-line, and as a base for current level-1 grouping,
1071           and possibly to automatic per-directory grouping</simpara>
1072         </listitem>
1073         <listitem>
1074           <simpara>provide tools for automatic grouping (eg. using
1075           cycles, or selected external deps, or from leaves)</simpara>
1076         </listitem>
1077         <listitem>
1078           <itemizedlist>
1079             <title>keep group members as close as possible</title>
1080             <listitem>
1081               <simpara>Give more weight to intra-group edges</simpara>
1082             </listitem>
1083             <listitem>
1084               <simpara>Improve transitive reductions implying multiple
1085               edges into a single cycle, to prefer an edge into the
1086               lowest-level common group</simpara>
1087             </listitem>
1088           </itemizedlist>
1089         </listitem>
1090       </itemizedlist>
1091     </section>
1093     <section>
1094       <title>styling</title>
1096       <itemizedlist>
1097         <listitem>
1098           <simpara>allow styling through font color, node shape
1099           (dot/tulip), number of peripheries (dot)</simpara>
1100         </listitem>
1101         <listitem>
1102           <simpara>allow to draw non-consecutive group
1103           levels (eg. --consolidate 1,3)</simpara>
1104         </listitem>
1105         <listitem>
1106           <simpara>allow different node shapes when mixing high-level
1107           nodes with lower-level ones through the default singleton
1108           groups (special_node mechanism similar to the special_edge
1109           one ?)</simpara>
1110         </listitem>
1111         <listitem override="+">
1112           <simpara>optionally show labels (using
1113           attributes ?) or count for files (subnodes) in a node and
1114           color arcs according to them</simpara>
1115         </listitem>
1116         <listitem>
1117           <simpara>optionally show external deps (deps on files not on
1118           command-line)</simpara>
1119         </listitem>
1120         <listitem>
1121           <simpara>limit graph to one or more given group(s) of files
1122           (specified by &lt;level&gt;:&lt;label&gt;)</simpara>
1123         </listitem>
1124         <listitem>
1125           <simpara>draw cycles in a given color</simpara>
1126         </listitem>
1127         <listitem>
1128           <simpara>draw a specific path</simpara>
1129         </listitem>
1130         <listitem>
1131           <simpara>provide automatic coloring schemes</simpara>
1132         </listitem>
1133         <listitem>
1134           <simpara>color intra-group edges with the same color as
1135           nodes (post-processing ?)</simpara>
1136         </listitem>
1137         <listitem>
1138           <simpara>allow to request drawing of who in a high-level
1139           node points to another node (ie. violates some
1140           constraint)</simpara>
1141         </listitem>
1142         <listitem>
1143           <simpara>propagate excuses in some way when they are dropped
1144           by the transitive reducer</simpara>
1145         </listitem>
1146         <listitem>
1147           <simpara>investigate candidate tools for hyperbolic layout
1148           ?</simpara>
1149         </listitem>
1150         <listitem>
1151           <simpara>allow to show the count of deps in a given edge
1152           using line width instead of labels</simpara>
1153         </listitem>
1154       </itemizedlist>
1155     </section>
1157     <section>
1158       <title>documentation</title>
1159       <itemizedlist>
1160         <listitem>
1161           <simpara>write more documentation</simpara>
1162         </listitem>
1163       </itemizedlist>
1164     </section>
1166     <section>
1167       <title>testsuite</title>
1169       <itemizedlist>
1170         <listitem>
1171           <simpara>write a testsuite.</simpara>
1172         </listitem>
1173         <listitem>
1174           <simpara>ensure that all provided non-abstract classes are
1175             self-contained</simpara>
1176         </listitem>
1177       </itemizedlist>
1178     </section>
1180     <section>
1181       <title>gui</title>
1183       <para>The standard GUI should be able to navigate the project
1184       definition, visualizing the hierarchy of groups, (un)folding
1185       groups and edges, displaying single culprits from a group, and
1186       anything you can think of.</para>
1188       <para>For an engine, maybe with graphviz' lefty, or write a
1189       specialized tulip gui ?  A self-customizable GUI like entity may
1190       be a good idea.  Since entity has support for OpenGL areas,
1191       maybe it can be made to embed tulip graphs.</para>
1193     </section>
1194   </section>
1196   <section id="bugs">
1197     <title>Known bugs</title>
1199     <itemizedlist>
1200       <listitem>
1201         <simpara>volume names in paths are not handled yet (eg. on
1202         windows)</simpara>
1203       </listitem>
1204       <listitem>
1205         <simpara>on windows, backslash path separator in -prefixstrip
1206         argument interferes with regexp ("Trailing \ in regex m/ ... at
1207         wesnoth.pm line 21")</simpara>
1208       </listitem>
1209       <listitem>
1210         <simpara>traversal counts on edges are unreasonably high on
1211         cycles (real graph traversal issue, but unlikely to get fixed
1212         before we get another visual way to spot cycles ;)</simpara>
1213       </listitem>
1214       <listitem>
1215         <simpara>the colored style of a node of level &lt; min is not
1216         shown when that node is displayed because it is not part of
1217         any node &gt; min and &lt; max.</simpara>
1218       </listitem>
1219       <listitem>
1220         <simpara>--showdropped mode draws too many edges as dropped
1221         (ie. does not consider marked edges as dropped when deciding
1222         whether to consider subsequent edges as dropped)</simpara>
1223       </listitem>
1224       <listitem>
1225         <simpara>transitive reduction may not be complete, some more
1226         edges could possibly be dropped - wesnoth tree at 2005-03-25
1227         exhibits the problem with the "display -&gt; builder -&gt;
1228         animated -&gt; image" path</simpara>
1229       </listitem>
1230     </itemizedlist>
1231   </section>
1233 </article>