Learn how to use doxygen

In my previous post, I've described how I used design patterns for my TelloCpp driver.

But, while project design is important -

A project is nothing without proper documentation


I always document my code, here's why:

  • It makes it easy to resume developing a neglected code
  • It results in a better design
    • If a function/class cannot be described in 1 sentence, then it is not designed properly

During the TelloCpp driver project,
I took the opportunity to learn how to Doxygen:

Doxygen is the de facto standard tool for generating documentation from annotated C++ sources, but it also supports other popular programming languages such as C, Objective-C, C#, PHP, Java, Python, IDL (Corba, Microsoft, and UNO/OpenOffice flavors), Fortran, VHDL and to some extent D.

Simply put - it generates an HTML out of a [properly] documented project.

This is how I used it:

  • Installing Doxygen:
sudo apt-add-repository universe  
sudo apt-get update  
sudo apt-get install doxygen  
  • Generating Doxygen config file:
cd /home/gal/dev/tello_driver/docs  
doxygen -g <config-file>  
  • Editing the generated configuration file:

This is a huge file (with 2580 lines in it!). But don't worry, tweaking with it is easy, here is what I changed in it:

Some general settings:

LINE 35 - PROJECT_NAME           = "TelloCpp driver"  
LINE 47 - PROJECT_BRIEF          = "A one of its kind TelloCpp driver, that supports the unofficial SDK."  
LINE 54 - PROJECT_LOGO           = "/home/gal/dev/tello_driver/docs/TelloCppDriver.jpg"  
LINE 61 - OUTPUT_DIRECTORY       = "/home/gal/dev/tello_driver/docs/doxygen"  

These are scope-related documentation settings:
Mind that if a project is to be exported as a package, one might turn off some of these settings.

LINE 470 - EXTRACT_ALL            = YES  
LINE 476 - EXTRACT_PRIVATE        = YES  
LINE 482 - EXTRACT_PRIV_VIRTUAL   = YES  
LINE 488 - EXTRACT_PACKAGE        = YES  
LINE 494 - EXTRACT_STATIC         = YES  

These next settings are nice, they make all the /** @todo */ documentation appear under a page called TODO

LINE 664 - GENERATE_TODOLIST      = YES

# Same principal with - /** @test */
LINE 670 - GENERATE_TESTLIST      = YES  

This is the main entrance of the project path:

LINE 832 - INPUT                  = "/home/gal/dev/tello_driver/"  
# Document subdirectories as well
LINE 911 - RECURSIVE              = YES  

This is an important setting:
If one's project has libraries that also include documentation, they could exclude them from being doxy-generated along with the project.

(Note: See how I entered a list of paths here)

LINE 920 - EXCLUDE                = /home/gal/dev/tello_driver/build /home/gal/dev/tello_driver/lib/googletest /home/gal/dev/tello_driver/lib/spdlog  

Another nice setting I love:
Organize all the /** @example */ annotations under Examples page.

LINE 953 - EXAMPLE_PATH           = /home/gal/dev/tello_driver/examples

# This makes a main-page out of a markdown.
LINE 1029 - USE_MDFILE_AS_MAINPAGE = /home/gal/dev/tello_driver/README.md

# Include functions body to the generated HTML's
LINE 1048- INLINE_SOURCES         = YES

# Enable this If you have mathjax inside your documentation
LINE 1607 - USE_MATHJAX           = YES  
  • Doxygen generation is even easier:
cd /home/gal/dev/tello_driver/docs # Doxygen file directory  
doxygen TelloCppDoxygen  

A successful doxy-generation looks like that:

You can access the generated documentation via the index.html file:


Doxygen is very powerful

Using this tool, you can assure that his project follows preliminary designs.

Here are the class relations designs that I made for the TelloCpp driver project.

Take a closer look at the ISubject and its users.

Using Doxygen auto-generated graphs - I could rest assure that the mechanism of the observer-observable pattern was implemented accordingly (see the similarity):

In my opinion - That's awesome!
(I did change the interface name, so eventually, the design wasn't strictly followed. But still, look at it!).


Using Doxygen is fluent.

If the project is documented according to Doxygen's syntax from start

See this example, from the DataManager:

It follows Doxygen documentation syntax.
Thus after generating documentation it processed without a fuss:


How to use MATHJAX in Doxygen documentation

In their site, they provide a description that is friendly enough.

I didn't need to use complex math in this project, hence I've made a simple MATH use:

    /**
     * @brief With close-loop operation. \n
     * - Takeoff \n 
     *   - wait until mode is tello_protocol::FlyModes::HOLDING_POSITION \n
     * - SetRoll in a range from \f$0 \rightarrow 0.5 \rightarrow 0 \rightarrow -0.5\f$ \n <---------------- MATHJAX
     *   Rolling amount measured in \f$ \text{stick}\% \f$ <---------------- MATHJAX
     * - Land \n
     *   - wait until mode is tello_protocol::FlyModes::LANDING \n
     * 
     */
    void StartScenario4();

After generating documentation:

With zero efforts, mathematics can become a part of the documentation!


Pros and cons

+ Doxygen configuration file is portable. You don't need to keep all generated files, the conf-file is enough.
- Doxgen conf-file can't process shell environment variables such as $HOME, or ~. The path need's to be hardcoded.

As stated above, Doxygen is the de facto standard tool for generating documentation.
Use it, that's the engineer's way.


Thats it :)

Cheers, Gal.

GalBrandwine

Read more posts by this author.

Subscribe to What I Made Today

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!