📚 Creating C++ API Documentation with Sphinx #
Following on from an earlier Doxygen post, in this post, we look at creating C++ Sphinx docs. We noted Doxygen is stable and works well with CMake in that earlier post. Sphinx does bring some flexibility to the table though, as well as some more modern themes.
I tried adding Sphinx docs to a game I am working on. For the most part, I followed a good post I found on generating Sphinx documentation from Doxygen with Breathe and CMake. In this post, I highlight what I did differently, as well as include links to Breathe and Sphinx resources.
🦁 How is Sphinx Different to Doxygen? #
Doxygen default styling can look a little brutalist, with a look generating an early Internet feel. This might be fine, though, for an internal documentation site used internally. Other use cases, however, might call for a fresher feel.
One advantage of Doxygen is that you write documentation in a Markdown-like syntax (in your code source). Markdown is quick to learn and will already be familiar to many content writers. Sphinx uses reStructuredText , so there is a little more to learn for generating some content. We will see, though, that you can generate your Sphinx output from C++ classes documented with Doxygen (Markdown-based) comments, which limits the places you will need to use reStructuredText.


🧘🏽 What is Breathe? #
Breathe is a Sphinx extension. It lets Sphinx generate your documentation, using the XML output
from Doxygen as an input. Sphinx and Breathe are Python-based projects, and they get another
mention (further down) when I talk about requirements.txt
.
Sphinx Resources #
- Clear, Functional C++ Documentation with Sphinx and Breathe blog post. I based my documentation generation on this post, making some minor changes (mentioned further down).
- Sphinx Themes Gallery - showcase for some Sphinx Themes.
- reStructuredText primer - reStructuredTest is the markup language used by Sphinx.
As an aside, that first link mentions fmtlib docs as an example of what Sphinx docs can look like. It seems the fmtlib project has since moved from Sphinx to MkDocs .
Sphinx Config: index.rst
& conf.py
#
Both index.rst
and conf.py
get generated
by the sphinx-quickstart
step in the Clear, Functional C++ Documentation blog post that I followed. index.rst
is a reStructuredText file,
and essentially the markup for the site home page.
index.rst
#
1 .. Arkanoid documentation master file, created by2 sphinx-quickstart on Sat Aug 10 10:23:02 2024.3 You can adapt this file completely to your liking, but it should at least4 contain the root `toctree` directive.56 Arkanoid documentation7 ======================89 Arkanoid clone game docs. Project10 `GitHub repo <https://github.com/rodneylab/arkanoid-clone>`_.111213 .. toctree::14 :maxdepth: 215 :caption: Contents:1617 Docs18 ====192021 .. doxygenstruct:: Audible22 :members:2324 .. doxygenstruct:: AxisAlignedOneWayCollider25 :members:
A key difference with Doxygen is that you declare which structs you want documented, and in which section their documentation is placed. This brings more flexibility, though you need to create an external process to ensure you remember to add documentation for new APIs.
Lines 21
– 22
and
24
– 25
(above)
show how to add documentation from Doxygen for the Audible
and AxisAlignedOneWayCollider
C++ structs to the “Docs” section.
conf.py #
1 # Configuration file for the Sphinx documentation builder.2 #3 # For the full list of built-in configuration values, see the documentation:4 # https://www.sphinx-doc.org/en/master/usage/configuration.html56 # -- Project information -----------------------------------------------------7 # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information89 project = "Arkanoid"10 copyright = "2024, Rodney Johnson"11 author = "Rodney Johnson"1213 # -- General configuration ---------------------------------------------------14 # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration1516 extensions = ["breathe"]17 breathe_default_project = "Arkanoid"1819 templates_path = ["_templates"]20 exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]212223 # -- Options for HTML output -------------------------------------------------24 # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output2526 html_theme = "press"27 html_static_path = ["_static"]
I set my chosen theme, press, in line 26
. The theme
includes a dark mode, and requires the Python package sphinx_press_theme
, which I added to the project requirements.txt
. I also added breathe
, sphinx
and related required packages to that file.

breathe==4.35.0 \--hash=sha256:52c581f42ca4310737f9e435e3851c3d1f15446205a85fbc272f1f97ed74f5be# TRUNCATED...sphinx==8.0.2 \--hash=sha256:56173572ae6c1b9a38911786e206a110c9749116745873feae4f9ce88e59391d# TRUNCATED...sphinx_press_theme==0.9.1 \--hash=sha256:eed3fdd8df249b67136b507dfc6a84d1a2c5feca5376960c6d4d28ada4f6cdf7
See the project repo (link further down), for the full list requirements.txt
file.
CMake Config #
Following the Clear Function C++ Documentation blog post (mentioned earlier), I added a new
section at the bottom of the existing Doxygen CMake file (docs/CMakeLists.txt
) to generate the Sphinx documentation:
1 option(BUILD_DOC "Build documentation" ON)23 # Doxgen documentation generation4 # TRUNCATED...56 # Sphinx documentation generation7 find_package(Sphinx REQUIRED)8 set(SPHINX_SOURCE ${CMAKE_CURRENT_BINARY_DIR})9 set(SPHINX_BUILD ${CMAKE_CURRENT_BINARY_DIR}/sphinx)10 set(DOXYGEN_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/doc_doxygen)11 add_custom_command(12 TARGET doc_doxygen13 POST_BUILD14 COMMAND15 ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/../docs/index.rst16 ${CMAKE_CURRENT_BINARY_DIR}/index.rst17 COMMAND18 ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/../docs/conf.py19 ${CMAKE_CURRENT_BINARY_DIR}/conf.py)20 add_custom_target(21 Sphinx ALL22 COMMAND23 ${SPHINX_EXECUTABLE} -b html24 -Dbreathe_projects.Arkanoid=${DOXYGEN_OUTPUT_DIR}/xml ${SPHINX_SOURCE}25 ${SPHINX_BUILD}26 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}27 COMMENT "Generating documentation with Sphinx")
-
Line
10
setsDOXYGEN_OUTPUT_DIR
, used by Sphinx as an input. -
In lines
14
-19
, I copy the Sphinx config files from the project input folders to the build folder. -
In line
24
, I add the path for the Doxygen generated XML output.
I also updated docs/Doxyfile.in
to output XML (it just outputs HTML
by default).
# ..TRUNCATEDGENERATE_XML = YES
🎬 Creating C++ Sphinx Docs: GitHub Action #
In the previous Doxygen post, I generated the docs in a GitHub Action and hosted the site on GitHub Pages. The Action publishes documentation to GitHub Pages on each successful merge.
Here is the updated GitHub Action, which uses the freshly added Sphinx output (.github/workflows/documentation.yml
).
1 name: Documentation2 on:3 push:4 tags:5 - "*"6 branches: [main, master]7 permissions:8 contents: read9 jobs:10 build:11 name: Build and publish documentation12 permissions:13 contents: write14 pages: write15 runs-on: ubuntu-latest16 steps:17 - name: Harden Runner18 uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.119 with:20 egress-policy: audit21 disable-telemetry: true22 - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.723 - name: Install Linux Dependencies24 if: runner.os == 'Linux'25 run: sudo apt-get update && sudo apt-get install libxrandr-dev libxcursor-dev libudev-dev libopenal-dev libflac-dev libvorbis-dev libgl1-mesa-dev libegl1-mesa-dev freeglut3-dev libxinerama-dev libxi-dev26 - name: Setup Cpp27 uses: aminya/setup-cpp@bfbfe9ca0b2c69a076f6513393d61fc478fb54f8 # v0.41.028 with:29 clangtidy: true30 - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.031 - name: Install Docs32 run: |33 sudo apt-get install doxygen34 pip install -r requirements.txt --require-hashes35 - name: configure36 run: |37 cmake -H. -Bbuild -G "Unix Makefiles" -DCMAKE_BUILD_TYPE="Debug"38 - name: building39 run: |40 cmake --build build --config Debug --target doc_doxygen Sphinx -j441 - name: Deploy to GitHub Pages42 uses: Cecilapp/GitHub-Pages-deploy@526a34f794dfdf7edd6a4ac94321b1e7945910c0 # v343 env:44 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}45 with:46 build_dir: ./build/docs/sphinx
I just change the last line here to point GitHub Pages to the Sphinx output. I did not need to
update anything in the GitHub Pages config console. The Action will install the new Python
dependencies from the updated requirements.txt
file already included
in line 34
.
🗳 Poll #
🙌🏽 Creating C++ Sphinx Docs: Wrapping Up #
In this post on creating C++ Sphinx docs, I talked about how I added Sphinx documentation to a C++ game. More specifically, we saw:
- a fantastic resource for getting started with Sphinx and CMake;
- some tweaks for updating the Sphinx theme and CMake config; and
- a GitHub Action for publishing Sphinx documentation to GitHub Pages.
I hope you found this useful. As promised, you can get the full project code on the Rodney Lab GitHub repo . Do let me know if you found this content useful and would like to see more similar content. Also reach out if there is anything I could improve to provide a better experience for you.
🙏🏽 Creating C++ Sphinx Docs: Feedback #
If you have found this post useful, see links below for further related content on this site. Let me know if there are any ways I can improve on it. I hope you will use the code or starter in your own projects. Be sure to share your work on X, giving me a mention, so I can see what you did. Finally, be sure to let me know ideas for other short videos you would like to see. Read on to find ways to get in touch, further below. If you have found this post useful, even though you can only afford even a tiny contribution, please consider supporting me through Buy me a Coffee.
Finally, feel free to share the post on your social media accounts for all your followers who will find it useful. As well as leaving a comment below, you can get in touch via @askRodney on X (previously Twitter) and also, join the #rodney Element Matrix room. Also, see further ways to get in touch with Rodney Lab. I post regularly on Game Dev as well as Rust and C++ (among other topics). Also, subscribe to the newsletter to keep up-to-date with our latest projects.