C/C++ Documentation Using Sphinx

Introduction

In my previous blog posts, I have described how to use Sphinx to create documentations for Python projects and how to use Doxygen to create documentations for C/C++ projects. While creating C/C++ documentations using Doxygen is somewhat simple, Doxygen also has some kind of limitations, such as its limited number of themes and lack of customization in creating new pages, which I have mentioned in my previous blog posts. It turns out that Sphinx could leverage the XML files generated by Doxygen to create the documentation for C/C++ projects by using the Sphinx extension Breathe.

In this blog post, I would like to briefly describe how to use Sphinx, Breath, and Doxygen to create C/C++ documentations. Because Doxygen has to be used anyway for creating XML files from the annotated C/C++ source code, it is highly recommended that the reader should go through the previous two blog posts, Python Documentation Using Sphinx and C/C++ Documentation Using Doxygen, before reading this one.

Triangle C++ Library

This time, we are also using the C++ Triangle library trianglelib as an example. It could be found in the Sphinx C++ TriangleLib on my GitHub. The documentation corresponding to this project could be found on Read the Docs.

The installation of the library and the building of the documentation could be found in the READMEs in the repository.

Note that this repository is almost identical to the code used in the Doxygen CPP TriangleLib repository, except that the Sphinx configuration file is different and it has additional reStructuredText files required for Sphinx, and an additional dependency on Breathe.

Notes

Sphinx Configurations

The Sphinx configuration file conf.py used in this project is slightly different from the one used in the Doxygen CPP TriangleLib project.

It requires to use the following Sphinx extensions.

1
2
3
4
5
6
7
8
9
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.doctest',
'sphinx.ext.mathjax',
'sphinx.ext.viewcode',
'sphinx.ext.imgmath',
'sphinx.ext.todo',
'breathe',
]

In addition, we have added the Doxygen XML automatic building for the documentations and told the Breathe extension where the XML files are.

1
2
3
4
5
6
import subprocess
subprocess.call('make clean', shell=True)
subprocess.call('cd ../../doxygen ; doxygen', shell=True)

breathe_projects = { "trianglelib": "../../doxygen/build/xml/" }
breathe_default_project = "trianglelib"

Doxygen Configurations

The Doxygen configuration file Doxyfile remained the same. Note that GENERATE_XML has to be YES, because Sphinx uses the XML files generated by Doxygen to create documentations, instead of parsing the source code directly.

reStructuredText

The Breathe extension will add some additional reStructuredText directives to Sphinx. We could use doxygenclass or doxygenfunction for documenting classes and functions, respectively. For example, using the following reStructuredText, I have created the documentation for a class trianglelib::Triangle and two functions trianglelib::createTriangle and trianglelib::isTriangle.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
The trianglelib C++ API Reference
=================================

C++ Classes
-----------

.. doxygenclass:: trianglelib::Triangle
:members:

C++ Functions
-------------

.. doxygenfunction:: trianglelib::createTriangle

.. doxygenfunction:: trianglelib::isTriangle

In the API reStructuredText file of the Sphinx Python Triangle Library, we have seen how to use automodule to automatically document all the classes and functions in a single file, without having to specify the classes and functions one by one. We could also do similar things using the autodoxygenindex directive. Unfortunately, I think the implementation of autodoxygenindex is not matured yet, and it would introduce some unwanted information in the documentation. In addition, in Python, we tend to separate different modules into different Python files and Sphinx could take advantage of that, whereas in C++, we tend to put a lot of declarations in one single header file. Using autodoxygenindex would put almost the documentations of almost all the classes and functions together. If we would like to generate a single API documentation, it is OK. However, if we would like to separate the documentations of different classes and functions into modules, it will be problematic.

So I think probably specifying classes and functions one by one manually in different reStructuredText files might be best option currently for documenting C/C++ projects using Sphinx.

Final Remarks

Creating C/C++ documentations using Sphinx and Breathe is one step further to creating C/C++ documentations using Doxygen. Unfortunately, this means that the user would have to know how to create C/C++ documentations using Doxygen.

Sphinx and Breathe does not seem to read C/C++ source code directly. Otherwise, it might be able to directly parse C/C++ source code without having to rely on Doxygen.

References

Author

Lei Mao

Posted on

08-05-2020

Updated on

08-05-2020

Licensed under


Comments