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.
[Basics] - [Tags] - [Build System] - [Checking]
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."
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.
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:
void incSexyness(KInstance *instance);
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 KDENetwork {
/** Wrapper for a TCP/IP socket */
class Socket {
  public:
/** Constructor. Calls listen() on some random high port. */
Socket();
private:
int fd;
} ;
}
You can see here that each nesting level of
"things" is documented with
a comment -- the
namespace,
the
class
and the
method.
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
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:
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.
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.
./
./src/
./src/app/
./src/lib/
./plugins/
./plugins/foo/
./plugins/foo/lib
./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):
This is the situation in case
This is not the case for directories
This means that for cases
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.
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:
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.
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.
Do make sure the comment is just before
the namespace and doesn't get distanced from the namespace
it documents. The following is fine:
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).
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.
The same caveats apply as with namespace apidox:
make sure the class follows its apidox immediately.
Same caveats apply.
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:
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:
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.
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.
Documentation for a namespace.
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.
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.
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.
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.
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.
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.
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.
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:
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.
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:
These directories can be of two sorts: Cross-references may also contain slashes, for instance
kio/bookmarks to
cross reference to the bookmarks part of the kio library in kdelibs.
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.
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:
Due to implementation constraints, the value for the setting
must be on a single line in the Makefile.am. No backslash
continuations are allowed.
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 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.
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.
On my own system where I compile KDE 3.5,
I use the following settings:
[ Edit ]
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.
or
since they each contain subdirectories that generate
their own apidox.
and
,
only files from the respective directory are processed
(i.e. ./*
and ./plugins/foo/*).
Writing APIDOX in New Code
Fixing APIDOX in Old Code
Example APIDOX
Common Pitfalls
double distance(int x, int y, bool nonFree=false);
Supported Tags
Build System Tags
Code Examples in APIDOX
Checking APIDOX