Running on Read the Docs

Read the Docs is an excellent site for hosting project documentation. It provides hooks into common project hosting sites like Github & Bitbucket and can rebuild your documentation automatically whenever you push new code.

The site is designed for documentation written with Sphinx and supports Sphinx extensions via a correctly configured setup.py file.

As Breathe is a Sphinx extension you can use it on Read the Docs. However, as Breathe requires doxygen XML files, some additional configuration is required.

Doxygen Support

Read the Docs do not explicitly support doxygen however they have had requests for it to be supported and it is currently installed on their build servers.

Generating Doxygen XML Files

We assume that you are not checking your doxygen XML files into your source control system and so you will need to generate them on the Read the Docs server before Sphinx starts processing your documentation.

One simple way of achieving this is to add the following code to your conf.py file:

import subprocess, os

read_the_docs_build = os.environ.get('READTHEDOCS', None) == 'True'

if read_the_docs_build:

    subprocess.call('cd ../doxygen; doxygen', shell=True)

The first line uses the READTHEDOCS environment variable to determine whether or not we are building on the Read the Docs servers. Read the Docs set this environment variable specifically for this purpose.

Then, if we are in a Read the Docs build, execute a simple shell command to build the doxygen xml for your project. This is a very simple example; the command will be determined by your project set up but something like this works for the Breathe documentation.

As this is then executed right at the start of the sphinx-build process then all your doxygen XML files will be in place for the build.

A More Involved Setup

If you’d rather do something more involved then you can run doxygen as part of a builder-inited event hook which you can install from your conf.py file by adding a setup function as shown below.

This is an approximation of the code that Breathe has in its conf.py in order to run doxygen on the Read the Docs server.

import subprocess, sys

def run_doxygen(folder):
    """Run the doxygen make command in the designated folder"""

    try:
        retcode = subprocess.call("cd %s; make" % folder, shell=True)
        if retcode < 0:
            sys.stderr.write("doxygen terminated by signal %s" % (-retcode))
    except OSError as e:
        sys.stderr.write("doxygen execution failed: %s" % e)


def generate_doxygen_xml(app):
    """Run the doxygen make commands if we're on the ReadTheDocs server"""

    read_the_docs_build = os.environ.get('READTHEDOCS', None) == 'True'

    if read_the_docs_build:

        run_doxygen("../../examples/doxygen")
        run_doxygen("../../examples/specific")
        run_doxygen("../../examples/tinyxml")


def setup(app):

    # Add hook for building doxygen xml when needed
    app.connect("builder-inited", generate_doxygen_xml)