Posted on: 2025-09-15, Updated on: 2025-09-15 20:56:09 | Read time: 3.7 minutes
Topic(s): programming
Doxygen is a tool that you can use to automate documentation generation for software projects. This guide will focus on setting up and using Doxygen in C++ projects.
Some of the benefits and features of Doxygen are as follows:
To get started, you'll need to install Doxygen and (optionally) Graphviz if you want fancy class diagrams. On Fedora, you can install the needed packages with the following command:
$ sudo dnf install doxygen graphviz
You could also use the development-tools package group which installs Doxygen by default:
$ sudo dnf group install development-tools
On Debian/Ubuntu you can use:
$ sudo apt install doxygen graphviz
Once installed, you can generate a default configuration file for your project with:
$ doxygen -g Doxyfile
This creates a text file called Doxyfile
that controls how Doxygen scans your source code and generates documentation. For a small project you can often leave most of the defaults alone, but you'll likely want to update a few key settings:
PROJECT_NAME
– set this to the name of your project.PROJECT_NUMBER
– useful for indicating a specific version of your project.PROJECT_BRIEF
– short, single-line description to display at the top of the page.PROJECT_LOGO
– icon image file for your project.OUTPUT_DIRECTORY
– set where you want the generated docs to live (e.g. DoxyDocs/
).JAVADOC_AUTOBRIEF
– ensures first line of Javadoc-style comments don't need an explicit @brief
command.JAVADOC_BANNER
– ensure a /*********
Javadoc-style comment will be treated as a banner.INPUT
– important; list files and directories to document.RECURSIVE
– set the YES
if you want Doxygen to scan sub-directories (important if you have a nested directory structure for you source code files)I'll touch more on the Doxygen configuration file and its relevant options later in this guide.
Once your configuration is ready, generate documentation by running:
$ doxygen Doxyfile
There are a number of ways to structure a software project and C++ is no different. Thankfully, it is fairly easy to configure Doxygen to find your code and other documents.
By default you'll get an DoxyDocs/html/
directory with a browsable website and a DoxyDocs/latex/
directory if you want to produce PDF documents. I'll omit instructions for using the LaTeX documentation, since most likely you won't have a LaTeX distribution installed on your system.
Navigate to the parent of the DoxyDocs/html/
directory and run the following command to open the generate HTML documentation in your web browser:
xdg-open ./DoxyDocs/html/index.html
Doxygen picks up specially formatted comments in your source files. Instead of walking you through each, I figure it will be easiest to just show you one large example. It is possible to Doxygen comments in implementation files (.cpp
, .cxx
, .cc
), but typically it is most important to document the interface (C++ header files: .h
, .hpp
, .hxx
). You could use regular, non-Javadoc style comments for code that isn't part of your public API.
There are a few main comment styles that Doxygen recognizes:
///
: Useful for single-line comments./** ... */
: Standard Javadoc-style for multi-line comments./*! ... */
and //!
: Less common; for multi-line and single-line respectively.You can create inline comments for member variables using //!<
. You can think of the <
character as indicating “document the previous element.”
Some of the most common Doxygen comment tags you'll use are:
@brief
– short one-line description.@param
– describe a function parameter.@return
– describe what the function returns.@note
or @warning
– call out special behavior.@see
or @sa
(see also) – create cross-references to other related functions/classes.@code
and @endcode
– embed example blocks in your Doxygen comments@todo
– document pending tasks; placed in a special “Todo List” page.If you document your classes and methods this way, Doxygen will generate a structured reference for you, including cross-references between files, functions, and classes.
//! BGE namespace.
namespace BGE
{
class CommandParser; // Forward declare
BGE_DECLARE_PTR(CommandParser);
/**
* @brief A class to parse and handle command-line arguments.
*/
class CommandParser final
{
private: // Internal state
std::span<std::string_view> m_arguments; //!< List of command-line arguments passed to the program.
std::unordered_map<std::string, std::string> m_argumentMap; //!< Map of argument name to their corresponding values.
std::string m_lastError; //!< Stores the last error message encountered during parsing or operations.
// Bounds checking
double m_min = std::numeric_limits<double>::lowest(); //!< Minimum allowable value for arguments.
double m_max = std::numeric_limits<double>::max(); //!< Maximum allowable value for arguments.
bool m_bMinSet = false; //!< Indicates whether a minimum bound has been set.
bool m_bMaxSet = false; //!< Indicates whether a maximum bound has been set.
public:
/**
* @brief Constructs a CommandParser with a given list of arguments.
* @param arguments The command line arguments to be parsed.
*/
explicit CommandParser(std::span<std::string_view> arguments);
//! Default constructor.
~CommandParser(void) = default;
/**
* @brief Checks if an argument exists in the list.
* @param name The name of the argument to check for.
* @return true if the argument exists, false otherwise.
*/
bool Boolean(std::string_view name) const;
/**
* @brief Extracts a boolean parameter from the arguments.
* @param name The name of the parameter to extract.
* @param bValue Reference to store the extracted boolean value.
* @return Optional containing a boolean value if successful, empty otherwise.
*/
std::optional<bool> Boolean(std::string_view name, bool &bValue) const;
/**
* @brief Extracts an integer parameter from the arguments.
* @param name The name of the parameter to extract.
* @param value Reference to store the extracted integer value.
* @return Optional containing an integer value if successful, empty otherwise.
*/
std::optional<int> Integer(std::string_view name, int &value) const;
/**
* @brief Extracts a floating-point parameter from the arguments.
* @param name The name of the parameter to extract.
* @param value Reference to store the extracted float value.
* @return Optional containing a float value if successful, empty otherwise.
*/
std::optional<float> Float(std::string_view name, float &value) const;
/**
* @brief Extracts a double-precision floating-point parameter from the arguments.
* @param name The name of the parameter to extract.
* @param value Reference to store the extracted double value.
* @return Optional containing a double value if successful, empty otherwise.
*/
std::optional<double> Double(std::string_view name, double &value) const;
/**
* @brief Extracts a string parameter from the arguments.
* @param name The name of the parameter to extract.
* @param value Reference to store the extracted string.
* @return Optional containing a string value if successful, empty otherwise.
*/
std::optional<std::string> String(std::string_view name, std::string &value) const;
/**
* @brief Extracts a filename parameter from the arguments.
* @param name Reference to store the extracted filename.
* @return Optional containing the filename if successful, empty otherwise.
*/
std::optional<std::string> Filename(std::string &name) const;
/**
* @brief Sets the minimum allowable value for arguments.
* @param value The minimum value to set.
* @return Reference to the current CommandParser instance.
*/
CommandParser &Min(double value);
/**
* @brief Sets the maximum allowable value for arguments.
* @param value The maximum value to set.
* @return Reference to the current CommandParser instance.
*/
CommandParser &Max(double value);
/**
* @brief Sets the strict minimum bound for arguments (exclusive).
* @param value The bound value to set.
* @return Reference to the current CommandParser instance.
*/
CommandParser &Inf(double value);
/**
* @brief Sets the strict maximum bound for arguments (exclusive).
* @param value The bound value to set.
* @return Reference to the current CommandParser instance.
*/
CommandParser &Sup(double value);
/**
* @brief Detects and counts unprocessed excess arguments.
* @return The number of unprocessed arguments.
*/
int ExcessArguments(void) const;
/**
* @brief Retrieves the last error message encountered.
* @return String view of the last error message.
*/
std::string_view GetLastError(void) const;
private:
/**
* @brief Parses the given list of arguments and initializes the internal state.
* @param arguments The arguments to parse.
*/
void ParseArguments(std::span<std::string_view> arguments);
};
} // End namespace (BGE)
When you first opened the Doxyfile
you created, you likely got overwhelmed by the sheer size (2500+ lines) and amount of configuration options. Thankfully, the Doxygen configuration file template is quite well documented. There are relevant notes above each option with references to related options when appropriate. The Doxyfile
has hundreds of options, but a few are especially useful when starting out:
EXTRACT_PRIVATE
– set to YES
if you want private class members to appear in the docs.HAVE_DOT
and CALL_GRAPH
– enable these if you installed Graphviz, so you can generate call graphs and class diagrams.GENERATE_LATEX
– disable this (NO
) if you don't care about creating PDF documents and want faster runs.USE_MDFILE_AS_MAINPAGE
– point this at your README.md if you want that file to be the starting page of your docs (specify the file in the INPUT
value too).SOURCE_BROWSER
– set to YES
to generate a list of source files.STRIP_CODE_COMMENTS
– set to NO
if you want your Doxygen comments to be visible when viewing source file output.I usually start with the defaults and only enable features as I need them. A smaller configuration makes Doxygen faster to run and keeps the output simple.
NOTE: Since the Doxygen configuration file is quite long, use your text editor's search feature to find relevant items. Searching for items like
HTML_
orGENERATE_
can help jump around faster.
There are also numerous settings and ways to change the look and feel of Doxygen output. Here are a few common HTML look-and-feel options:
HTML_EXTRA_STYLESHEET
– set to a .css
file to override HTML output styling.DISABLE_INDEX
– when set to NO
, will give you a navbar.GENERATE_TREEVIEW
– when set to YES
, gives a sidebar tree.If want to use an extra CSS stylesheet, first take a look at the doxygen.css
file you can see in your HTML output directory. This can give you a better idea of which elements and CSS class are used, so you can make your desired customizations.
Doxygen is one of those tools that doesn’t take long to set up, but it pays off quickly once you start documenting your project. Certainly it is quite helpful when you expect other people to use your project, but even if you’re the only one reading the docs, having an automatically generated reference can make it easier to keep track of how your code fits together. Additionally, if you ever decide to publish or share your code, having decent documentation already in place is a big win. Thanks for reading!
Resources: