This is my personal Doxygen cheatsheet: Its initial (and primary) purpose is to be a compact help on this topic for myself.
It’s not meant as a general introduction or comprehensive reference for this tool, but it is meant to be a small knowledge base or collection of basics & “gotchas”, often-used commands, snippets, tips, and instructions on how to do certain tasks.
First steps
-
Download and install Doxygen.
-
Create a configuration file:
doxygen -g [<ConfigFilename>]
The filename is optional; if omitted, the default name Doxyfile will be used.
The configuration file can be customized, see below. -
Generate the documentation:
doxygen [<ConfigFilename>]
The filename is optional; if omitted, the default name Doxyfile will be used.
Assumes that the source code has been prepared, see below.
Configuration
I use a customized input file (Doxyfile.in), that file relies on a CMake build process to replace some variables/placeholders (which is automatically done in my standard setup).
Build quiet/silent
If you don’t want all the “noise” on the command line output:
QUIET = YES
Input
Doxygen needs to know, which files and directories it should investigate:
INPUT = <repo>/ReadMe.md <repo>/src/ ...
RECURSIVE = YES
GENERATE_TREEVIEW = YES
- One can specify particular files or whole directories (path items must be seperated by spaces).
- Enable recursion, so that all files beneath e.g. the CMAKE_SOURCE_DIR should be checked.
- A treeview might also be helpful, if more files are added.
Related:
The
EXCLUDEtag can be used to specify files and/or directories that should be excluded from the INPUT source files.
Or better:
If the value of the
INPUTtag contains directories, you can use theEXCLUDE_PATTERNStag to specify one or more wildcard patterns to exclude certain files from those directories.
Documenting the Source Code
First off, I actually use this mainly as a broad guideline/orientation on how to write and structure comments in the source code itself, for myself; the fact that Doxygen can “additionally” generate nice looking documentation in multiple other output formats is currently just a nice bonus 😄
By the way: My comment style has been heavily inspired by Powershell’s comment-based help over the last couple of years. It doesn’t fit C++ or Doxygen 100%, but it’s a good orientation mark for me.
Tip: Since Doxygen 1.8.0 Markdown can be used as a plain text formatting syntax in the source code comments as well as in custom pages (see below); its by default enabled in the Doxyfile.
Tip: Use \n to force a new line in the generated HTML output.
Special comment block (before)
A special comment block marks the comment therein for Doxygen.
There are multiple ways to denote blocks and commands; I prefer the “Qt style”, using the exclamation mark (!) and at sign (@):
/*!
Text for doxygen...
*/
//!
//! At least two lines are required for this version to work!
//!
Important: If you have very simple source code file (where Doxygen can’t detect things automatically),
there needs to be at least one special comment block (see below) with a @file command in it.
Otherwise, Doxygen won’t pick up this file at all and global stuff in it (like functions, variables, etc.) won’t show up in the generated pages!
/*!
@file
@authors Name 1, Name 2
@copyright © 2025 Name (address@example.net)
@license SPDX-License-Identifier: ...-... (see LICENSE.txt).
*/
Within a special comment block, a Doxygen section is marked (tagged) with either @sectionname or \sectionname commands
(I prefer the @ symbol).
A few things also work automatically, without these tags (e.g. a brief line or details), if the configuration fits; see the Doxygen docu for more – but I usually prefer to make it distinctively clear (with a command/tag), what the section/paragraph is about.
Normally a section is valid until a blank line or the start of another section is encountered;
but there are also exceptions to the first rule (blank line); the @details section for example can consist
of multiple paragraphs (that are separated by a blank line, see below).
Same-line comments (after members)
Same-line Doxygen comments (also known as “documentation after members”)
can also be used.
As usual, multiple ways/styles are possible; applying the Qt-Style (!<) is just one way.
int a; //!< This comment is for this line item.
int b; /*!< Another documentation after a member. */
These “same-line” blocks can only be used to document members and parameters; they cannot be used to document files, classes, unions, structs, groups, namespaces, macros or enums!
Commands
The essentials
This is a small excerpt that includes a lot of the standard keywords and structure that I would use to comment a function (template), for example:
/*!
@brief (or @short)
A short abstract/summary (one line) of the content/functionality of this item (file, function or class, etc.)
@details
A more extensive description.
Can consist of multiple paragraphs.
@authors Names of the authors (on a single line!)
@author Name 1 (Multiple entries will be combined
@author Name 2 as separate lines under one heading)
@param P Describes the parameter named "P".
@tparam T Describes a template parameter named "T".
@param [in] PI
Describes an input parameter with the name "PI".
@param [out] PO
Describes an output parameter with the name "PO".
@param[in,out] PIO
Describes an input/output parameter with the name "PIO".
A note on lengthy parameter description:
Tested and failed; found https://developer.lsst.io/cpp/api-docs.html#cpp-doxygen-parameters>:
> Doxygen will not properly parse parameter descriptions that have multiple paragraphs.
> If your function's input requires a lengthy explanation, put the explanation in the Notes
> and refer to it from the parameter descriptions.
@return (or @returns or @result)
The description of what will be returned (by a function)/what will be the result (of a function).
@retval <return value>
The description of the returned value.
@throws (or @throw or @exception) <exception-object>
A text that desecribes the thrown exception more...
*/
Other, often used commands and tags
Special parapgraphs
| Command | Description |
|---|---|
@attention |
manual |
@warning |
manual |
@bug |
manual |
@fixme |
A custom alias in my Doxyfile |
@deprecated |
manual |
@important |
manual |
@note |
manual |
@remark |
manual |
@todo |
manual |
Authorship, dates, versions
| Command | Description |
|---|---|
@version |
|
@date |
|
@copyright |
|
@license |
Custom aliases in my Doxyfile, based on this GitHub Gist |
- Examples for the license command/alias:
/*! @license Licensed under the Xyz License (see LICENSE.txt). @license{The Xyz License} Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. @licenseblock Licensed under the Xyz License. ... block with multiple paragraphs... @endlicenseblock @licenseblock{The Xyz License} Permission is hereby granted, free of charge, to any person obtaining a copy ... block with multiple paragraphs... @endlicenseblock */
Other
| Command | Description |
|---|---|
@test |
Text describing a test case. |
@see |
A “see also” note; cross-references to classes, functions, methods, variables, files or URL… |
More:
| Command | Description |
|---|---|
@struct |
to document a structure. |
@union |
to document an union. |
@enum |
to document an enumeration type. |
@fn |
to document a function. |
@var |
to document a variable or typedef or enum value. |
@def |
to document a pre-processor definition. |
@typedef |
to document a type definition. |
@file |
to document a file. |
@namespace |
to document a namespace (e.g. @namespace NiftyOddity::Toolkit::CLI::Utilities) |
- Note on
@namespace: - Doxygen 1.9.3 makes a difference between C++17 nested namespaces “with spaces/without spaces”
and build two different hierarchies (with the same display name) – weird stuff:
/*! @namespace NiftyOddity::Toolkit::CastConvert ... @namespace NiftyOddity :: Toolkit :: CastConvert ... */ namespace NiftyOddity::Toolkit::CastConvert { /*...*/ } namespace NiftyOddity :: Toolkit :: CastConvert { /*...*/ }
Common features of all the above:
- The text of the paragraph has no special internal structure.
- All visual enhancement commands may be used inside the paragraph.
- Multiple adjacent commands (of the same kind) will be joined into a single paragraph.
- The command/section ends when a blank line or some other sectioning command is encountered.
Mark a (small) code snippet:
/*!
@code
// Some short code excerpt:
int a = func(3,0,5);
@endcode
*/
For internal use only
/*!
@internal
Some internal comment that should not appear in the generated (public) documentation
... unless INTERNAL_DOCS is set to YES in the Doxyfile! (The default is NO)
@endinternal
*/
Including an example
/*!
@example <filename>
*/
But this works a bit different then what I first assumed:
- This indicates that a comment block contains documentation for a source code example from
<filename> - The contents of this file (as a whole!) will be included in the documentation (after the text in this block)!
- The filename will be searched according to the value of EXAMPLE_PATH in the Doxyfile.
Lists
Tip: Better not use asterisks (*) for lists, they may get removed (see the entry in the manual)
/*!
Unordered & nested:
- item 1
- item 1.a
- item 2
Ordered (& multiline):
1. item 1\n
Continued...
2. item 2
Checklist:
- [ ] Unchecked
- [x] Checked
*/
Tables
Tables can be included in either in HTML format (verbose/distracting) or in the simpler Markdown syntax:
/*!
Column 1 Header | Column 2 Header
---------------- | -------------
Cell Content | Cell Content
Cell Content | Cell Content
*/
Don’t repeat yourself, use @copy*
@copydoc <WHAT_TO_COPY>@copybrief <WHAT_TO_COPY>@copydetails <WHAT_TO_COPY>
If in doubt that Doxygen will use the correct item, be specific:
Full namespace, no return value, no parameters, parantheses without space!
Example: @copydoc NamespaceOrClass1::NamespaceOrClass2::function_name()
- Example
- If in the Doxyfile, two input directories have been set up, then Doxygen knows where to look stuff up:
- C:\devel\git\TheNiftyOddityToolkit\
- C:\devel\git\TheNiftyOddityToolkit\src\
@copybrief KeyboardLED.h --> A file with that name only exists once (for Doxygen). @copybrief KeyboardLED/KeyboardLED.h --> Specifycing a (relative/partial) path also works. | +--> Means file C:\devel\git\TheNiftyOddityToolkit\src\KeyboardLED\KeyboardLED.h
Pages
Additional Documentation (that is not directly related to one specific class, file or member) can also be included as custom pages.
Supported file extensions for these are .dox, .txt or .md.
Weirdly though, Doxygen will treat *.dox or *.txt files as C/C++ source code, but *.md files as Markdown.
By default Doxygen won’t know about these files; use INPUT (see above) to point it.
If you specify the src directory there and enable recursion, then other *.md files in its subdirectories
(e.g. a directory-specific ReadMe.me) will also be picked up by Doxygen (but the name in the filelist/filetree will not be
like the Markdown heading!).
Main page (index page)
This command in a special comment block marks it as custom content for the main/index page:
/*!
@mainpage The Title
...
*/
But instead of this, I usually specify in my Doxyfile the repository’s top-level ReadMe markdown file
as its main page (note that *_REPO_ROOT_DIR is a custom variable in my CMakeLists.txt):
USE_MDFILE_AS_MAINPAGE = ${${CMAKE_PROJECT_NAME}_REPO_ROOT_DIR}/ReadMe.md
Custom Pages
- The command
@pagecan be used in the source code to define custom pages (incl. sections, sub[-sub-]sections and a TOC). - Pages can also be grouped by subpaging (
@subpage). - The command
@refcan be used to links to named symbols, files, sections/subsections, pages or anchors.
/*!
@page page1 A documentation page
Leading text.
@tableofcontents
@section sec An example section
This page contains the subsections @ref subsection1 and @ref subsection2.
For more info see page @ref page2.
@subsection subsection1 The first subsection
Text.
@subsection subsection2 The second subsection
More text.
@subsubsection subsection2 A subsection to a subsection
Text for the sub-subsection.
*/
/*!
@page page2 Another page
Even more info.
*/
Customization (output format, layout & style)
Disclaimer: Doxygen can output, directly or indirectly, several formats; at the moment, I’m only interested in the generated HTML output!
The default layout and colors of generated Doxygen documentation looks a bit, hmmm, “functional” or “expedient”: It’s not bad, but the look and feel can seem a bit dull and dated…
But fear not, there are ways the change (customize) the layout and style: https://www.doxygen.nl/manual/customize.html
–> TODO
Further reading
Film & Television (55)
How To (64)
Journal (17)
Miscellaneous (4)
News & Announcements (21)
On Software (12)
Projects (26)