Documenting Software

Note

This how-to guide is yet not complete.

BASIS supports two well-known and established documentation generation tools: Doxygen and Sphinx.

Documentation Quick Start

When you use the basisproject tool to generate a project as described in Create/Modify a Project, you will have a tree with a /doc directory preconfigured to generate a starter documentation website and PDF just like the BASIS website.

Here is how to create a new project that supports documentation:

basisproject --name docProject --description "This is a BASIS project." --full

We will assume that you ran this command in your ~/ directory for simplicity in the steps below.

Writing Documentation

Now you can simply open the ~/docProject/doc/*.rst files and start editing the existing reStructuredText files to create your Sphinx documentation.

You can also update your doxygen mainpage by opening ~/docProject/doc/apidoc/apidoc.dox.

We also suggest taking a look at the /doc folder of the BASIS source code itself for more examples of how to write documentation.

Generating Documentation

Once you have the project ready the docs can be generated.

mkdir ~/docProject-build
cd ~/docProject-build
cmake ../docProject -DBUILD_DOCUMENTATION=ON -DCMAKE_INSTALL_PREFIX=~/docProject-install
make doc
make install

The web documentation will be in ~/docProject-install/doc/html/index.html, and the PDF docs will be in ~/docProject-install/doc/docProject_Software_Manual.pdf.

Serving Website Locally

Note that simply opening the documentation will not render all pages correctly due to the use of the iframe HTML tag to embed the Doxygen generated API docs and the security settings built into modern browsers. Instead, display your docs via a server, for example, using Python by running the following command in the root directory of the (installed) documentation.

Python 2:

python -m SimpleHTTPServer

Python 3:

python -m http.server

Then go to localhost:8000 to view the pages.

Doxygen Documentation

Language Support

Since version 1.8.0, Doxygen can natively generate documentation from

  • C/C++
  • Java
  • Python
  • Tcl
  • Fortran.

The markup language used to format documentation comments was originally a set of commands inherited from Javadoc. Recently Doxygen also adopted Markdown and elements from Markdown Extra.

Doxygen Filters

To extend the reportoire of programming languages processed by Doxygen, so-called custom Doxygen filters can be provided which transform any source code into the syntax of one of the languages well understood by Doxygen. The target language used is commonly C/C++ as this is the language best understood by Doxygen.

BASIS includes Doxygen filters for:

  • CMake
  • Bash
  • Perl
  • MATLAB
  • Python

Generating Doxygen

The basis_add_doxygen_doc() CMake command can be used to create your own custom doxygen documentation.

Sphinx Documentation

BASIS makes use of Sphinx for the alternative documentation generation from Python source code and corresponding doc strings. The markup language used by Sphinx is reStructuredText (reST).

Sphinx Documentation has the advantages of being able to be produced in many different formats, and it can be used inline in Python code, and producing documentation in a much more usable layout. However, it cannot generate documentaiton from inline code for C++ in the way that doxygen can.

Output Formats

Sphinx and restructured text allow documentation to be generated in a wide number of useful formats, including:

  • HTML
  • LaTeX
  • man pages
  • Docutils

These can be used to produce:

  • software manual
  • developer’s guide
  • tutorial slides,
  • project web site

This is accomplished by providing text files marked up using reST which are then processed by Sphinx to generate documentation in the desired output format.

BASIS includes two Sphinx extensions breathe and doxylink which are included with BASIS can be used to include, respectively, link to the the documentation generated by Doxygen from the documentation generated by Sphinx. The latter only for the HTML output, which, however, is the most commonly used and preferred output format. Given that the project web site and manuals are generated by Sphinx and only the more advanced reference documentation is generated by Doxygen, this one directional linking of documentation pages is sufficient for most use cases. Currently BASIS uses doxylink because it is able to work with more complete and better organized output than breathe can handle as of the time of writing.

Themes

A number of Sphinx themes are provided with BASIS, and the recommended default theme is readable-wide that is used by the BASIS website.

  • readable-wide
  • readable
  • agogo
  • default
  • haiku
  • pyramid
  • sphinxdoc
  • basic
  • epub
  • nature
  • readable
  • scrolls
  • traditional

You can also use your own theme from the web or include it yourself by simply providing a path to the theme using the HTML_THEME parameter of basis_add_doc() and basis_add_sphinx_doc().

Markdown

Markdown, GitHub flavored Markdown and Markdown Extra can be used for the root package documentation files such as the AUTHORS.md, README.md, INSTALL.md, and COPYING.md files. Many online hosting platforms for the distribution of open source software such as SourceForge and GitHub render markdown on the project page with the marked up formatting.

Note

Not all of these documentation tools are supported for all languages.

Creating Documentation

The best example for creating documenation is the BASIS documentation itself, which can be found in the doc/apidoc folder. The most important function for generating documentation is basis_add_doc(), which can handle the parameters of the related basis_add_sphinx_doc() and basis_add_doxygen_doc() commands.

Here is the code that generates the integrated Sphinx and Doxygen Documentation:

# ============================================================================
# Copyright (c) 2011-2012 University of Pennsylvania
# Copyright (c) 2013-2014 Carnegie Mellon University
# Copyright (c) 2013-2016 Andreas Schuh
# All rights reserved.
#
# See COPYING file for license information or visit
# https://cmake-basis.github.io/download.html#license
# ============================================================================

##############################################################################
# @file  CMakeLists.txt
# @brief Build configuration of software documentation.
#
# This build configuration builds and/or installs the documentation of the
# software package. The documentation can be divided into user documentation
# (e.g., software manual) and developer documentation (e.g., developer's guide).
# For developers, both those using a library provided by this package and the
# package maintainers, the documentation of the API is of particular interest.
# Developers who are responsible for maintaining this software may be provided
# with even more detailed documentation of the implementation in the so-called
# developer's guide.
#
# See the basis_add_doc() command for details on the documentation build tools
# supported by BASIS for the generation of documentation from plain text files
# and in-source code comments.
##############################################################################

# ============================================================================
# generic targets
# ============================================================================

# create custom targets so "make site" and "make manual" always work
# note that the "doc" target is added automatically which will trigger
# the build of the complete documentation unless the EXCLUDE_FROM_ALL
# option is passed to basis_add_doc
basis_add_custom_target (site)   # build HTML pages
basis_add_custom_target (manual) # build PDF manual

# ============================================================================
# API reference (in-source code comments)
# ============================================================================

basis_find_package(Doxygen REQUIRED)

# replace < year|contact|copyright|license > pattern in template file which
# shall be included in documentation to avoid unrecognized xml/html tag warning
function (basis_sanitize_template_for_doxygen OUTPUT_FILE_VAR TEMPLATE_FILE)
  get_filename_component (TEMPLATE_NAME "${TEMPLATE_FILE}" NAME)
  file (READ "${TEMPLATE_FILE}" TEMPLATE)
  string (REGEX REPLACE "<year>"      "&lt;year&gt;"      TEMPLATE "${TEMPLATE}")
  string (REGEX REPLACE "<contact>"   "&lt;contact&gt;"   TEMPLATE "${TEMPLATE}")
  string (REGEX REPLACE "<copyright>" "&lt;copyright&gt;" TEMPLATE "${TEMPLATE}")
  string (REGEX REPLACE "<license>"   "&lt;license&gt;"   TEMPLATE "${TEMPLATE}")
  set (OUTPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/${TEMPLATE_NAME}")
  file (WRITE "${OUTPUT_FILE}" "${TEMPLATE}")
  set (${OUTPUT_FILE_VAR} "${OUTPUT_FILE}" PARENT_SCOPE)
endfunction ()

set (BASIS_TEMPLATE_DIR "${PROJECT_TOOLS_DIR}/basisproject/templates/basis")
basis_sanitize_template_for_doxygen (DEPENDS_MODULE   "${BASIS_TEMPLATE_DIR}/1.0/config/Depends.cmake")
basis_sanitize_template_for_doxygen (BOOTSTRAP_MODULE "${BASIS_TEMPLATE_DIR}/1.1/BasisBootstrapping.cmake")

basis_add_doc (
  apidoc 
  GENERATOR             Doxygen
  INPUT                 "${DEPENDS_MODULE}" "${BOOTSTRAP_MODULE}"
  EXCLUDE_PATTERNS      # External libraries packaged with BASIS to exclude from final documentation
                        "*/gmock/*"            # Google Mock
                        "*/gtest/*"            # Google Test
                        "*/tclap/*"            # TCLAP library
                        "*/breathe/*"          # Sphinx extension
                        "*/doxylink/*"         # Sphinx extension
                        "*/argh/*"             # Python Argh
                        "*/test.cxx"           # Google Mock and Test
                        "*/test_main.cxx"      # main() of unit tests based on GMock
                        "*/testdriver.cxx"     # testdriver which includes *.inc files
  HTML_DESTINATION      "${INSTALL_DOC_DIR}/html/apidoc/latest"
  HTML_HEADER	          "apidoc/doxygen_header.html.in"
  HTML_FOOTER           "apidoc/doxygen_footer.html.in"
  HTML_EXTRA_STYLESHEET "apidoc/doxygen_extra.css.in"
  OUTPUT                html xml
)

# ============================================================================
# software manual
# ============================================================================

# add build target for the generation of the web pages and PDF manual
# from the same set of reStructuredText input source files
basis_set_if_not_set (BUILD_SOFTWAREMANUAL ON)
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/manual.rst" AND
    EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/sidebar.rst" AND
    BUILD_SOFTWAREMANUAL)

  basis_find_package (Sphinx REQUIRED COMPONENTS build)
  basis_find_package (LATEX  REQUIRED COMPONENTS PDFLATEX)
 
  # software manual output formats
  set (SOFTWAREMANUAl_BUILDER html pdf)
  if (UNIX)
    list (APPEND SOFTWAREMANUAL_BUILDER man)
  endif ()

  # add target to build software manual
  basis_add_doc (
    softwaremanual                                        # documenation build target name
    GENERATOR        Sphinx                               # select Sphinx as the generator
    BUILDER          ${SOFTWAREMANUAl_BUILDER}            # selected Sphinx output formats
    MAN_SECTION      7                                    # http://en.wikipedia.org/wiki/Man_page#Manual_sections
    HTML_THEME       cmake-basis                          # select the Sphinx layout theme
    HTML_LOGO        logo_title.svg                       # logo to use at heading of documentation
    HTML_FAVICON     favicon.ico                          # icon for bookmark and tab title
    HTML_SIDEBARS    searchbox globaltoc links            # sidebar options to use
    HTML_DESTINATION "${INSTALL_DOC_DIR}/html"            # output directory for completed documentation
    SIDEBARWIDTH     300                                  # sidebar width in pixels
    MASTER_DOC       "sidebar"                            # .rst file to start with when generating HTML
    LATEX_MASTER_DOC "manual"                             # .rst file to start with when generating LaTeX/PDF
    LATEX_TITLE      "${PROJECT_NAME} Software Manual"    # title within LaTeX/PDF documents
    OUTPUT_NAME      "${PROJECT_NAME}_Software_Manual"    # general output file name, e.g., LaTeX/PDF files
    DOXYLINK         apidoc                               # Doxygen generator build target for integrated API reference
    DOXYLINK_URL     "${PROJECT_WEBSITE}/apidoc/latest"   # location of Doxygen output files
    NO_HTML_MODINDEX NO_HTML_INDEX                        # disable currently unused index page
    EXCLUDE_PATTERN  intro.rst                            # .rst files which are included by other .rst
    EXCLUDE_PATTERN  faq.rst                              # each pattern must be preceeded by EXCLUDE_PATTERN
    EXCLUDE_PATTERN  features.rst
  )

  # PDF manual required for build of HTML download page
  #
  # Note that the Sphinx :download: link directive requires the download file
  # to be present in the source tree; thus copy generated PDF to source tree
  add_custom_command (TARGET softwaremanual_pdf POST_BUILD
    COMMAND "${CMAKE_COMMAND}" -E copy_if_different
      "${CMAKE_CURRENT_BINARY_DIR}/latex/${PROJECT_NAME}_Software_Manual.pdf" 
      "${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}_Software_Manual.pdf"
  )
  basis_add_dependencies (softwaremanual_html softwaremanual_pdf)

  # add dependency to more readable target names
  basis_add_dependencies (manual softwaremanual_pdf)
  basis_add_dependencies (site   softwaremanual_html)

endif ()

Software Manual

Introduces users to software tools and guides them through example application.

Developer’s Guide

Describes implementation details.

API Documentation

Documentation generated from source code and in-source comments, integrated with default template.

Software Web Site

A web site can be created using the documentation generation tool Sphinx. The main input to this tool are text files written in the lightweight markup language reStructuredText. A default theme for use at SBIA has been created which is part of BASIS. This theme together with the text files that define the content and structure of the site, the HTML pages of the software web site can be generated by sphinx-build. The CMake function basis_add_doc() provides an easy way to add such web site target to the build configuration. For example, the template doc/CMakeLists.txt file contains the following section:

# ----------------------------------------------------------------------------
# web site (optional)
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/site/index.rst")
  basis_add_doc (
    site
    GENERATOR     Sphinx
    BUILDER       html dirhtml pdf man
    MAN_SECTION   7
    HTML_THEME    readable-wide
    HTML_SIDEBARS globaltoc
    RELLINKS      installation documentation publications people
    COPYRIGHT     "<year> University of Pennsylvania"
    AUTHOR        "<author>"
  )
endif ()

where <year> and <author> should be replaced by the proper values. This is usually done by the basisproject command-line tool upon creation of a new project.

This CMake code adds a build target named site which invokes sphinx-build with the proper default configuration to generate a web site from the reST source files with file name extension .rst found in the site/ subdirectory. The source file of the main page, the so-called master document, of the web site must be named index.rst. The main pages which are linked in the top navigation bar are named using the RELLINKS option of basis_add_sphinx_doc(), the CMake function which implements the addition of a Sphinx documentation target. The corresponding source files must be named after these links. For example, given above CMake code, the reStructuredText source of the page with the download instructions has to be saved in the file site/download.rst.

See the corresponding section of the Installation guide for details on how to generate the HTML pages from the reST source files given the specification of a Sphinx documentation build target such as the site target defined by above template CMake code.