This add a virtualenv [1] with we can control the versions
of Documentation's (python) requirements. It also changes the
default behavior, if sphinx is not installed on the OS.

If Sphinx is not available make builds a virtualenv under
Documentation/local and installs the requirements from
Documentation/sphinx/requirements.txt with pip [2].

Using virtualenv helps also to provide well tested environments. ATM the
requirements.txt defines::

  # last patch level from Sphinx-doc v1.5
  Sphinx>=1.5,<1.6

  # latest version of the RTD theme: http://docs.readthedocs.io
  sphinx_rtd_theme

To enforce a virtualenv set option VENV explicitly. E.g. on build
hosts you might want to choose a the python version explicitly and a
individually requirements-file [3] where you can stick the versions of
the installed python-packages::

  make VENV=myenv PY_REQUIRE=myenv.txt PY=3 ...

[1] https://virtualenv.pypa.io
[2] https://pip.pypa.io
[3] 
https://pip.pypa.io/en/stable/reference/pip_install/#requirements-file-format

Signed-off-by: Markus Heiser <markus.hei...@darmarit.de>
---
 Documentation/.gitignore              |   1 +
 Documentation/Makefile                |  76 ++++++++++++----------
 Documentation/Makefile.python         | 116 ++++++++++++++++++++++++++++++++++
 Documentation/conf.py                 |   2 +-
 Documentation/doc-guide/sphinx.rst    |  25 ++++++--
 Documentation/sphinx/requirements.txt |   9 +++
 6 files changed, 190 insertions(+), 39 deletions(-)
 create mode 100644 Documentation/Makefile.python
 create mode 100644 Documentation/sphinx/requirements.txt

diff --git a/Documentation/.gitignore b/Documentation/.gitignore
index e74fec8..7a7c8f4 100644
--- a/Documentation/.gitignore
+++ b/Documentation/.gitignore
@@ -1,2 +1,3 @@
 output
+local
 *.pyc
diff --git a/Documentation/Makefile b/Documentation/Makefile
index a423203..27c1d5a 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -14,20 +14,40 @@ PAPER         =
 BUILDDIR      = $(obj)/output
 PDFLATEX      = xelatex
 LATEXOPTS     = -interaction=batchmode
+VENV_ROOT     = ./Documentation/local
+PY_REQUIRE    = ./Documentation/sphinx/requirements.txt
 
 # User-friendly check for sphinx-build
 HAVE_SPHINX := $(shell if which $(SPHINXBUILD) >/dev/null 2>&1; then echo 1; 
else echo 0; fi)
 
-ifeq ($(HAVE_SPHINX),0)
+# User-friendly check for pdflatex
+HAVE_PDFLATEX := $(shell if which $(PDFLATEX) >/dev/null 2>&1; then echo 1; 
else echo 0; fi)
 
-.DEFAULT:
-       $(warning The '$(SPHINXBUILD)' command was not found. Make sure you 
have Sphinx installed and in PATH, or set the SPHINXBUILD make variable to 
point to the full path of the '$(SPHINXBUILD)' executable.)
-       @echo "  SKIP    Sphinx $@ target."
+# If sphinx-build is not available, set 'VENV' to build a local virtualenv
+ifeq ($(HAVE_SPHINX),0)
+  VENV ?= sphinx-env
+else
+  VENV ?=
+endif
 
-else # HAVE_SPHINX
+dochelp::
+       @echo  ' Linux kernel internal documentation in different formats from 
ReST:'
+       @echo  '  htmldocs        - HTML'
+       @echo  '  latexdocs       - LaTeX'
+       @echo  '  pdfdocs         - PDF'
+       @echo  '  epubdocs        - EPUB'
+       @echo  '  xmldocs         - XML'
+       @echo  '  linkcheckdocs   - check for broken external links (will 
connect to external hosts)'
+       @echo  '  cleandocs       - clean all generated files'
+       @echo
+       @echo  '  make SPHINXDIRS="s1 s2" [target] Generate only docs of folder 
s1, s2'
+       @echo  '  valid values for SPHINXDIRS are: $(_SPHINXDIRS)'
+       @echo
+       @echo  '  make SPHINX_CONF={conf-file} [target] use *additional* 
sphinx-build'
+       @echo  '  configuration. This is e.g. useful to build with nit-picking 
config.'
+       @echo
 
-# User-friendly check for pdflatex
-HAVE_PDFLATEX := $(shell if which $(PDFLATEX) >/dev/null 2>&1; then echo 1; 
else echo 0; fi)
+include Documentation/Makefile.python
 
 # Internal variables.
 PAPEROPT_a4     = -D latex_paper_size=a4
@@ -62,13 +82,23 @@ quiet_cmd_sphinx = SPHINX  $@ --> file://$(abspath 
$(BUILDDIR)/$3/$4)
        $(abspath $(srctree)/$(src)/$5) \
        $(abspath $(BUILDDIR)/$3/$4)
 
-htmldocs:
+# rules to build sphinx-exe target
+ifneq ($(strip $(VENV)),)
+SPHINXBUILD = $(PY_ENV_BIN)/sphinx-build
+sphinx-exe: $(PY_ENV)
+       @:
+else  # VENV
+sphinx-exe:
+       @:
+endif # VENV
+
+htmldocs: sphinx-exe
        @+$(foreach var,$(SPHINXDIRS),$(call 
loop_cmd,sphinx,html,$(var),,$(var)))
 
-linkcheckdocs:
+linkcheckdocs: sphinx-exe
        @$(foreach var,$(SPHINXDIRS),$(call 
loop_cmd,sphinx,linkcheck,$(var),,$(var)))
 
-latexdocs:
+latexdocs: sphinx-exe
        @+$(foreach var,$(SPHINXDIRS),$(call 
loop_cmd,sphinx,latex,$(var),latex,$(var)))
 
 ifeq ($(HAVE_PDFLATEX),0)
@@ -84,17 +114,12 @@ pdfdocs: latexdocs
 
 endif # HAVE_PDFLATEX
 
-epubdocs:
+epubdocs: sphinx-exe
        @+$(foreach var,$(SPHINXDIRS),$(call 
loop_cmd,sphinx,epub,$(var),epub,$(var)))
 
-xmldocs:
+xmldocs: sphinx-exe
        @+$(foreach var,$(SPHINXDIRS),$(call 
loop_cmd,sphinx,xml,$(var),xml,$(var)))
 
-endif # HAVE_SPHINX
-
-# The following targets are independent of HAVE_SPHINX, and the rules should
-# work or silently pass without Sphinx.
-
 # no-ops for the Sphinx toolchain
 sgmldocs:
        @:
@@ -107,20 +132,5 @@ installmandocs:
 
 cleandocs:
        $(Q)rm -rf $(BUILDDIR)
+       $(call cmd,pyclean)
        $(Q)$(MAKE) BUILDDIR=$(abspath $(BUILDDIR)) 
$(build)=Documentation/media clean
-
-dochelp:
-       @echo  ' Linux kernel internal documentation in different formats from 
ReST:'
-       @echo  '  htmldocs        - HTML'
-       @echo  '  latexdocs       - LaTeX'
-       @echo  '  pdfdocs         - PDF'
-       @echo  '  epubdocs        - EPUB'
-       @echo  '  xmldocs         - XML'
-       @echo  '  linkcheckdocs   - check for broken external links (will 
connect to external hosts)'
-       @echo  '  cleandocs       - clean all generated files'
-       @echo
-       @echo  '  make SPHINXDIRS="s1 s2" [target] Generate only docs of folder 
s1, s2'
-       @echo  '  valid values for SPHINXDIRS are: $(_SPHINXDIRS)'
-       @echo
-       @echo  '  make SPHINX_CONF={conf-file} [target] use *additional* 
sphinx-build'
-       @echo  '  configuration. This is e.g. useful to build with nit-picking 
config.'
diff --git a/Documentation/Makefile.python b/Documentation/Makefile.python
new file mode 100644
index 0000000..cf34e1f
--- /dev/null
+++ b/Documentation/Makefile.python
@@ -0,0 +1,116 @@
+# -*- coding: utf-8; mode: makefile-gmake -*-
+
+# python version, empty means: use OS's default python
+PY           ?=
+# name of the virualenv
+VENV         ?= py$(PY)
+
+# for those of us, who wan't to maintain multiple Sphinx versions
+PY_REQUIRE   ?= requirements.txt
+
+# see cmd_pyclean
+VENV_ROOT    ?= ./local
+
+PYTHON       = python$(PY)
+PIP          = pip$(PY)
+VIRTUALENV   = virtualenv --python=$(PYTHON)
+
+VTENV_OPTS   = "--no-site-packages"
+PY_ENV       = $(VENV_ROOT)/$(VENV)-py$(PY)
+PY_ENV_BIN   = $(PY_ENV)/bin
+
+ifeq ($(KBUILD_VERBOSE),1)
+  PIP_VERBOSE =
+  VIRTUALENV_VERBOSE =
+else
+  PIP_VERBOSE = "-q"
+  VIRTUALENV_VERBOSE = "-q"
+endif
+
+python-help dochelp::
+       @echo  '  Documentation/Makefile.python targets:'
+       @echo  '    $(PY_ENV)   - setup virtualenv and install PY_REQUIRE'
+       @echo  '  options:'
+       @echo  '    make PY=3 [targets] => setup a virtualenv with python3 
($(PYTHON))'
+       @echo  '    make VENV=...       => to eval targets within vitualenv 
($(VENV))'
+       @echo  '    make PY_REQUIRE=... => requirements.txt file 
($(PY_REQUIRE))'
+
+
+# 
------------------------------------------------------------------------------
+# OS requirements
+# 
------------------------------------------------------------------------------
+
+PHONY += msg-python-exe python-exe
+msg-python-exe:
+       @echo "\n  $(PYTHON) is required\n\n\
+  Make sure you have an $(PYTHON) installed, grab it from\n\
+  https://www.python.org or install it from your package\n\
+  manager. On debian based OS these requirements are\n\
+  installed by::\n\n\
+    sudo apt-get install $(PYTHON)\n" | $(FMT)
+
+ifeq ($(shell which $(PYTHON) >/dev/null 2>&1; echo $$?), 1)
+python-exe: msg-python-exe
+       $(error The '$(PYTHON)' command was not found)
+else
+python-exe:
+       @:
+endif
+
+msg-pip-exe:
+       @echo "\n  $(PIP) is required\n\n\
+  Make sure you have an updated pip installed, grab it from\n\
+  https://pip.pypa.io or install it from your package\n\
+  manager. On debian based OS these requirements are\n\
+  installed by::\n\n\
+    sudo apt-get install python$(PY)-pip\n" | $(FMT)
+
+ifeq ($(shell which $(PIP) >/dev/null 2>&1; echo $$?), 1)
+pip-exe: msg-pip-exe
+       $(error The '$(PIP)' command was not found)
+else
+pip-exe:
+       @:
+endif
+
+PHONY += msg-virtualenv-exe virtualenv-exe
+msg-virtualenv-exe:
+       @echo "\n  virtualenv is required\n\n\
+  Make sure you have an updated virtualenv installed, grab it from\n\
+  https://virtualenv.pypa.io/en/stable/installation/ or install it\n\
+  via pip by::\n\n\
+    pip install --user virtualenv\n" | $(FMT)
+
+ifeq ($(shell which virtualenv >/dev/null 2>&1; echo $$?), 1)
+virtualenv-exe: msg-virtualenv-exe
+       $(error The 'virtualenv' command was not found)
+else
+virtualenv-exe:
+       @:
+endif
+
+# commands
+# --------
+
+# $2 path to folder where virtualenv take place
+quiet_cmd_virtualenv  = PYENV     $@
+      cmd_virtualenv  = \
+       if [ ! -d "./$(PY_ENV)" ];then                                  \
+               $(VIRTUALENV) $(VIRTUALENV_VERBOSE) $(VTENV_OPTS) $2;   \
+       else                                                            \
+               echo "using virtualenv from $2";                        \
+        fi
+
+quiet_cmd_pyclean     = CLEAN     $(VENV_ROOT)
+      cmd_pyclean     = rm -rf $(VENV_ROOT)
+
+# targets
+# -------
+
+# to build *local* environment, python and virtualenv from the OS is needed!
+$(PY_ENV): virtualenv-exe python-exe
+       $(call cmd,virtualenv,$(PY_ENV))
+       @$(PY_ENV_BIN)/pip install $(PIP_VERBOSE) -r $(PY_REQUIRE)
+
+
+.PHONY: $(PHONY)
diff --git a/Documentation/conf.py b/Documentation/conf.py
index 77d47bb..884c0b7 100644
--- a/Documentation/conf.py
+++ b/Documentation/conf.py
@@ -106,7 +106,7 @@ language = None
 
 # List of patterns, relative to source directory, that match files and
 # directories to ignore when looking for source files.
-exclude_patterns = ['output']
+exclude_patterns = ['output', 'local']
 
 # The reST default role (used for this markup: `text`) to use for all
 # documents.
diff --git a/Documentation/doc-guide/sphinx.rst 
b/Documentation/doc-guide/sphinx.rst
index 84e8e8a..bfaf1a6 100644
--- a/Documentation/doc-guide/sphinx.rst
+++ b/Documentation/doc-guide/sphinx.rst
@@ -23,15 +23,28 @@ Sphinx Build
 ============
 
 The usual way to generate the documentation is to run ``make htmldocs`` or
-``make pdfdocs``. There are also other formats available, see the documentation
-section of ``make help``. The generated documentation is placed in
+``make pdfdocs``. There are also other formats and options available, see the
+documentation section of ``make help``. The generated documentation is placed 
in
 format-specific subdirectories under ``Documentation/output``.
 
+.. _virtualenv: https://virtualenv.pypa.io
+.. _pip: https://pip.pypa.io
+.. _requirements-file: 
https://pip.pypa.io/en/stable/reference/pip_install/#requirements-file-format
+
 To generate documentation, Sphinx (``sphinx-build``) must obviously be
 installed. For prettier HTML output, the Read the Docs Sphinx theme
-(``sphinx_rtd_theme``) is used if available. For PDF output you'll also need
-``XeLaTeX`` and ``convert(1)`` from ImageMagick (https://www.imagemagick.org).
-All of these are widely available and packaged in distributions.
+(``sphinx_rtd_theme``) is used if available. If Sphinx is not available 
``make``
+builds a virtualenv_ under ``Documentation/local`` and installs the
+``Documentation/sphinx/requirements.txt`` with pip_. To enforce a virtualenv 
set
+option ``VENV`` explicitly. E.g. on build hosts you might want to choose a the
+python version explicitly and a individually requirements-file_ where you can
+stick the versions of the installed python-packages::
+
+  make VENV=myenv PY_REQUIRE=myenv.txt PY=3 ...
+
+For PDF output you'll also need ``XeLaTeX`` and ``convert(1)`` from ImageMagick
+(https://www.imagemagick.org).  All of these are widely available and packaged
+in distributions.
 
 To pass extra options to Sphinx, you can use the ``SPHINXOPTS`` make
 variable. For example, use ``make SPHINXOPTS=-v htmldocs`` to get more verbose
@@ -118,6 +131,8 @@ Here are some specific guidelines for the kernel 
documentation:
 the C domain
 ------------
 
+.. _Sphinx C Domain: http://www.sphinx-doc.org/en/stable/domains.html
+
 The `Sphinx C Domain`_ (name c) is suited for documentation of C API. E.g. a
 function prototype:
 
diff --git a/Documentation/sphinx/requirements.txt 
b/Documentation/sphinx/requirements.txt
new file mode 100644
index 0000000..9ee6c68
--- /dev/null
+++ b/Documentation/sphinx/requirements.txt
@@ -0,0 +1,9 @@
+# -------------
+# Documentation
+# -------------
+
+# last patch level from Sphinx-doc v1.5
+Sphinx>=1.5,<1.6
+
+# latest version of the RTD theme: http://docs.readthedocs.io
+sphinx_rtd_theme
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to