Add support for documenting C++ with Sphinx

Signed-off-by: Robert Winkler <rwinkler@antmicro.com>
This commit is contained in:
Robert Winkler 2019-10-01 12:35:54 +02:00 committed by Tomasz Michalak
parent bf7fbea99c
commit 4bd488cdcd
7 changed files with 516 additions and 1 deletions

11
doxygen/CMakeLists.txt Normal file
View File

@ -0,0 +1,11 @@
cmake_minimum_required(VERSION 3.13)
project(symbiflow-docs)
include(doxygen.cmake)
add_doxygen_project(
PRJNAME "prjxray"
INPUT_DIR "${SYMBIFLOW_DOCS_DIR}/source/prjxray/lib"
"${SYMBIFLOW_DOCS_DIR}/source/prjxray/tools"
LANGUAGE "c++"
FILE_EXTENSIONS ".cpp" ".cc" ".h" ".hh")

47
doxygen/README.md Normal file
View File

@ -0,0 +1,47 @@
# Adding C++ support for a new project
1. Add the project to the `symbiflow-docs/doxygen/CMakeLists.txt`, i.e:
```
add_doxygen_project(
PRJNAME "prjxray"
INPUT_DIR "${SYMBIFLOW_DOCS_DIR}/source/prjxray/lib"
"${SYMBIFLOW_DOCS_DIR}/source/prjxray/tools"
LANGUAGE "c++"
FILE_EXTENSIONS ".cpp" ".cc" ".h" ".hh")
```
- `PRJNAME` - the project's name
- `INPUT_DIR` - input directories which will be recursively scanned for
documented files
- `LANGUAGE` - the programming language of the project (currently only "c" and "c++" are supported")
This variable is used to determine proper doxygen configuration template (`<lang>.doxyfile.in` file)
- `FILE_EXTENSIONS` - extensions of the files that contain documentation
The generated doxygen documentation will be placed in
`symbiflow-docs/build/doxygen/<PRJNAME>/xml` directory
2. Add the project to the `breathe_projects` variable in `symbiflow-docs/source/conf.py`:
```
breathe_projects = {
...
"prjxray" : "../build/doxygen/prjxray/xml",
...
}
```
The first field in the dictionary refers to the project's name.
This value is placed after `:project:` property in the Breathe's directives.
The second field in dictionary refers to the Doxygen documentation output directory.
It should be a relative path to generated Doxygen documentation, mentioned above.
3. Now you can document the project using the breathe plugin.
Note that every class should be documented using its full namespace, i.e:
```
.. doxygenclass:: prjxray::xilinx::xc7series::ConfigurationBus
:project: prjxray
```

331
doxygen/c.doxyfile.in Normal file
View File

@ -0,0 +1,331 @@
# Doxyfile 1.8.13
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "@DOXYGEN_PROJECT_NAME@"
PROJECT_NUMBER =
PROJECT_BRIEF =
PROJECT_LOGO =
OUTPUT_DIRECTORY = "@DOXYGEN_OUTPUT_DIRECTORY@"
CREATE_SUBDIRS = NO
ALLOW_UNICODE_NAMES = NO
OUTPUT_LANGUAGE = English
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF = "The $name class" \
"The $name widget" \
"The $name file" \
is \
provides \
specifies \
contains \
represents \
a \
an \
the
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = NO
STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = NO
QT_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 4
ALIASES =
TCL_SUBST =
OPTIMIZE_OUTPUT_FOR_C = YES
OPTIMIZE_OUTPUT_JAVA = NO
OPTIMIZE_FOR_FORTRAN = NO
OPTIMIZE_OUTPUT_VHDL = NO
EXTENSION_MAPPING =
MARKDOWN_SUPPORT = YES
TOC_INCLUDE_HEADINGS = 0
AUTOLINK_SUPPORT = YES
BUILTIN_STL_SUPPORT = NO
CPP_CLI_SUPPORT = NO
SIP_SUPPORT = NO
IDL_PROPERTY_SUPPORT = YES
DISTRIBUTE_GROUP_DOC = NO
GROUP_NESTED_COMPOUNDS = NO
SUBGROUPING = YES
INLINE_GROUPED_CLASSES = NO
INLINE_SIMPLE_STRUCTS = NO
TYPEDEF_HIDES_STRUCT = NO
LOOKUP_CACHE_SIZE = 0
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = NO
EXTRACT_PRIVATE = NO
EXTRACT_PACKAGE = NO
EXTRACT_STATIC = NO
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = NO
EXTRACT_ANON_NSPACES = NO
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
HIDE_FRIEND_COMPOUNDS = NO
HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = YES
HIDE_SCOPE_NAMES = NO
HIDE_COMPOUND_REFERENCE= NO
SHOW_INCLUDE_FILES = YES
SHOW_GROUPED_MEMB_INC = NO
FORCE_LOCAL_INCLUDES = NO
INLINE_INFO = YES
SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = NO
SORT_MEMBERS_CTORS_1ST = NO
SORT_GROUP_NAMES = NO
SORT_BY_SCOPE_NAME = NO
STRICT_PROTO_MATCHING = NO
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_FILES = YES
SHOW_NAMESPACES = YES
FILE_VERSION_FILTER =
LAYOUT_FILE =
CITE_BIB_FILES =
#---------------------------------------------------------------------------
# Configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = NO
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_AS_ERROR = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# Configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = @DOXYGEN_INPUT@
INPUT_ENCODING = UTF-8
FILE_PATTERNS = @DOXYGEN_FILE_PATTERNS@
RECURSIVE = YES
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXCLUDE_SYMBOLS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS = *
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
INPUT_FILTER =
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
FILTER_SOURCE_PATTERNS =
USE_MDFILE_AS_MAINPAGE =
#---------------------------------------------------------------------------
# Configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = NO
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
REFERENCED_BY_RELATION = NO
REFERENCES_RELATION = NO
REFERENCES_LINK_SOURCE = YES
SOURCE_TOOLTIPS = YES
USE_HTAGS = NO
VERBATIM_HEADERS = YES
CLANG_ASSISTED_PARSING = NO
CLANG_OPTIONS =
#---------------------------------------------------------------------------
# Configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = YES
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = NO
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
HTML_HEADER =
HTML_FOOTER =
HTML_STYLESHEET =
HTML_EXTRA_STYLESHEET =
HTML_EXTRA_FILES =
HTML_COLORSTYLE_HUE = 220
HTML_COLORSTYLE_SAT = 100
HTML_COLORSTYLE_GAMMA = 80
HTML_TIMESTAMP = NO
HTML_DYNAMIC_SECTIONS = NO
HTML_INDEX_NUM_ENTRIES = 100
GENERATE_DOCSET = NO
DOCSET_FEEDNAME = "Doxygen generated docs"
DOCSET_BUNDLE_ID = org.doxygen.Project
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
DOCSET_PUBLISHER_NAME = Publisher
GENERATE_HTMLHELP = NO
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
CHM_INDEX_ENCODING =
BINARY_TOC = NO
TOC_EXPAND = NO
GENERATE_QHP = NO
QCH_FILE =
QHP_NAMESPACE = org.doxygen.Project
QHP_VIRTUAL_FOLDER = doc
QHP_CUST_FILTER_NAME =
QHP_CUST_FILTER_ATTRS =
QHP_SECT_FILTER_ATTRS =
QHG_LOCATION =
GENERATE_ECLIPSEHELP = NO
ECLIPSE_DOC_ID = org.doxygen.Project
DISABLE_INDEX = NO
GENERATE_TREEVIEW = NO
ENUM_VALUES_PER_LINE = 4
TREEVIEW_WIDTH = 250
EXT_LINKS_IN_WINDOW = NO
FORMULA_FONTSIZE = 10
FORMULA_TRANSPARENT = YES
USE_MATHJAX = NO
MATHJAX_FORMAT = HTML-CSS
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
MATHJAX_EXTENSIONS =
MATHJAX_CODEFILE =
SEARCHENGINE = YES
SERVER_BASED_SEARCH = NO
EXTERNAL_SEARCH = NO
SEARCHENGINE_URL =
SEARCHDATA_FILE = searchdata.xml
EXTERNAL_SEARCH_ID =
EXTRA_SEARCH_MAPPINGS =
#---------------------------------------------------------------------------
# Configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = NO
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4
EXTRA_PACKAGES =
LATEX_HEADER =
LATEX_FOOTER =
LATEX_EXTRA_STYLESHEET =
LATEX_EXTRA_FILES =
PDF_HYPERLINKS = YES
USE_PDFLATEX = YES
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
LATEX_SOURCE_CODE = NO
LATEX_BIB_STYLE = plain
LATEX_TIMESTAMP = NO
#---------------------------------------------------------------------------
# Configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
RTF_SOURCE_CODE = NO
#---------------------------------------------------------------------------
# Configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
MAN_SUBDIR =
MAN_LINKS = NO
#---------------------------------------------------------------------------
# Configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = YES
XML_OUTPUT = xml
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# Configuration options related to the DOCBOOK output
#---------------------------------------------------------------------------
GENERATE_DOCBOOK = NO
DOCBOOK_OUTPUT = docbook
DOCBOOK_PROGRAMLISTING = NO
#---------------------------------------------------------------------------
# Configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# Configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED =
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration options related to external references
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE =
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
EXTERNAL_PAGES = YES
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
MSCGEN_PATH =
DIA_PATH =
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = YES
DOT_NUM_THREADS = 0
DOT_FONTNAME = Helvetica
DOT_FONTSIZE = 10
DOT_FONTPATH =
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES
UML_LOOK = NO
UML_LIMIT_NUM_FIELDS = 10
TEMPLATE_RELATIONS = NO
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
CALL_GRAPH = NO
CALLER_GRAPH = NO
GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = png
INTERACTIVE_SVG = NO
DOT_PATH =
DOTFILE_DIRS =
MSCFILE_DIRS =
DIAFILE_DIRS =
PLANTUML_JAR_PATH =
PLANTUML_CFG_FILE =
PLANTUML_INCLUDE_PATH =
DOT_GRAPH_MAX_NODES = 50
MAX_DOT_GRAPH_DEPTH = 0
DOT_TRANSPARENT = NO
DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES
DOT_CLEANUP = YES

93
doxygen/doxygen.cmake Normal file
View File

@ -0,0 +1,93 @@
find_package(Doxygen REQUIRED)
### Global SymbiFlow variables
get_filename_component(SYMBIFLOW_DOCS_DIR "${PROJECT_SOURCE_DIR}/.." ABSOLUTE)
get_filename_component(SYMBIFLOW_DOCS_BUILD_DIR "${SYMBIFLOW_DOCS_DIR}/build" ABSOLUTE)
get_filename_component(SYMBIFLOW_DOCS_DOXYGEN_DIR "${SYMBIFLOW_DOCS_DIR}/doxygen" ABSOLUTE)
get_filename_component(SYMBIFLOW_DOCS_DOXYGEN_BUILD_DIR "${SYMBIFLOW_DOCS_BUILD_DIR}/doxygen" ABSOLUTE)
function(ADD_DOXYGEN_PROJECT)
set(options)
set(oneValueArgs PRJNAME LANGUAGE)
set(multiValueArgs INPUT_DIR FILE_EXTENSIONS)
cmake_parse_arguments(
ADD_DOXYGEN_PROJECT
"${options}"
"${oneValueArgs}"
"${multiValueArgs}"
${ARGN})
### Input validation
if (("${ADD_DOXYGEN_PROJECT_PRJNAME}" STREQUAL "") OR
("${ADD_DOXYGEN_PROJECT_INPUT_DIR}" STREQUAL "") OR
("${ADD_DOXYGEN_PROJECT_LANGUAGE}" STREQUAL ""))
message(FATAL_ERROR
"Missing function argument!\n"
"ADD_DOXYGEN_PROJECT(\n"
" PRJNAME <name>\n"
" INPUT_DIR <input_dir_1> {<input_dir_n>}\n"
" LANGUAGE <language>)")
endif()
if ((NOT "${ADD_DOXYGEN_PROJECT_LANGUAGE}" STREQUAL "c++") AND
(NOT "${ADD_DOXYGEN_PROJECT_LANGUAGE}" STREQUAL "c"))
message(FATAL_ERROR
"Language: ${ADD_DOXYGEN_PROJECT_LANGUAGE} is not supported!")
endif()
### Project settings
set(PROJECT_OUTPUT_FILE "${SYMBIFLOW_DOCS_DOXYGEN_BUILD_DIR}/${ADD_DOXYGEN_PROJECT_PRJNAME}/xml/index.xml")
set(PROJECT_DOXYFILE "${SYMBIFLOW_DOCS_DOXYGEN_DIR}/build/${ADD_DOXYGEN_PROJECT_PRJNAME}.doxyfile")
if (("${ADD_DOXYGEN_PROJECT_LANGUAGE}" STREQUAL "c") OR
("${ADD_DOXYGEN_PROJECT_LANGUAGE}" STREQUAL "c++"))
set(PROJECT_DOXYFILE_IN "${SYMBIFLOW_DOCS_DOXYGEN_DIR}/c.doxyfile.in")
endif()
### Searching for all files in the project
foreach(ext ${ADD_DOXYGEN_PROJECT_FILE_EXTENSIONS})
foreach(input ${ADD_DOXYGEN_PROJECT_INPUT_DIR})
list(APPEND GLOBBING_DIRS "${input}/*${ext}")
endforeach()
endforeach()
file(GLOB_RECURSE PROJECT_FILES CONFIGURE_DEPENDS ${GLOBBING_DIRS})
### Doxygen settings
set(DOXYGEN_PROJECT_NAME "${ADD_DOXYGEN_PROJECT_PRJNAME}")
set(DOXYGEN_OUTPUT_DIRECTORY "${SYMBIFLOW_DOCS_DOXYGEN_BUILD_DIR}/${ADD_DOXYGEN_PROJECT_PRJNAME}")
string(REPLACE ";" " \\\n" DOXYGEN_INPUT "${ADD_DOXYGEN_PROJECT_INPUT_DIR}")
foreach(ext ${ADD_DOXYGEN_PROJECT_FILE_EXTENSIONS})
list(APPEND DOXYGEN_FILE_PATTERNS "*${ext}")
endforeach()
string(REPLACE ";" " " DOXYGEN_FILE_PATTERNS "${DOXYGEN_FILE_PATTERNS}")
# Fill in the Doxyfile with the project's values
configure_file("${PROJECT_DOXYFILE_IN}" "${PROJECT_DOXYFILE}" @ONLY)
### Prerequisites
# Ensure that docs will be correctly regenerated
file(REMOVE "${PROJECT_OUTPUT_FILE}")
# Ensure that needed directories are created
file(MAKE_DIRECTORY "${DOXYGEN_OUTPUT_DIRECTORY}")
### Create Makefile targets
add_custom_command(OUTPUT "${PROJECT_OUTPUT_FILE}"
DEPENDS "${PROJECT_FILES}"
COMMAND "${DOXYGEN_EXECUTABLE}" "${PROJECT_DOXYFILE}"
WORKING_DIRECTORY "${SYMBIFLOW_DOCS_DOXYGEN_DIR}"
MAIN_DEPENDENCY "${PROJECT_DOXYFILE}"
COMMENT "Generating doxygen docs for ${ADD_DOXYGEN_PROJECT_PRJNAME}...")
add_custom_target("docs-${ADD_DOXYGEN_PROJECT_PRJNAME}"
ALL
DEPENDS "${PROJECT_OUTPUT_FILE}" "${PROJECT_FILES}")
endfunction()

View File

@ -4,6 +4,8 @@ channels:
- conda-forge - conda-forge
- defaults - defaults
dependencies: dependencies:
- doxygen
- cmake
- pip - pip
- pip: - pip:
- -r file:requirements.txt - -r file:requirements.txt

View File

@ -1,3 +1,4 @@
Sphinx==2.0.0 Sphinx==2.0.0
git+http://github.com/SymbiFlow/sphinx_materialdesign_theme.git@master#egg=sphinx_symbiflow_theme git+http://github.com/SymbiFlow/sphinx_materialdesign_theme.git@master#egg=sphinx_symbiflow_theme
sphinx-markdown-tables sphinx-markdown-tables
breathe==4.13.1

View File

@ -22,7 +22,11 @@ needs_sphinx = '1.6'
# Add any Sphinx extension module names here, as strings. They can be extensions # Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.todo'] extensions = [
'sphinx.ext.todo',
'sphinx.ext.imgmath', # breathe
'breathe'
]
numfig = True numfig = True
@ -289,3 +293,29 @@ rst_prolog = """
.. role:: raw-html(raw) .. role:: raw-html(raw)
:format: html :format: html
""" """
### BREATHE ###
from pathlib import Path
import subprocess
# For building doxygen only on Read the Docs see:
# https://breathe.readthedocs.io/en/latest/readthedocs.html
def doxygen_generate(log_file=None):
doxygen_cmake_build_dir = Path('../doxygen/build')
if not doxygen_cmake_build_dir.exists():
doxygen_cmake_build_dir.mkdir(parents=True, exist_ok=True)
cmd = "cd " + str(doxygen_cmake_build_dir) + "&& cmake .. && make"
else:
cmd = "cd " + str(doxygen_cmake_build_dir) + "&& make"
subprocess.call(cmd, shell=True, stderr=log_file, stdout=log_file)
doxygen_generate()
breathe_projects = {
"prjxray" : "../build/doxygen/prjxray/xml",
}