From patchwork Tue Apr 6 10:36:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luca Fancellu X-Patchwork-Id: 12184811 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.5 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, LOTS_OF_MONEY,MAILING_LIST_MULTI,NORMAL_HTTP_TO_IP,NUMERIC_HTTP_ADDR, SPF_HELO_NONE,SPF_PASS,T_MONEY_PERCENT,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2A7EBC433ED for ; Tue, 6 Apr 2021 10:37:25 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B6ABB6128A for ; Tue, 6 Apr 2021 10:37:24 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B6ABB6128A Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from list by lists.xenproject.org with outflank-mailman.105769.202296 (Exim 4.92) (envelope-from ) id 1lTj4z-0000zB-Ct; Tue, 06 Apr 2021 10:37:05 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 105769.202296; Tue, 06 Apr 2021 10:37:05 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1lTj4z-0000z4-94; Tue, 06 Apr 2021 10:37:05 +0000 Received: by outflank-mailman (input) for mailman id 105769; Tue, 06 Apr 2021 10:37:04 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1lTj4y-0000yp-Iz for xen-devel@lists.xenproject.org; Tue, 06 Apr 2021 10:37:04 +0000 Received: from foss.arm.com (unknown [217.140.110.172]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTP id e4c3ca21-fac3-43c6-aaee-2b4d764a7891; Tue, 06 Apr 2021 10:37:02 +0000 (UTC) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 4F0FCED1; Tue, 6 Apr 2021 03:37:02 -0700 (PDT) Received: from e125770.cambridge.arm.com (e125770.cambridge.arm.com [10.1.197.16]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 680363F73D; Tue, 6 Apr 2021 03:37:00 -0700 (PDT) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: e4c3ca21-fac3-43c6-aaee-2b4d764a7891 From: Luca Fancellu To: xen-devel@lists.xenproject.org Cc: bertrand.marquis@arm.com, wei.chen@arm.com, Andrew Cooper , George Dunlap , Ian Jackson , Jan Beulich , Julien Grall , Stefano Stabellini , Wei Liu Subject: [PATCH 1/3] docs: add doxygen support for html documentation Date: Tue, 6 Apr 2021 11:36:01 +0100 Message-Id: <20210406103603.8530-2-luca.fancellu@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210406103603.8530-1-luca.fancellu@arm.com> References: <20210406103603.8530-1-luca.fancellu@arm.com> Add doxygen support to build html documentation with sphinx, to do that the following modification are applied: 1) Modify docs/configure.ac and consequently configure script to check, through the ./configure script, the presence in the system of the sphinx-build binary, if it is found then it checks also the presence of the doxygen binary, breathe and sphinx-rtd-theme python packages. Doxygen and the packages are required only if sphinx-build is found, otherwise the Makefile will simply skip the sphinx html generation. The ax_python_module.m4 support is needed to check for python packages. 2) Add doxygen templates and configuration file 3) Modify docs/Makefile to call in sequence doxygen and sphinx-build, the doxygen configuration file will be modified to include the xen absolute path and a list of folder to check. A doxygen_input.h file is generated to include every header listed in the doxy_input.list file. Signed-off-by: Luca Fancellu --- .gitignore | 6 + config/Docs.mk.in | 2 + docs/Makefile | 47 +- docs/conf.py | 48 +- docs/configure | 258 ++ docs/configure.ac | 15 + docs/xen-doxygen/customdoxygen.css | 36 + docs/xen-doxygen/doxy_input.list | 0 docs/xen-doxygen/doxy_input_template.in | 21 + docs/xen-doxygen/footer.html | 21 + docs/xen-doxygen/header.html | 56 + docs/xen-doxygen/mainpage.md | 5 + docs/xen-doxygen/xen_project_logo_165x67.png | Bin 0 -> 18223 bytes docs/xen.doxyfile.in | 2314 ++++++++++++++++++ m4/ax_python_module.m4 | 56 + m4/docs_tool.m4 | 9 + 16 files changed, 2888 insertions(+), 6 deletions(-) create mode 100644 docs/xen-doxygen/customdoxygen.css create mode 100644 docs/xen-doxygen/doxy_input.list create mode 100644 docs/xen-doxygen/doxy_input_template.in create mode 100644 docs/xen-doxygen/footer.html create mode 100644 docs/xen-doxygen/header.html create mode 100644 docs/xen-doxygen/mainpage.md create mode 100644 docs/xen-doxygen/xen_project_logo_165x67.png create mode 100644 docs/xen.doxyfile.in create mode 100644 m4/ax_python_module.m4 diff --git a/.gitignore b/.gitignore index 1c2fa1530b..a5eebf1213 100644 --- a/.gitignore +++ b/.gitignore @@ -58,6 +58,12 @@ docs/man7/ docs/man8/ docs/pdf/ docs/txt/ +docs/doxygen-output +docs/sphinx +docs/xen.doxyfile +docs/xen.doxyfile.tmp +docs/doxygen_input.h +docs/doxygen_input.h.tmp extras/mini-os* install/* stubdom/*-minios-config.mk diff --git a/config/Docs.mk.in b/config/Docs.mk.in index e76e5cd5ff..dfd4a02838 100644 --- a/config/Docs.mk.in +++ b/config/Docs.mk.in @@ -7,3 +7,5 @@ POD2HTML := @POD2HTML@ POD2TEXT := @POD2TEXT@ PANDOC := @PANDOC@ PERL := @PERL@ +SPHINXBUILD := @SPHINXBUILD@ +DOXYGEN := @DOXYGEN@ diff --git a/docs/Makefile b/docs/Makefile index 8de1efb6f5..dd651e9a93 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -17,6 +17,22 @@ TXTSRC-y := $(sort $(shell find misc -name '*.txt' -print)) PANDOCSRC-y := $(sort $(shell find designs/ features/ misc/ process/ specs/ \( -name '*.pandoc' -o -name '*.md' \) -print)) +# Directory in which the doxygen documentation is created +# This must be kept in sync with breathe_projects value in conf.py +DOXYGEN_OUTPUT = doxygen-output + +# Doxygen input headers from xen-doxygen/doxy_input.list file +DOXY_LIST_SOURCES != cat "xen-doxygen/doxy_input.list" +DOXY_LIST_SOURCES := $(realpath $(addprefix $(XEN_ROOT)/,$(DOXY_LIST_SOURCES))) + +# Get folder path for all input headers and delete duplicates +DOXY_LIST_DIRS := $(foreach inc,$(DOXY_LIST_SOURCES),$(dir $(realpath $(inc)))) +DOXY_LIST_DIRS := $(sort $(DOXY_LIST_DIRS)) + +DOXY_DEPS := xen.doxyfile \ + xen-doxygen/mainpage.md \ + doxygen_input.h + # Documentation targets $(foreach i,$(MAN_SECTIONS), \ $(eval DOC_MAN$(i) := $(patsubst man/%.$(i),man$(i)/%.$(i), \ @@ -46,8 +62,29 @@ all: build build: html txt pdf man-pages figs .PHONY: sphinx-html -sphinx-html: - sphinx-build -b html . sphinx/html +sphinx-html: $(DOXY_DEPS) $(DOXY_LIST_SOURCES) +ifneq ($(SPHINXBUILD),) + $(DOXYGEN) xen.doxyfile + XEN_ROOT=$(realpath $(XEN_ROOT)) $(SPHINXBUILD) -b html . sphinx/html +else + @echo "Sphinx is not installed; skipping sphinx-html documentation." +endif + +xen.doxyfile: xen.doxyfile.in xen-doxygen/doxy_input.list + @echo "Generating $@" + @sed -e "s,@XEN_BASE@,$(realpath $(XEN_ROOT)),g" $< \ + | sed -e "s,@DOXY_OUT@,$(DOXYGEN_OUTPUT),g" > $@.tmp + @$(foreach dir,\ + $(DOXY_LIST_DIRS),\ + echo "INCLUDE_PATH += \"$(dir)\"" >> $@.tmp; \ + ) + mv $@.tmp $@ + +doxygen_input.h: xen-doxygen/doxy_input_template.in xen-doxygen/doxy_input.list + @echo "Generating $@" + @sed -e "s,@XEN_BASE@,$(realpath $(XEN_ROOT)),g" $< > $@.tmp + @$(foreach inc,$(DOXY_LIST_SOURCES),cat "$(inc)" >> $@.tmp;) + @mv $@.tmp $@ .PHONY: html html: $(DOC_HTML) html/index.html @@ -71,7 +108,11 @@ clean: clean-man-pages $(MAKE) -C figs clean rm -rf .word_count *.aux *.dvi *.bbl *.blg *.glo *.idx *~ rm -rf *.ilg *.log *.ind *.toc *.bak *.tmp core - rm -rf html txt pdf sphinx/html + rm -rf html txt pdf sphinx $(DOXYGEN_OUTPUT) + rm -f xen.doxyfile + rm -f xen.doxyfile.tmp + rm -f doxygen_input.h + rm -f doxygen_input.h.tmp .PHONY: distclean distclean: clean diff --git a/docs/conf.py b/docs/conf.py index 50e41501db..a48de42331 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -13,13 +13,17 @@ # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # -# import os -# import sys +import os +import sys # sys.path.insert(0, os.path.abspath('.')) # -- Project information ----------------------------------------------------- +if "XEN_ROOT" not in os.environ: + sys.exit("$XEN_ROOT environment variable undefined.") +XEN_ROOT = os.path.abspath(os.environ["XEN_ROOT"]) + project = u'Xen' copyright = u'2019, The Xen development community' author = u'The Xen development community' @@ -35,6 +39,7 @@ try: xen_subver = line.split(u"=")[1].strip() elif line.startswith(u"export XEN_EXTRAVERSION"): xen_extra = line.split(u"=")[1].split(u"$", 1)[0].strip() + except: pass finally: @@ -44,6 +49,15 @@ finally: else: version = release = u"unknown version" +try: + xen_doxygen_output = None + + for line in open(u"Makefile"): + if line.startswith(u"DOXYGEN_OUTPUT"): + xen_doxygen_output = line.split(u"=")[1].strip() +except: + sys.exit("DOXYGEN_OUTPUT variable undefined.") + # -- General configuration --------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. @@ -53,7 +67,8 @@ needs_sphinx = '1.4' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = [] +# breathe -> extension that integrates doxygen xml output with sphinx +extensions = ['breathe'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -175,6 +190,33 @@ texinfo_documents = [ 'Miscellaneous'), ] +# -- Options for Breathe extension ------------------------------------------- + +breathe_projects = { + "Xen": "{}/docs/{}/xml".format(XEN_ROOT, xen_doxygen_output) +} +breathe_default_project = "Xen" + +breathe_domain_by_extension = { + "h": "c", + "c": "c", +} +breathe_separate_member_pages = True +breathe_show_enumvalue_initializer = True +breathe_show_define_initializer = True + +# Qualifiers to a function are causing Sphihx/Breathe to warn about +# Error when parsing function declaration and more. This is a list +# of strings that the parser additionally should accept as +# attributes. +cpp_id_attributes = [ + '__syscall', '__deprecated', '__may_alias', + '__used', '__unused', '__weak', + '__DEPRECATED_MACRO', 'FUNC_NORETURN', + '__subsystem', +] +c_id_attributes = cpp_id_attributes + # -- Options for Epub output ------------------------------------------------- diff --git a/docs/configure b/docs/configure index 569bd4c2ff..0ebf046a79 100755 --- a/docs/configure +++ b/docs/configure @@ -588,6 +588,8 @@ ac_unique_file="misc/xen-command-line.pandoc" ac_subst_vars='LTLIBOBJS LIBOBJS PERL +DOXYGEN +SPHINXBUILD PANDOC POD2TEXT POD2HTML @@ -673,6 +675,7 @@ POD2MAN POD2HTML POD2TEXT PANDOC +DOXYGEN PERL' @@ -1318,6 +1321,7 @@ Some influential environment variables: POD2HTML Path to pod2html tool POD2TEXT Path to pod2text tool PANDOC Path to pandoc tool + DOXYGEN Path to doxygen tool PERL Path to Perl parser Use these variables to override the choices made by `configure' or to help @@ -1800,6 +1804,7 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + case "$host_os" in *freebsd*) XENSTORED_KVA=/dev/xen/xenstored ;; *) XENSTORED_KVA=/proc/xen/xsd_kva ;; @@ -1812,6 +1817,53 @@ case "$host_os" in esac +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_python_module.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_PYTHON_MODULE(modname[, fatal, python]) +# +# DESCRIPTION +# +# Checks for Python module. +# +# If fatal is non-empty then absence of a module will trigger an error. +# The third parameter can either be "python" for Python 2 or "python3" for +# Python 3; defaults to Python 3. +# +# LICENSE +# +# Copyright (c) 2008 Andrew Collier +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 9 + +# This is what autoupdate's m4 run will expand. It fires +# the warning (with _au_warn_XXX), outputs it into the +# updated configure.ac (with AC_DIAGNOSE), and then outputs +# the replacement expansion. + + +# This is an auxiliary macro that is also run when +# autoupdate runs m4. It simply calls m4_warning, but +# we need a wrapper so that each warning is emitted only +# once. We break the quoting in m4_warning's argument in +# order to expand this macro's arguments, not AU_DEFUN's. + + +# Finally, this is the expansion that is picked up by +# autoconf. It tells the user to run autoupdate, and +# then outputs the replacement expansion. We do not care +# about autoupdate's warning because that contains +# information on what to do *after* running autoupdate. + + test "x$prefix" = "xNONE" && prefix=$ac_default_prefix @@ -2232,6 +2284,212 @@ $as_echo "$as_me: WARNING: pandoc is not available so some documentation won't b fi +# If sphinx is installed, make sure to have also the dependencies to build +# Sphinx documentation. +for ac_prog in sphinx-build +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_SPHINXBUILD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$SPHINXBUILD"; then + ac_cv_prog_SPHINXBUILD="$SPHINXBUILD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_SPHINXBUILD="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +SPHINXBUILD=$ac_cv_prog_SPHINXBUILD +if test -n "$SPHINXBUILD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SPHINXBUILD" >&5 +$as_echo "$SPHINXBUILD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$SPHINXBUILD" && break +done +test -n "$SPHINXBUILD" || SPHINXBUILD="no" + + if test "x$SPHINXBUILD" = xno; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: sphinx-build is not available so sphinx documentation \ +won't be built" >&5 +$as_echo "$as_me: WARNING: sphinx-build is not available so sphinx documentation \ +won't be built" >&2;} +else + + # Extract the first word of "sphinx-build", so it can be a program name with args. +set dummy sphinx-build; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_SPHINXBUILD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $SPHINXBUILD in + [\\/]* | ?:[\\/]*) + ac_cv_path_SPHINXBUILD="$SPHINXBUILD" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_SPHINXBUILD="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +SPHINXBUILD=$ac_cv_path_SPHINXBUILD +if test -n "$SPHINXBUILD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SPHINXBUILD" >&5 +$as_echo "$SPHINXBUILD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + # Extract the first word of "doxygen", so it can be a program name with args. +set dummy doxygen; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_DOXYGEN+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $DOXYGEN in + [\\/]* | ?:[\\/]*) + ac_cv_path_DOXYGEN="$DOXYGEN" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_DOXYGEN="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +DOXYGEN=$ac_cv_path_DOXYGEN +if test -n "$DOXYGEN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DOXYGEN" >&5 +$as_echo "$DOXYGEN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if ! test -x "$ac_cv_path_DOXYGEN"; then : + + as_fn_error $? "doxygen is needed" "$LINENO" 5 + +fi + + + if test -z $PYTHON; + then + if test -z ""; + then + PYTHON="python3" + else + PYTHON="" + fi + fi + PYTHON_NAME=`basename $PYTHON` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking $PYTHON_NAME module: breathe" >&5 +$as_echo_n "checking $PYTHON_NAME module: breathe... " >&6; } + $PYTHON -c "import breathe" 2>/dev/null + if test $? -eq 0; + then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + eval HAVE_PYMOD_BREATHE=yes + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + eval HAVE_PYMOD_BREATHE=no + # + if test -n "yes" + then + as_fn_error $? "failed to find required module breathe" "$LINENO" 5 + exit 1 + fi + fi + + + if test -z $PYTHON; + then + if test -z ""; + then + PYTHON="python3" + else + PYTHON="" + fi + fi + PYTHON_NAME=`basename $PYTHON` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking $PYTHON_NAME module: sphinx_rtd_theme" >&5 +$as_echo_n "checking $PYTHON_NAME module: sphinx_rtd_theme... " >&6; } + $PYTHON -c "import sphinx_rtd_theme" 2>/dev/null + if test $? -eq 0; + then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + eval HAVE_PYMOD_SPHINX_RTD_THEME=yes + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + eval HAVE_PYMOD_SPHINX_RTD_THEME=no + # + if test -n "yes" + then + as_fn_error $? "failed to find required module sphinx_rtd_theme" "$LINENO" 5 + exit 1 + fi + fi + + + +fi + # Extract the first word of "perl", so it can be a program name with args. set dummy perl; ac_word=$2 diff --git a/docs/configure.ac b/docs/configure.ac index c2e5edd3b3..a2ff55f30a 100644 --- a/docs/configure.ac +++ b/docs/configure.ac @@ -20,6 +20,7 @@ m4_include([../m4/docs_tool.m4]) m4_include([../m4/path_or_fail.m4]) m4_include([../m4/features.m4]) m4_include([../m4/paths.m4]) +m4_include([../m4/ax_python_module.m4]) AX_XEN_EXPAND_CONFIG() @@ -29,6 +30,20 @@ AX_DOCS_TOOL_PROG([POD2HTML], [pod2html]) AX_DOCS_TOOL_PROG([POD2TEXT], [pod2text]) AX_DOCS_TOOL_PROG([PANDOC], [pandoc]) +# If sphinx is installed, make sure to have also the dependencies to build +# Sphinx documentation. +AC_CHECK_PROGS([SPHINXBUILD], [sphinx-build], [no]) + AS_IF([test "x$SPHINXBUILD" = xno], + [AC_MSG_WARN(sphinx-build is not available so sphinx documentation \ +won't be built)], + [ + AC_PATH_PROG([SPHINXBUILD], [sphinx-build]) + AX_DOCS_TOOL_REQ_PROG([DOXYGEN], [doxygen]) + AX_PYTHON_MODULE([breathe],[yes]) + AX_PYTHON_MODULE([sphinx_rtd_theme], [yes]) + ] + ) + AC_ARG_VAR([PERL], [Path to Perl parser]) AX_PATH_PROG_OR_FAIL([PERL], [perl]) diff --git a/docs/xen-doxygen/customdoxygen.css b/docs/xen-doxygen/customdoxygen.css new file mode 100644 index 0000000000..4735e41cf5 --- /dev/null +++ b/docs/xen-doxygen/customdoxygen.css @@ -0,0 +1,36 @@ +/* Custom CSS for Doxygen-generated HTML + * Copyright (c) 2015 Intel Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +code { + font-family: Monaco,Menlo,Consolas,"Courier New",monospace; + background-color: #D8D8D8; + padding: 0 0.25em 0 0.25em; +} + +pre.fragment { + display: block; + font-family: Monaco,Menlo,Consolas,"Courier New",monospace; + padding: 1rem; + word-break: break-all; + word-wrap: break-word; + white-space: pre; + background-color: #D8D8D8; +} + +#projectlogo +{ + vertical-align: middle; +} + +#projectname +{ + font: 200% Tahoma, Arial,sans-serif; + color: #3D578C; +} + +#projectbrief +{ + color: #3D578C; +} diff --git a/docs/xen-doxygen/doxy_input.list b/docs/xen-doxygen/doxy_input.list new file mode 100644 index 0000000000..e69de29bb2 diff --git a/docs/xen-doxygen/doxy_input_template.in b/docs/xen-doxygen/doxy_input_template.in new file mode 100644 index 0000000000..fc7565ab5b --- /dev/null +++ b/docs/xen-doxygen/doxy_input_template.in @@ -0,0 +1,21 @@ +#define __XEN__ + +#include "@XEN_BASE@/xen/include/xen/config.h" + +#if defined(CONFIG_X86_64) + +#define __x86_64__ 1 + +#elif defined(CONFIG_ARM_64) + +#define __aarch64__ 1 + +#elif defined(CONFIG_ARM_32) + +#define __arm__ 1 + +#else + +#error Architecture not supported/recognized. + +#endif diff --git a/docs/xen-doxygen/footer.html b/docs/xen-doxygen/footer.html new file mode 100644 index 0000000000..a24bf2b9b4 --- /dev/null +++ b/docs/xen-doxygen/footer.html @@ -0,0 +1,21 @@ + + + + + + + + + + diff --git a/docs/xen-doxygen/header.html b/docs/xen-doxygen/header.html new file mode 100644 index 0000000000..83ac2f1835 --- /dev/null +++ b/docs/xen-doxygen/header.html @@ -0,0 +1,56 @@ + + + + + + + + +$projectname: $title +$title + + + +$treeview +$search +$mathjax + +$extrastylesheet + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + +
+
$projectname +  $projectnumber +
+
$projectbrief
+
+
$projectbrief
+
$searchbox
+
+ + diff --git a/docs/xen-doxygen/mainpage.md b/docs/xen-doxygen/mainpage.md new file mode 100644 index 0000000000..ff548b87fc --- /dev/null +++ b/docs/xen-doxygen/mainpage.md @@ -0,0 +1,5 @@ +# API Documentation {#index} + +## Introduction + +## Licensing diff --git a/docs/xen-doxygen/xen_project_logo_165x67.png b/docs/xen-doxygen/xen_project_logo_165x67.png new file mode 100644 index 0000000000000000000000000000000000000000..7244959d59cdeb9f23c5202160ea45508dfc7265 GIT binary patch literal 18223 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