CPP / C++ Notes - Doxygen - Documentation Generator
Table of Contents
1 Doxygen Documentation Generator
1.1 Overview
Doxygen is a tool that can generate project documentation in html, pdf or Latex from code comments formatted with Doxygen markup syntax. The generated documentation makes easier to navigate and understand the code as it may contain all public functions, classes, namespaces, enumerations, side notes and code examples.
- Author: Dimitri Van Heesch (1997)
- Official Web Site: http://www.doxygen.nl/
- Projects using Doxygen:
Supported Languages besides C++:
- C
- C++
- Fortran
- Objective-C
- C#
- PHP
- Python
- IDL (Corba, MIDL - Microsft Interface Definition Language)
- VHDL
- Tcl
- D-Language (Not full support)
Online Examples of Doxygen Documentation:
- SFML [Best] - Simple and Fast Multimedia Library
- Well known game development library.
- Doxygen Configuration:
- OpenCV [Best] - Open Source Computer Vision
- Doxygen Configuration:
- Magnum Graphics [Best] - Lightweight and modular C++11/C++14 graphics
middleware for games and data visualization https://magnum.graphics/
- Github: https://github.com/mosra/magnum
- Doxygen Configuration:
- OpenFoam - Open Source C++ library for CFD (Computational Fluid
Dynamics) with toolboxes for fluid dynamics, chemical reactions,
turbulence, heat transfer and so on.
- More at: https://en.wikipedia.org/wiki/OpenFOAM
- Doxygen Configuration:
- CERN's Root Framework
- Doxygen Configuration:
- Eigen3 - Template-based library for Linear Algebra.
- Ogre3D - Game Engine (Object-Oriented Graphics Rendering Engine)
- GslWrapper - C++ wrapper class for the GNU Scientific Library
- FreeBSD Kernel Code
Other C++ Documentation Generators:
- Github: foonathan/standardese
- Creator: Jonathan Müller
- A (work-in-progress) nextgen Doxygen for C++ - this documentation generator uses libclang as its parser. By using this library, the generator can extract more useful information and metadata about the code.
- Video: Lightning Talks Meeting C++ 2016 - Jonathan Müller - Standardese
- QT5 QDoc (No well documented, lack examples.)
- Creator: QT Company
- "QDoc is a tool used by Qt Developers to generate documentation for software projects. It works by extracting QDoc comments from project source files and then formatting these comments as HTML pages or DITA XML documents. QDoc finds QDoc comments in .cpp files and in .qdoc files. QDoc does not look for QDoc comments in .h files."
- NaturalDocs (Basic support for C++, full support only for C#.)
- "Natural Docs lets you document code written in any of 20 programming languages, plus it can be easily extended for more so whatever you use, it can too. And if your project uses multiple languages, no problem! It will all be included in the same set of documentation."
- Supported Languages: https://www.naturaldocs.org/languages/
- Sphinx
- Sphinx is a documentation generator for Python. However, it can generate C++ documentation by using the metadata created by Doxygen.
- https://breathe.readthedocs.io/en/latest/
- Is Sphinx already suitable for C++ documentation?
- ROBODoc - Official Web Site
Other Documentation Generators:
- Pydoc - Python standard documentation generator.
- Ddoc - Documentation Generator for D-language (Walter Bright)
See also:
1.2 Installing Doxygen
Windows:
Installation via Chocolately package manager:
$ choco install doxygen.portable --version 1.8.9.1
Installing via scoop package manager:
$ scoop install doxygen Installing 'doxygen' (1.9.0) [64bit] doxygen-1.9.0.windows.x64.bin.zip (22.6 MB) [==================================] 100% Checking hash of doxygen-1.9.0.windows.x64.bin.zip ... ok. Extracting doxygen-1.9.0.windows.x64.bin.zip ... done. Linking ~\scoop\apps\doxygen\current => ~\scoop\apps\doxygen\1.9.0 Creating shim for 'doxygen'. Creating shim for 'doxyindexer'. Creating shim for 'doxysearch.cgi'.
Linux Distributions
Fedora Linux:
$ sudo dnf install doxygen.x86_64
Ubuntu or Debian Linux:
$ sudo apt-get install doxygen
1.3 Doxygen Tags Ref Card
Tags for Documenting File
Note: Those tags should be placed at top of file.
Tag | Description |
---|---|
@file <FILENAME> | File Name |
@author <AUTHOR_NAME> | Author name |
@brief <BRIEF> | Short description |
@date <DATE> | Date |
Example: => File: IDownloader.hpp
/** * @file IGraphicsContext.hpp * @brief Graphics Context Interface * @author Somebody else * @date 2012-02-20 ***********************************************/ class IGraphicsContext { virtual ~IGraphicsContext() = default; virtual void draw() const = 0; virtual void dawLine(const Point& p1, Point& p2) = 0; };
Tags for Documenting Functions, Classes, Methods and so on
Tag | Description |
---|---|
General Description | |
@brief | Brief description of class or function (fits a single line) |
@details | Details about class or function |
@author <AUTHOR NAME> | Insert author name |
Function Or Method Documentation | |
@param <PARAM> <DESCR> | Function or method parameter description |
@param[in] <PARAM> <DESCR> | Input parameter (C-function) |
@param[out] <PARAM> <DESCR> | Output paramter of C-style function that returns multiple values |
@param[in, out] <PARAM> <DESCR> | Parameter used for both input and output in a C-style function. |
@tparam <PARAM> <DESCR> | Template type parameter |
@trhow <EXCEP-DESCR> | Specify exceptions that a function can throw |
@pre <DESCR> | Pre conditions |
@post <DESCR> | Post conditions |
@return <DESCR> | Description of return value or type. |
Code Blocks | |
@code … <C++-Code>… @encode | C++ code example. |
Miscellaneous | |
@remark | Additional side-notes |
@note | Insert additional note |
@warning | |
@see SomeClass::Method | Reference to some class, method, or web site |
@li | Bullet point |
@todo <TODO-NOTE> | TODO annotation, reminders about what is still needs to be done. |
1.4 Doxyfile Settings
This section provides suitable settings for the Doxygen configuration file Doxyfile generated with the command $ doxygen -g or with the application DoxyWizard.
Set project name:
PROJECT_NAME = "MyProject"
Set project description:
PROJECT_BRIEF = "Library for loading C++ classes from C or any C-compatible FFI."
Set Input directory
- Directory containing source code to be scanned. In this case, this directory is set to ./src which contains all source code src/main.cpp, src/class1.hpp, class1.cpp and so on. The default value of the entry INPUT is the current directory where is the Doxyfile.
# The INPUT tag is used to specify the files and/or directories that contain # documented source files. You may enter file names like myfile.cpp or # directories like /usr/src/myproject. Separate the files or directories with # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. INPUT = ./src
Set Output directory:
- Set the directory where html or latex documentation will be generated.
# Generates the index.html page at ./docs/html/index.html OUTPUT_DIRECTORY = ./docs
Force code to be regarded as C++ code:
- Explanation: Header files intended to be used by both C and C++
between the statements
_ifdef __cplusplus ... #endif
can be understood by Doxygen as C-code, not C++ code. So, any class, struct, namespace of function defined in this namespace will be discarded. The solution to this shortcoming is to notify Doxygen that the macro__cplusplus
is defined.
# The PREDEFINED tag can be used to specify one or more macro names that are # defined before the preprocessor is started (similar to the -D option of e.g. # gcc). The argument of the tag is a list of macros of the form: name or # name=definition (no spaces). If the definition and the "=" are omitted, "=1" # is assumed. To prevent a macro definition from being undefined via #undef or # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. PREDEFINED = __cplusplus
Disable Latex Documentation Generation:
- Disabling Latex - makes the generation of documentation faster. Besides that, processing Latex requires a huge number of dependencies.
GENERATE_LATEX = NO
Entry: Distribute group doc:
# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. # The default value is: NO. DISTRIBUTE_GROUP_DOC = YES
Extract everything from source code
- This option is useful for undestandign new code.
# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in # documentation are documented, even if no documentation was available. Private # class members and static file members will be hidden unless the # EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. # Note: This will also disable the warnings about undocumented members that are # normally produced when WARNINGS is set to YES. # The default value is: NO. EXTRACT_ALL = YES
Source browser
- Useful for navigating and understanding unfamiliar code.
# If the SOURCE_BROWSER tag is set to YES then a list of source files will be # generated. Documented entities will be cross-referenced with these sources. # # Note: To get rid of all source code in the generated output, make sure that # also VERBATIM_HEADERS is set to NO. # The default value is: NO. SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body of functions, # classes and enums directly into the documentation. # The default value is: NO. INLINE_SOURCES = YES
1.5 Example
1.5.1 Overview
Files: Gist with full Code
Getting the sample code:
$ git clone https://gist.github.com/caiorss/b04df92734c93e300658285d0b76ed07 example-doxygen Cloning into 'example-doxygen'... remote: Enumerating objects: 4, done. remote: Counting objects: 100% (4/4), done. remote: Compressing objects: 100% (4/4), done. remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (4/4), done. $ cd example-doxygen $ ls Doxyfile mathutils.hpp
Generate html documentation:
$ doxygen Doxyfile Notice: Output directory `./docs' does not exist. I have created it for you. Searching for include files... Searching for example files... Searching for images... Searching for dot files... Searching for msc files... Searching for dia files... Searching for files to exclude Searching INPUT for files to process... Searching for files in directory /home/archbox/root-scripts/example-doxygen Reading and parsing tag files Parsing files Preprocessing /home/archbox/root-scripts/example-doxygen/mathutils.hpp... Parsing file /home/archbox/root-scripts/example-doxygen/mathutils.hpp... Building group list... ... ... ... ... Generating file member index... Generating example index... finalizing index lists... writing tag file... lookup cache used 46/65536 hits=123 misses=47 finished...
List generated documentation:
$ ls docs/ Doxyfile mathutils.hpp $ tree docs -L 2 docs ├── html │ ├── annotated.html │ ├── bc_s.png │ ├── bdwn.png │ ├── classes.html │ ├── classMathUtils_1_1XYChart.html │ ├── classMathUtils_1_1XYChart-members.html │ ├── closed.png │ ├── doc.png │ ├── doxygen.css ... ... ... ... ... ... │ ├── tab_a.png │ ├── tab_b.png │ ├── tab_h.png │ ├── tabs.css │ ├── tab_s.png │ └── todo.html ... ... ... ... ... ... 3 directories, 62 files
Open documentation in the browser:
$ firefox docs/html/index.html
If the project Doxyfile configuration file does not exist, a default one can be generated with Doxygen:
$ doxygen -g # Default output file "Doxyfile" $ doxygen -g OutputFile.cof
1.5.2 Type Aliases
Simple type alias:
/// Mathematical function of type double using MathFunc = std::function<double (double)>;
Output:
Templated type alias
/// Generic math function /// @tparam T Any float-point type such as float, double or long double template<class T> using MathFuncGen = std::function<T (T)>;
1.5.3 Enumeration MathErrorCode
Enumeration code (file: mathutils.hpp):
/// @brief Mathematical error code enum class MathErrorCode: std::uint32_t { /// Bit 0 (value 0x00 or 0) not set => Means no error E_OK = 0x00, /// bit 0 (value 0x01 or 1) means that an error of any type happened E_ERROR = 0x01, /// bit 1 (value 0x02 or 2) Overflow error E_OVERFLOW = 0x02, /// bit 2 (value 0x04 or 4) Undeflow error E_UNDERFLOW = 0x04, /// bit 3 (value 0x08 or 8) Not a number E_NAN = 0x08, /// bit 4 (value 0x10 or 16) Root, series or algorithm result doesn't converge. E_CONVERGENCE = 0x10, /// bit 5 (value 0x20 or 16) Maximum iterations reached E_MAX_ITER = 0x20 };
Output:
1.5.4 Function NewtonSolver
File: mathutils.hpp
/** @brief Contains non-linear equations solvers */ namespace MathUtils::Solvers{ // Note: Nested namespaces are only available in C++17. using namespace MathUtils::Base; /** * @brief Solves non-linear equation with Newton method. * * @details * Solves a non-linear equation using the Newton method which uses the * function and its derivate function for finding a suitable approximation * to the equation root. * * @see MathUtils::Base::MathFunc * @see https://en.wikipedia.org/wiki/Newton%27s_method * @todo Implement unit test with lots of test cases. * * @param fun Non-linear function f(x) * @param dfun Derivative of non-linear function df(x) = d/dx f(x) * @param x0 Initial guess * @param eps Tolerance for stopping criteria. * @return Equation result object containing result and error code. */ MathResult NewtonSolver(MathFunc fun, MathFunc dfun, double x0, double eps); ... ... ... ... ... ... ... ... ... ... ... ...
Output:
1.5.5 Templated Function GenericNewtonSolver
File: mathutils.hpp
/** @brief Contains non-linear equations solvers */ namespace MathUtils::Solvers{ ... .... ... .... ... .... /// @brief Solves non-linear equation with Newton method. /// /// @tparam T Any float-point type such as float, double or long double /// @param fun Non-linear function f(x) /// @param dfun Derivative of non-linear function df(x) = d/dx f(x) /// @param x0 Initial guess /// @param eps Tolerance for stopping criteria. /// @return Equation result as a float point type T. /// /// @details /// Solves non-linear equation using Newton method. This function needs two /// functions, the function to be solved @p fun and its derivate @p dfun /// /// @note The function f(x) must be continues and differentiable. /// @warning Throws NonCoverge exception when the root is not found. /// /// @see NewtonSolver /// @see https://en.wikipedia.org/wiki/Newton%27s_method /// /// Example: /// @code /// // Solve f(x) = x^2 - 25.0 , df(x) = 2x around x0 = 10.0 /// auto fun = [](double x){ return x * x - 25.0 }; /// auto dfun = [](double x){ return 2 * x; } /// /// double root = GenericNewtonsolver(fun, dfun, 10.0, 0.001); /// std::cout << "Root = " << root << std::endl; /// @endcode /// template<typename T> auto GenericNewtonSolver(MathFuncGen<T> fun, MathFuncGen<T> dfun, T x0, T eps) -> T; } // --- End of Namespace MathUtils::Solvers ----//
Output:
1.5.6 C-Function daxpy
/** @brief C++ implementation of Fotran BLAS daxypy Computes the equation ys[i] <- xs[i] * alpha + beta @note Function with C-linkage. @param[in] n Array size. Size of xs and ys @param[in] xs Input array xs @param[in, out] ys Output array ys @param[in] alpha Linear coefficient @return Void */ extern "C" auto daxpy(size_t n, double const* xs, double* ys, double alpha, double beta) -> void;
Output:
1.5.7 Class XYChart
/// @brief Class for plotting cuves, equations and differential equations. /// @author Ghost Author class XYChart{ public: /// @brief Construct plot object with a given dimension. /// /// @pre The chart size must not be negative. /// /// @param width Initial XYChart width /// @param height Initial XYChart length /// XYChart(double width, double length); /// Class destructor virtual ~XYChart() = default; /// @brief Clear chart /// @details Clear all drawings and plots in the chart area. virtual void clear(); /// @brief Add curve x[i], y[i] to chart /// /// @pre Precondition: the arrays x[] and y[] must have size n. /// @post There are no post conditions. /// /// @param n array size /// @param x array of x-coordinates values /// @param y array of y-coordinates values /// @return Void /// /// @details /// Plot the curve compriseds of points P[i] = (X[i], Y[i]), /// where i = 0, 1, 2... n - 1. /// void addCurve(size_t n, const double x[], const double y[]); /// Copy constructor XYChart(Plotter const&) = delete; /// Copy-assignment operator XYChart& operator=(XYChart const&) = delete; private: };
Output:
Constructor
/// @brief Construct plot object with a given dimension. /// /// @pre The chart size must not be negative. /// /// @param width Initial XYChart width /// @param height Initial XYChart length /// XYChart(double width, double length);
Output:
Method addCurve
/// @brief Add curve x[i], y[i] to chart /// /// @pre Precondition: the arrays x[] and y[] must have size n. /// @post There are no post conditions. /// /// @param n array size /// @param x array of x-coordinates values /// @param y array of y-coordinates values /// @return Void /// /// @details /// Plot the curve compriseds of points P[i] = (X[i], Y[i]), /// where i = 0, 1, 2... n - 1. /// void addCurve(size_t n, const double x[], const double y[]);