This is a work-in-progress, describing how to add dox to your KDE code, what tags to use and how, and how to check that your dox are OK. It's not done yet.

KDE API Dox HOWTO

API (Application Programming Interface) documentation is documentation that applies to a program and its interfaces. It is documentation that explains to a developer who is going to work with the program, or a developer who is going to work on a program, how things work and what methods are there to call.

API documentation is sometimes called an API reference manual. It needn't just be a reference manual, though, there can be extensive additional material, like tutorials, histories, etc. In this page, we will refer to all the material that documents and explains the API of a piece of code as "apidox."

Good apidox take some effort to write -- but I would say less than good user documentation, since you as a developer are writing for another developer, and explaining how code works and what it is supposed to do. So your audience is clear to start with. The benefits of apidox come when someone else (or maybe even you, in six months time) needs to (re)use the code, or extend it. Good apidox means that someone new can show up, understand your code, and produce meaningful patches (that is, help) all the more quickly. Especially for libraries, good apidox make the library usable as a black box (and that's how they should be) because all the needed documentation is available in the apidox and not hidden in the (perhaps inaccessible) C code.

APIDOX are what make a program accessible to other contributors. They are not essential, mind you, but they certainly help a great deal for new people who show up and want to work on your code, or better yet, re-use it elsewhere with a minimum of modification.

Look at the Qt documentation to get a feeling of what good apidox are like. There is a consistency of style, a thoroughness which permeates all the documentation. It is possible to learn a lot about Qt just from reading the documentation. You do not necessarily need to run the tutorial programs or read the source code of the library to find out what a parameter flags does in some method of the library. It is all spelled out for you.

Writing apidox is a two-part process. One part is technical: you need to understand the code you are documenting -- or at least know what it is supposed to do and how it is meant to be used. The other part is plain discipline: apidox are most useful when they are exhaustive.

This document is going to try to prevent the apidox process from becoming exhausting, by giving straightforward tips about how to go about writing apidox. There are also the apidox policies, which are much much stricter, which provide measurable properties that apidox must adhere to. Glance at them now. When you come back, say "thank goodness it doesn't have to be like that."

Sometimes, there's interesting things to know about API reference manual generation that isn't really important for the whole story. That kind of information is in boxes like this one, with a little "information" graphic.
On the other hand, this is important: when reading this HOWTO, pay attention to the warnings because they will tell you about cases where it's easy to make mistakes, or which could cause unexpected problems.
Documentation examples look like this. Normally, they are formatted as you would expect code to be formatted, with comment signs and the whole thing, but this box doesn't have that since it's just an example of what examples can look like.
Comments relating to other files on your system (configuration, source, Makefiles, whatever) look like this.
Things to type into a shell prompt (a Bourne shell, so no csh) are written in this kind of boxes. Comments are indicated with a #, which commands you type are indicated with a $ (do not type the $).
Finally, some parts of this HOWTO may be broken, incomplete, or erroneous. These may be marked with comments that look like this to indicate that the document isn't finished yet.

APIDOX Basics

APIDOX are processed by the Doxygen documentation tool. This tool reads source code for your application (or library) and produces nicely formatted documentation from it. There is a good reference manual available -- but I hope to make it unnecessary to read, for basic use anyway.

You don't even need to have Doxygen installed to work on apidox for your application. Every few hours, the EnglishBreakfastNetwork compiles apidox for all of the KDE modules we know about. Logfiles are kept and you can see your apidox on the site, or read the error messages and fix those. .. it might not be the fastest way to write and fix apidox, but it gets the job done, and if you spend just an hour at the end of the day writing some apidox, it's sufficiently useful.

Basic apidox are fun and simple: you write comments in your code explaining what things are supposed to be for. These comments are nearly indistinguishable from stuff you would be writing in the headers of your code anyway, so that's not hard to do.

APIDOX are written in special comments. These comments start with /** (slash, star, star) -- that's what makes them special. The rest of the content of the comment is just plain text describing a part of your program. The plain text is interpreted by the Doxygen processor, so that you can write accurate descriptions of parameters, return types, and do some basic text markup. But documentation can be very straighforward: just write down what a method does, surrounded by /** and */, like this:

/** This method increases the sexyness of Kontact and should as such be called whenever possible (i.e. instead of having idle time, you might think of calling this method and helping Kontact gain even more popularity). You might even insert it into your own event loop to ensure it is called as often as possible. If these calls decrease the number of new features, it's still no problem to call it. */
void incSexyness(KInstance *instance);
-- Reinhold Kainhofer
 

For proper apidox, you need to document every "thing" in your program. "Things" here are directories, files, namespaces, classes, methods, enums, and member variables. You can actually leave out files and directories, and concentrate on the latter. Complete apidox looks something like this:

/** Namespace for KDE network-related classes */ Callout #1namespace KDENetwork {   /** Wrapper for a TCP/IP socket */   Callout #2class Socket {   public:     /** Constructor. Calls listen() on some random high port. */     Callout #3Socket();   private:     int fd;   } ; }

You can see here that each nesting level of "things" is documented with a comment -- the Callout #1namespace, the Callout #2class and the Callout #3method. Things that are private do not need apidox, but things that are protected do.

It is important to document each level of nesting, because if you leave one level out, Doxygen will ignore the documentation in inner nesting levels, and you will be left wondering where it has gone. For instance, if we leave out the class documentation, then the method documentation for Socket() will vanish as well. This is one of the common pitfalls to writing apidox.

If you just do this -- write an explanation for every part of your program -- then you're already a long way on the road to having complete apidox. Writing all those explanations makes your program more accessible to other developers -- and often shows you where the design or choice of names is sub-optimal. So it's a win for you both ways.

You can consult the list of supported tags for examples of more fancy apidox -- explaining parameters, for instance, and annotating the apidox with credits and examples. It's also worthwhile to take a look at the section on enabling apidox, but it's also fine to divide the work: you write the apidox themselves, and just shout out:

yo [ade], I have apidox in KDE SVN in module your-module-here, please enable them.

And I will.

Enabling APIDOX in the Build System

This section applies even though we no longer use Makefile.am for the actual build system. So you must leave Makefile.am in the source tree, even if it is just empty except for apidox settings. This will eventually be removed, but not right now.
-- [ade] 2006/04/01

It's no good having wonderful apidox in your code if no one can see it. In order to see the apidox, they must be generated, and for that to happen, you have to tell the build system that there are apidox to build (and probably tell [ade] as well, so that they are automatically generated on the English Breakfast Network and on ktown).

To tell the build system that there are apidox to build, add the following line near the bottom of your Makefile.am:

include $(top_srcdir)/admin/Doxyfile.am

That's all! having done that, you will have to re-generate the Makefile (make will probably do that for you) and you can then run make apidox to generate the apidox. You might have to add the same line to the top-level Makefile.am, and run make apidox from there instead of your subdirectory -- experiment a little.

You may need to enable apidox in parent directories as well. This is a limitation of the apidox generation process. For instance, if you have apidox only in foo/bar/ and enable apidox in that directory only, your apidox may not be (re)generated when needed. You will notice this on the English Breakfast Network.

In order to enable apidox on directories that don't really have apidox but are needed anyway -- directory foo/ in this example -- enable apidox as usual by adding the include line, but also add a line like this:

DOXYGEN_EMPTY = YES

This makes the directory foo/ a placeholder with no apidox, and ensures that the apidox in foo/bar/ will be re-built as needed.

The one (or two) lines changed in the Makefile.am above are all that is needed to enable apidox in straightforward situations where you have a single subdirectory containing things that are documented and you want all of the contents of that subdirectory to be processed by documentation. Complications only set in if your subdirectory is hidden away in the depths of a source tree -- then you need to enable and set as empty the apidox on intermediate directories.

Real complications set in if you have apidox scattered about, or want to ignore some parts of the source tree, or have weirdly nested directories containing apidox. We will go into this below.

The following example is complicated and contrived. Most of the time it's more than enough to just add the include line in the top-level source directories of your project. Read on if you are missing apidox or have apidox that shows up multiple times.
Callout #1./
Callout #0./src/
Callout #0./src/app/
Callout #0./src/lib/
Callout #2./plugins/
Callout #3./plugins/foo/
Callout #0./plugins/foo/lib
Callout #0./plugins/fu/

If you have a library or program with multiple directories or some deeper nesting structure, you can control which subdirectories generate apidox. Consider the example directory layout to the right.

In this setup, there are three directories with apidox. Each of the directories' Makefile.am should contain the include line shown above. However, the rules for apidox generation are as follows (for any given directory):

  1. If no subdirectory of the directory for which apidox are being generated generates its own dox, then (and only then) does the apidox comprise all the sources in the directory and recursively its subdirectories.

    This is the situation in case Callout #3 in this sample directory tree: ./plugins/foo will generate apidox and contains no subdirectories that generate their own apidox, so the apidox for ./plugins/foo will also contain all the apidox written in ./plugins/foo/lib.

    This is not the case for directories Callout #1 or Callout #2  since they each contain subdirectories that generate their own apidox.

  2. If the directory does contain subdirectories that generate their own apidox, then only files in the directory itself will be processed.

    This means that for cases Callout #1 and Callout #2, only files from the respective directory are processed (i.e. ./* and ./plugins/foo/*).

With this particular setup, a lot of potential apidox are skipped: the whole ./src/ tree is skipped because of rule 2, and neither is ./plugins/fu processed. There are two KDE apidox settings that can be used to influence rules 1 and 2.

  1. Forcing recursive apidox processing: In order to force the apidox generation process to read all subdirectories -- thus defeating rule 1 -- you need to include the following line in the Makefile.am:
    DOXYGEN_SET_RECURSIVE = YES
  2. Preventing recursive apidox processing: You can prevent all recursive processing in a directory by changing "YES" to "NO" in the line above, or you can selectively exclude subdirectories from processing -- defeating rule 2's default behavior of recursively processing everything. Selective exclusion requires adding a line like the following to your Makefile.am:
    DOXYGEN_EXCLUDE = directory1 directory2 ...
    The list of directories should be relative to the directory whose apidox generation you are modifying (that is, write fu in the Makefile.am for ./plugins).

These two techniques need to be combined to deal with complex apidox situations like the one in this example. The Makefile.am for subdirectory ./plugins/ should look like this:

# Read all subdirectories DOXYGEN_SET_RECURSIVE = YES # Except foo, since it has its own apidox DOXYGEN_EXCLUDE = foo include $(top_srcdir)/admin/Doxyfile.am
 

Writing APIDOX in New Code

If you are writing new code and want to write apidox, use KDevelop. Really. Properly configured, it can automatically set up all the skeletons for apidox that you need, and what you do is write the descriptions. No messing with apidox commands.

If you're not in that fortunate position, the following little checklist should get you through the worst of writing apidox.

  1. Write apidox as you code. The discipline it takes to write down the apidox for function foo() now as you are thinking of foo() and what it needs to do more than compensates the effort later where you have to remember what foo() was supposed to do, anyway.

    This isn't to say you have to do it this way, but it is convenient. The apidox also document design decisions. They also document what you want a particular piece of code to do, regardless of what it actually does. That makes it possible to independently check that the code does what it's supposed to: because it's written down.

  2. Document your headers completely. The headers are what's most visible to users (in this context, users are developers who are re-using) of your code, and they should be complete. Document each structural bit of the headers as you go along. This means:
    • Every file should have a file-level comment. This is suggested in the KDE guidelines anyway -- near the top of your file, write down what the file is for, vaguely what it defines. Wrap this up in a /** @file */ comment and you are set.
    • Every namespace should have a comment. A given namespace only needs a comment once in your source tree (or within one bunch of files that generate apidox together), but it can't hurt to repeat the description on each occasion -- just make it brief. These comments are just plain apidox comments wrapped up in /** */ ; there are no special markups needed like the @file for file comments.

      Do make sure the comment is just before the namespace and doesn't get distanced from the namespace it documents. The following is fine:

      /** The Ungulate namespace collects classes and methods pertaining to hooved animals. */ namespace Ungulate {

      In the next example, someone has snuck in some extra stuff between the apidox comment and the namespace it is documenting. This may cause Doxygen errors (so then it is easy to spot) or it may cause the namespace documentation to attach to something wildly different (and then it's hard to spot).

      /** The Ungulate namespace collects classes and methods pertaining to hooved animals. */ class Mammal; namespace Ungulate {

      There is not much you can do about this except to be watching when you insert code -- don't separate apidox from the thing they are documenting.

    • Every class should have a comment. Classes are the important building blocks of your application or library, so this is one place where writing lots helps. Write down why the class exists. Write down what it is supposed to do. Give an example of how to use it. Explain how not to use it, or what prerequisites it has (for instance, lots of classes need a KInstance object, but don't document that explicitly).

      The same caveats apply as with namespace apidox: make sure the class follows its apidox immediately.

    • Every method should have a comment explaining what it does and what the parameters are for. Method parameters should be documented using @param. Don't rely on the name of the method or the parameters to be fully self-documenting. Besides, writing these things down properly will trigger Doxygen errors if you change them in an incompatible way later -- and that is going to save you lots of time in finding source and binary incompatibilities and explaining to users why their code suddenly doesn't do what they expect (assuming it compiles at all). So good method apidox is an additional insurance against making bad changes.

      Same caveats apply.

    • Every enumeration type should have a comment explaining what the enumeration is for, even if it's just /** Various constants */.
    • Every enumeration value should have a comment too, to explain what it represents. Don't rely on the name of the enumeration value being sufficiently expressive.

      For the purposes of readability, I suggest that you document enumeration values after the value, as opposed to the documentation format for namespaces, classes and methods where you write the documentation in front of the thing you are documenting. The format of the documentation is slightly different. Instead of writing /** Documentation */ in front, you write /**< Documentation afterards */ instead, where the < denotes that the documentation applies to the thing just past.

      It looks like this:

      enum State {   none /**< No bracket seen */,   bracket /**< Found a ( for grouping */,   squote /**< Found a single quote */,   dquote /**< Found double quotes */ } ;
  3. Watch this space! Watch the English Breakfast Network for the results of your apidox work. Check the log files for errors -- Doxygen can complain quite loudly.
  4. Write a main page for your application. This is usually done in a separate file Mainpage.dox in the top-level of a library or application. The file's content is just a single apidox comment that starts with /** @mainpage title ; the rest of the file is just a long comment about what the library or application is for.

Fixing APIDOX in Old Code

Writing apidox in old code is a lot like writing the same apidox in new code, except that there is more cruft in the way. The number 1 tip to follow is: watch the logs on English Breakfast Network. Those will show you what errors there are in the apidox. However, Doxygen can't catch everything that is wrong with the documentation on its own, so you will have to do some reading yourself. The other tips for new apidox apply equally here: you want to document everything, in a consistent style. If methods show up on the generated apidox pages with no documentation, you know that you have more apidox to write. (Doxygen may provide an error message, but doesn't do that everywhere in the current setup because there would just be too many.)

In old apidox, you are more likely to suffer from the following symptoms:

  • Missing parameter documentation (because parameters were renamed, or added, or removed, or something).
  • Missing method documentation.
  • Missing class documentation.
  • Documentation that has wandered off on its own and is attached to the wrong thing now.

The first of these can be fixed by correcting the parameter documentation. See the examples section. The next two -- missing documentation that you can see is there in the source files but that does not show up in the generated HTML pages, is usually a matter of missing documentation on surrounding blocks. See the common pitfalls section, and make sure that the surrounding classes, namespaces and files all have documentation.

The last problem can best be fixed by moving the offending documentation back to where it belongs (really, it's not the documentation that is at fault, it's whatever has squeezed in -- the home-breaker -- between the documentation and the thing it was originally attached to). You could use some Doxygen special tags to avoid moving stuff around like that, but it does not help the understandability of the source much.

Example APIDOX

So what does documentation look like in the headers? How do you write a method documenation that describes the parameters as well? This section contains boilerplate for most common situations. The boilerplate makes use of my own favorite comment style, but this is no requirement: Doxygen will ignore whitespace and asterisks at the beginning of a line, so you can make the documentation ASCII-pretty.

Documentation for a file. The newline after @file is significant! The text after @author is listed in a special Authors section of the apidox; you can list multiple authors.

/** @file * This file is part of AnApplication and defines * classes Ungulate and Moose. * * @author Mostly by me */

Documentation for a namespace.

/** * This namespace collects functions related to * counting and enumeration of mammals and their limbs.
*/

Documentation for a class. Some Doxygen special commands are used here to provide additional information. @author (as with files) identifies authors of the code; these are collected in a special Authors section of the apidox. You can list more than one author. The @since tag tells users since when the class has existed. It is usual to put a KDE release number here.

/** * This class represents a Moose in the woodland * simulator. A single Moose object can be created, * but it is more useful to instantiate Moose::Factory * by calling Moose::factory(), and then calling spawn() * for each new Moose, since that maintains the ecological * balance far better. * * @author Adriaan de Groot <degroot@kde.org> * @since 3.5 */

Method documentation. We can use @author and @since just like we do for classes. In addition, there are the parameters of the method that can be described. @p is used to refer to them in running text, and @param is used to construct a list of parameter descriptions that is specially formatted. Finally, @return entries describe the values that may be returned by the method.

/** * This method names a particular Moose and * as a side effect sets whether or not * the Moose is treated as a Reindeer. * When @p santa is @c true, the name of * the moose is set to the next of the available * Reindeer (if possible). * * @param name name to assign to the Moose, * which is only relevant if the moose * is not a Reindeer. * @param santa is this Moose assigned to Santa? * if so, the name is irrelevant. * * @return @c true if naming the Moose succeeded * @return @c false if naming the Moose failed. This * only happens if the Moose is assigned * to Santa duty but there are already * eight named Reindeer. */ bool name(const QString &name, bool santa = false);

Enum documentation is described in the section on writing new apidox. The same kind of documentation as for classes applies, with the addition of the documentation for each enumerated value which belongs inline.

Common Pitfalls

This section lists common pitfalls in writing apidox. Typically, they are easily overlooked mistakes that produce weird error messages, but I will also include some stylistic pitfalls that should be avoided.

  • Missing APIDOX: You know you wrote dox for class Moose, but after generation they are not visible. You know that the file-scope function int foo() is documented, but it's not there either! What is going on?

    The most common pitfall, the one that leads to "missing" apidox, is forgetting to document surrounding structure. The "structure" in the source comes from files, namespaces, classes and methods. In order to document a class you must document the namespace it is in (if there is one) and the file that it is in. In order to document a method, you must document the class it is in (and thus the namespace and file). So the easiest rule of thumb is to document everything.

    This hard-and-fast rule is not quite accurate: classes do not need the file to be documented, so you can leave out the /** @file */ comment for source files containing only classes (and namespaces). Note that classes in a namespace require the namespace to be documented, but classes in the :: namespace don't need extra documentation. I'm not sure about anonymous namespaces.

    For file-scoped functions -- that is, functions that are defined in a file, not in a namespace and not in a class, you must document the file they are in. This applies mostly to files which collect a bunch of non-method utility functions.

  • Broken parameter documentation: Documenting parameters to methods can be done two ways: you can document none of them, or you can document all of them for a given method. There is no middle ground (that doesn't generate gobs of errors that you should fix).

    If you document all of your parameters (which is a good thing to do, and generates things in a nicely formatted fashion), then your method apidox consists first of a general description of the method and then a bunch of @param tags which describe each individual parameter. The @param tag is followed by the name of the parameter -- watch out for spelling and case-sensitivity! -- and then the description. The description can span multiple lines.

    /** Calculate the root-mean-square distance from the * origin to the given integral coordinate. * * @param y y-coordinate, which is on an axis *    perpendicular to the x-axis, yet still in the *    same plane. * @param x x-coordinate */

    When you document all the parameters like this, Doxygen will complain if you misspell parameter names, or forget some, or mention parameters that are not there. This will force you to update the documentation if you change the method signature. And that's a good thing.

    Additional pitfalls I've seen here are putting the type of the parameter in the list, like @param int x, which makes "int" the name of the parameter. Another pitfall is that @param should come after the general description. Once the @param list starts, nothing can stop it except for other list-style Doxygen tags like @since, @author or @return. So write @param after the story and before, say, @return.

    If you document none of the parameters, you do not use the @param tag at all. You can talk about your parameters by writing @p before the name of a parameter (or anything else, really, but it only makes sense in front of a name of a parameter). Like this:

    /** Calculate the root-mean-square distance from the origin to the given integral coordinate which is given as a pair @p x , @p y. If @p nonFree is true, use ESR instead of RMS in the computation. */
    double distance(int x, int y, bool nonFree=false);
  • Misuse of tags in running text: This boils down to the warning above about where to put @param: not every Doxygen tag can go anywhere. Some start lists or basically end the general description part of a description, so you need to avoid using them in running text.
  • Chosing between Doxygen errors and compiler warnings: If you are going to document your parameters, you need to name them. If you are defining a stub method, this can lead to compiler warnings.
  • Accidental tags: It can be easy to accidentally use Doxygen tags in running text -- email addresses, backslash escapes, those are the easy ones. Watch the Doxygen logs and escape that at sign with a backslash when needed (i.e. write \@ to get an at sign). It's probably a good idea to avoid the backslash style of apidox entirely; at the same time, if you happen to write \moose, Doxygen will complain that that is an invalid tag.
  • Accidental HTML: If you use < and > in your apidox, these may confuse Doxygen -- especially if you write things like <service> which look like HTML tags. This is a common way of writing some kind of element that may be replaced in a method call or string or something, so it crops up all the time. You know, you write some thing like this:
    /** This method connects to a database. The * connection string is composed of a username, * password, host and database name as follows: * <username>:<password>@<host>//<database> * * @return true if the connection succeeded. */
    This bit of dox is terribly broken, because the whole sample connection string will be interpreted as (bad) HTML and ignored. There are two solutions:
    1. Write \< instead of just < to escape the < and make Doxygen output it normally. Doxygen is smart enough to turn this into &lt; in HTML output. This has only a minimal impact on readability of the dox in the header files themselves.
    2. Use the HTML formatting that Doxygen makes available, and write <i>foo</i> instead of <foo>. This produces nicer output with italics instead of plain text, so it is easier to spot what is the replaceable part of the text. The downside is that it has a larger visible impact on the apidox in the headers.
  • Superfluous @ref: It can be tempting -- certainly if you've written dox for other projects -- to use #method or @ref method to force a reference to another method somewhere. Relax, it's not needed and usually causes Doxygen warnings to boot. Just name the method normally, make apidox and watch the references appear naturally.

Supported Tags

Build System Tags

  • DOXYGEN_EXCLUDE

    This variable lists files and directories, both relative to the current directory, that should not be processed by Doxygen. This can be used to exclude the test/ directory, or a private and undocumented subdirectory from inclusion.

  • DOXYGEN_REFERENCES

    One nice feature of Doxygen is that it can create extensive cross-referencing in the apidox; so that you can follow an inheritance chain up from, say, KMail through kdeui to Qt; or that parameters of types defined in other KDE SVN modules are automatically linked to their description in those other modules. You have to tell Doxygen where to look, though.

    Doxygen automatically does cross-referencing within one directory (or within and below a directory, depending on the RECURSIVE settings). So when you refer to a class defined in another source file in the same directory, cross-referencing is automatic (and free).

    Cross-referencing across SVN modules or across directories requires you telling Doxygen what to cross-reference with. Set the variable DOXYGEN_REFERENCES to a space-separated list of directories to cross-reference, something like this:

    DOXYGEN_REFERENCES = kdecore kdeui \   libkdepim

    These directories can be of two sorts:

    • Relative to the top-level directory of the SVN module you are working in, i.e. the local module. Supposing the example above to be part of KDE PIM, then the directory libkdepim is a local cross-reference, because libkdepim is a directory within the KDE PIM module that has apidox.
    • Relative to the top-level directory of some other SVN module. These can be tricky, because you can really only depend on the kdelibs apidox being available for cross referencing. In this case, kdeui and kdecore are references to directories relative to the top of the kdelibs SVN module.

    Cross-references may also contain slashes, for instance kio/bookmarks to cross reference to the bookmarks part of the kio library in kdelibs.

  • DOXYGEN_SET_PROJECT_NAME

    By default, the pages generated by Doxygen for a particular subdirectory are named after that subdirectory. The subdirectory kdecore/ gets webpages titled "kdecore". You can change this by setting a different project name. This can be convenient if there are too many lib/ subdirectories inside one module, all causing confusion. By using DOXYGEN_SET_PROJECT_NAME you can give them more descriptive names.

  • DOXYGEN_SET_*

    If the list above of settings is not enough, then you can set any Doxygen setting with DOXYGEN_SET_*. Replace * by the Doxygen setting you want to change (PROJECT_NAME, or HAVE_DOT, or SHORT_NAMES, or ...) and this setting will override whatever the default or otherwise determined setting is. For example:

    DOXYGEN_SET_HAVE_DOT = YES DOXYGEN_SET_INPUT_PATTERN = *.c, *.D, *.eff

    Due to implementation constraints, the value for the setting must be on a single line in the Makefile.am. No backslash continuations are allowed.

    This is only sporadically useful. Some directories are so special (or contain examples in weird locations) that they need to have the Doxygen settings overriden. In general it's better not to mess with this.

Code Examples in APIDOX

It can be useful to put example code in the APIDOX for a class. Very useful, in fact, for the reader who is wondering how exactly to use the class in a straightforward way. Most classes in kdelibs/kdecore/ have example code.

One way to write example code is to use @code and @endcode around blocks of example code in the Doxygen comments themselves, like this:

/** * This class represents a Moose. * The correct way of generating Meese is to use the factory: * * @code * Moose::Factory outlet = Moose::factory(); * Moose *m = outlet.spawn(); * @endcode */

This is how most of the examples in kdelibs are done, actually. It works reasonably well, you can pare the example down to something really minimal and leave out all the boilerplate.

An important drawback of this approach to writing example code is that the code is never checked to see if it actually works. The code is also so terse, usually, that it's hard to expand into a complete example that actually compiles and runs.

To solve this problem, you can write real code that actually compiles (as part of the test suite for the code that you have anyway) and that illustrates exactly how to use the class under consideration in an actual program. Better yet, you do not need to include all the code in the APIDOX, just the interesting bits. The way to do this is to put the code in a file in the tests/ subdirectory of your code. Then use Doxygen's @include tag to include the code from that file into the API documentation.

Do not use @example! It does something totally different from what you might expect (it doesn't insert example code, for one thing).

Checking APIDOX

The APIDOX for KDE 3.5 (current release) and KDE trunk/ (development version) are re-built every 12 hours on the English Breakfast Network, an otherwise unaffiliated server. Log files are produced where you can check if your APIDOX are syntactically correct and document everything that is needed. In addition, you can see the output of your new APIDOX in the generated HTML output. The official KDE APIDOX updates once a week.

You may also want to build APIDOX yourself, so you do not have to go through the commit-wait-check cycle but can immediately see the results of your APIDOX corrections. To do so you will need to build APIDOX by hand. This requires at least Doxygen 1.4 (1.4.6, the lastest version as of this writing, is recommended). Some features of the APIDOX may only be available if you have additional tools installed, like graphviz.

  1. You must have either kdelibs installed -- for the version of KDE you are writing APIDOX for -- or a SVN checkout of kdelibs. You will need files from one or the other source. If you have KDE installed, you need files from share/doc/HTML/en/common/ within the installation path of KDE. If you have an SVN checkout, you need doc/common/ inside the kdelibs checkout. Set the shell variable DOXDATA appropriately:
    # For installed KDE $ DOXDATA=/path/to/kde/share/doc/HTML/en/common/ # For SVN checkout $ DOXDATA=/path/to/checkout/kdelibs/doc/common/
  2. You need an appropriate Qt Doxygen tag file. You can get a Qt 3.5 tag file from the EBN; this is somewhat usable for KDE trunk/ as well, but not ideal. You may also generate a Qt tag file yourself if you have the Qt headers installed. Change directory to the include directory of Qt and run doxytag as follows:
    $ cd /path/to/qt/include $ doxytag -t /tmp/qt.tag
    Put the qt.tag file somewhere you can find it, and set the shell variable QTDOCTAG appropriately:
    $ QTDOCTAG=/path/to/qt.tag
  3. Next, you need to ensure that references to Qt classes go to the right place. You can point them to the external documentation on Trolltech's website, or to your locally installed Qt documentation (assuming you have any). Do that by setting the QTDOCPATH variable:
    # For reference to the Qt 3.3 documentation on the web $ QTDOCPATH=http://doc.trolltech.com/3.3/ # For reference to the Qt 4.1 documentation on the web $ QTDOCPATH=http://doc.trolltech.com/4.1/ # For reference to locally installed documentation $ QTDOCPATH=/path/to/doc/qt/html
  4. Finally, you need to know where your source checkout lives for which you want to generate APIDOX. This should be a checkout of an entire SVN module. It should contain an admin/ directory at the top. Set the path to the source directory in the shell:
    $ SRC=/path/to/module/checkout/
  5. Now that you have collected all the information, all that remains is to build the APIDOX by running the doxygen.sh script. Export the variables you have set, and call the script to build the APIDOX in the current directory (independently of the source directory).
    $ export QTDOCPATH QTDOCTAG DOXDATA $ $SRC/admin/doxygen.sh $SRC

On my own system where I compile KDE 3.5, I use the following settings:

$ QTDOCTAG=/tmp/qt.tag $ QTDOCPATH=http://doc.trolltech.com/3.3/ $ DOXDATADIR=/usr/local/kde-3.5/share/doc/HTML/en/common/ $ SRC=/mnt/src/kde-3.5/kdebase $ export QTDOCPATH QTDOCTAG DOXDATADIR $ sh $SRC/admin/doxygen.sh $SRC

[ Edit ]