Exhale C++ API Documentation Generator

repository·master·Indexed 42 days ago

https://github.com/svenevs/exhale

An automatic C++ API documentation generator that bridges Doxygen and Sphinx. It utilizes Breathe to transform Doxygen's XML output into Sphinx-compatible reStructuredText, enabling the creation of Class, File, and Page hierarchies within Sphinx-based documentation websites.

Tokens
13.6K
Snippets
46
Records
73
Agent score
54%

What's inside Exhale

  1. Overview of Exhale

    master
    Exhale is an automatic C++ library API documentation generator. It integrates Doxygen, Sphinx, and Breathe to revive Doxygen's Class, File, and Page hierarchies as reStructuredText documents within Sphinx projects. This allows you to maintain beautiful Sphinx-generated websites while preserving the structural hierarchies provided by Doxygen, ensuring documentation stays in sync with your code as it is regenerated on the fly.
  2. Understand the Exhale Project Layout

    master

    For developers looking to extend or understand the internal structure of Exhale, the project is organized into several functional modules:

    • exhale.configs: Manages configuration from conf.py and provides the apply_sphinx_configurations bridge to Sphinx.
    • exhale.deploy: Handles Doxygen execution and the explode process, which transforms Doxygen XML into reStructuredText files.
    • exhale.graph: The core module that represents the documentation structure. It uses ExhaleRoot (similar to Doxygen's index.xml) to instantiate ExhaleNode objects representing documented items.
    • exhale.parse: Responsible for parsing file-level documentation from XML and converting it into valid reStructuredText.
    • exhale.utils: Provides helper methods for formatting, error reporting, and configuration serialization (required for Sphinx pickling).
  3. What is Exhale and how does it work?

    master

    Exhale is an automatic C++ library API generation utility that ports Doxygen's hierarchy view (classes and files) into the Sphinx domain.

    How it works:

    1. It parses your existing Doxygen XML documentation.
    2. It reconstructs the relationship graph (e.g., which file a class belongs to, or its namespace).
    3. It automatically generates a large number of reStructuredText files. These files act as wrappers for Breathe directives.
    4. It generates a root library document that links all API documents together. You are expected to include this root document in your top-level Sphinx toctree directive.

    Key Features:

    • Emulates Doxygen's HTML class and file hierarchies.
    • Includes enum in the Class Hierarchy.
    • Every generated file includes a reStructuredText label, allowing you to link to specific items (like an important class) from other parts of your documentation.
  4. Customize the Root API Document Layout

    master

    The main library page (the root document) is composed of several sections. You can customize the titles and content of these sections using keys in the exhale_args dictionary within your Sphinx conf.py.

    Layout Structure:

    1. Title: Uses rootFileTitle (unless \mainpage is used in Doxygen).
    2. Description: Uses afterTitleDescription.
    3. Page Hierarchy: Uses pageHierarchySubSectionTitle (only if Doxygen \page/\subpage commands are present).
    4. Class Hierarchy: Automatically included if class-like compounds exist.
    5. File Hierarchy: Automatically included.
    6. Hierarchy Description: Uses afterHierarchyDescription.
    7. API Section Title: Uses fullApiSubSectionTitle (defaults to "Full API").
    8. Unabridged API: The full index of all members.
    9. Body Summary: Uses afterBodySummary at the bottom of the page.

    Additional Controls:

    • fullToctreeMaxDepth: Controls the number of bullets shown in the unabridged API's toctree directives.
    • unabridgedOrphanKinds: Use this to exclude specific types from the full API listing.
    • listingExclude: Exclude specific items from listings.
  5. How Exhale integrates with Sphinx

    master

    Exhale works as a Sphinx extension that automates the generation of reStructuredText (rst) files from Doxygen XML output. To use Exhale, you must include both breathe and exhale in your Sphinx extensions list within conf.py.

    Execution Flow

    When you run make html, the following sequence occurs:

    1. Extension Loading: Sphinx loads breathe and exhale.
    2. Configuration: Exhale hooks into the builder-inited event to prepare for configuration. It reads settings from the exhale_args dictionary in your conf.py.
    3. Doxygen Execution: If configured, Exhale executes Doxygen to generate XML documentation.
    4. Explosion (RST Generation): Exhale's explode function parses the Doxygen XML and generates a graph of ExhaleNode objects, which are then written out as individual reStructuredText documents.
    5. Sphinx Parsing: Sphinx then picks up these newly generated .rst files from your source directory and processes them into the final documentation website.
  6. Prerequisites for using Exhale

    master

    Before using Exhale, ensure you meet the following requirements:

    1. Valid Doxygen XML: Exhale relies on your Doxygen XML documentation. If your Doxygen build produces warnings, Exhale may produce false relationships or orphaned documents. Ensure your Doxygen configuration (and preprocessor) is correctly set up to produce clean XML.
    2. Breathe Extension: Exhale is built on top of the Breathe extension. You must have Breathe configured in your Sphinx conf.py before configuring Exhale.
  7. Compare Exhale with Breathe alternatives

    master

    Exhale is specifically designed to provide Class, File, and Page hierarchies in Sphinx. If you do not need these specific hierarchies, consider these alternatives:

    1. breathe-apidoc: A tool included with breathe that is similar to the standard Sphinx sphinx-apidoc.
    2. .. autodoxygenindex:: directive: A directive provided by breathe that works well for smaller frameworks where a full hierarchy might be overkill.
  8. Use the Exhale Graph Module to navigate documentation

    master
    The exhale.graph module provides a graph-based representation of your documentation structure. It is composed of two primary classes: ExhaleRoot, which serves as the entry point for the documentation graph, and ExhaleNode, which represents individual elements (such as classes, functions, or modules) within that graph. This module allows you to programmatically traverse and inspect the relationships between different parts of your documented code.
  9. Handle file and namespace level documentation in Exhale

    master

    Exhale uses a "best-faith-effort" parser for file and namespace level documentation because Breathe's ile and amespace directives are not directly compatible. While it supports basic block-level elements like listings, it is not a robust parser.

    If your documentation renders unexpectedly, you can use a verbatim reStructuredText (RST) environment to bypass the mini-parser.

    Important Note on Cross-Referencing: When using a verbatim RST environment, Doxygen commands like \ref will no longer function as links. Instead, you must use Sphinx domain links. For example:

    • Instead of: \ref namespace::ClassName
    • Use: :class:namespace::ClassName``
  10. Handle C++ template specialization and metaprogramming

    master

    Exhale supports partial and full template specialization, but with some limitations:

    1. No Backlinks: Currently, there are no links from specialized types back to their original unspecialized types.
    2. Build Warnings: All template classes (specialized or not) produce build warnings from Breathe, which may result in slightly unusual layouts.
    3. Doxygen Preprocessor: For complex metaprogramming, you may need to ensure all necessary macros are defined in Doxygen's PREDEFINED settings.

    If Doxygen fails to process specific code, you can use preprocessor symbols that are only defined during the documentation build process.

  11. Use Exhale to execute Doxygen automatically

    master

    Exhale can be configured to execute Doxygen automatically during the documentation build process. This is the preferred method for hosting documentation on platforms like Read the Docs. To enable this, you must set up the associated configuration variables in your Sphinx configuration.

    Alternatively, you can execute Doxygen independently, but you must ensure that Doxygen is run before Exhale is triggered in your build pipeline.

  12. Create a custom Intersphinx mapping using sphobjinv

    master

    Because the official BeautifulSoup objects.inv mapping is broken, you can manually create and maintain a custom mapping using the sphobjinv tool. This involves converting the binary .inv file to a human-readable .txt format, adding your desired references using specific syntax, and converting it back to a binary file for Sphinx to use.

    Workflow

    1. Install the tool:

      pip install sphobjinv
    2. Prepare the base file: Download the original objects.inv from the target documentation and rename it to avoid conflicts.

      curl -O https://www.crummy.com/software/BeautifulSoup/bs4/doc/objects.inv
      mv objects.inv bs4_objects.inv
    3. Convert to plain text: Convert the binary file to a human-readable text file.

      sphobjinv convert plain bs4_objects.inv bs4_objects.txt
    4. Edit the text file: Add new references to bs4_objects.txt following the sphobjinv syntax. For example:

      bs4.BeautifulSoup           py:class  1 index.html#beautifulsoup - 
      bs4.BeautifulSoup.get_text  py:method 1 index.html#get-text      - 
      bs4.element.Tag             py:class  1 index.html#tag           -
    5. Convert back to binary:

      sphobjinv convert zlib bs4_objects.txt bs4_objects.inv
    6. Rebuild Sphinx: Clean the build to ensure the doctree index is rebuilt.

      make clean html
    # 1. Install
    pip install sphobjinv
    
    # 2. Download and rename
    curl -O https://www.crummy.com/software/BeautifulSoup/bs4/doc/objects.inv
    mv objects.inv bs4_objects.inv
    
    # 3. Convert to text
    sphobjinv convert plain bs4_objects.inv bs4_objects.txt
    
    # 4. (Edit bs4_objects.txt manually)
    
    # 5. Convert back to binary
    sphobjinv convert zlib bs4_objects.txt bs4_objects.inv
    
    # 6. Rebuild
    make clean html