aboutsummaryrefslogtreecommitdiff
path: root/cmake
diff options
context:
space:
mode:
authorGyorgy Szing <Gyorgy.Szing@arm.com>2018-09-27 17:00:46 +0200
committerGyorgy Szing <Gyorgy.Szing@arm.com>2019-05-02 11:33:56 +0200
commit74dae3cf92b7c4a52ff629c353649f43fcfa5c86 (patch)
treee62622b300f87ba92b12c4341c93e64f5fcbc1c8 /cmake
parentcf32b90f2b80d9afa0f5d62e817c40d70bf5a6f5 (diff)
downloadtrusted-firmware-m-74dae3cf92b7c4a52ff629c353649f43fcfa5c86.tar.gz
Doc: Add support for Sphinx documentation build.
Technical documentation of TF-M is captured in GitHub flavored markdown files. This change add support for building HTML and PDF output of these files using the Sphinx tool. Change-Id: I8be11256f2c654c248b1974974a5de6190ca0fc3 Signed-off-by: Gyorgy Szing <Gyorgy.Szing@arm.com>
Diffstat (limited to 'cmake')
-rw-r--r--cmake/Common/BuildDoxygenDoc.cmake4
-rw-r--r--cmake/Common/BuildSphinxDoc.cmake169
-rw-r--r--cmake/Common/Utils.cmake93
-rw-r--r--cmake/FindPlantUML.cmake54
-rw-r--r--cmake/FindPythonModules.cmake64
-rw-r--r--cmake/FindSphinx.cmake92
-rw-r--r--cmake/SphinxCopyDoc.cmake57
7 files changed, 479 insertions, 54 deletions
diff --git a/cmake/Common/BuildDoxygenDoc.cmake b/cmake/Common/BuildDoxygenDoc.cmake
index 6f9c6c725c..f98c0f9c33 100644
--- a/cmake/Common/BuildDoxygenDoc.cmake
+++ b/cmake/Common/BuildDoxygenDoc.cmake
@@ -56,7 +56,7 @@ function(DoxyFindTools)
set(DOXYGEN_EXECUTABLE "${DOXYGEN_EXECUTABLE}" PARENT_SCOPE)
set(DOXYGEN_DOT_EXECUTABLE "${DOXYGEN_DOT_EXECUTABLE}" PARENT_SCOPE)
set(PLANTUML_JAR_PATH "${PLANTUML_JAR_PATH}" PARENT_SCOPE)
- set(_NODOC False PARENT_SCOPE)
+ set(NODOC False PARENT_SCOPE)
else()
message(WARNING "Some tools are missing for document generation. Document generation target is not created.")
set(NODOC True PARENT_SCOPE)
@@ -85,7 +85,7 @@ if (NOT NODOC)
#Version ID of TF-M.
#TODO: this shall not be hard-coded here. A process need to defined for
# versioning the document (and TF-M).
- set(DOXYCFG_TFM_VERSION "v0.01")
+ set(DOXYCFG_TFM_VERSION "v1.0.0-Beta")
#Using add_custom_command allows CMake to generate proper clean commands
#for document generation.
diff --git a/cmake/Common/BuildSphinxDoc.cmake b/cmake/Common/BuildSphinxDoc.cmake
new file mode 100644
index 0000000000..7287d0588a
--- /dev/null
+++ b/cmake/Common/BuildSphinxDoc.cmake
@@ -0,0 +1,169 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#This file adds build and install targets to build the Sphinx documentation
+#for TF-M. This currently means the "User Guide". Further documentation
+#builds may be added in the future.
+
+Include(CMakeParseArguments)
+
+#This function will find the location of tools needed to build the
+#documentation. These are:
+# - Mandatory:
+# - Sphinx 1.9.0 or higher
+# - PlantUML and it's dependencies
+# - Optional
+# - LateX/PDFLateX
+#
+#Inputs:
+# none (some global variables might be used by FindXXX modules used. For
+# details please check the modules used.)
+#Outputs:
+# SPHINX_NODOC - will be defined and set to true is any mandatory tool is
+# missing.
+# PDFLATEX_COMPILER - path to pdflatex executable
+# SPHINX_EXECUTABLE - path to sphinx-build
+# PLANTUML_JAR_PATH - path to PlantUML
+
+#Examples
+# SphinxFindTools()
+#
+function(SphinxFindTools)
+ find_package(Sphinx)
+
+ #Find additional needed python dependencies.
+ find_package(PythonModules COMPONENTS m2r sphinx-rtd-theme)
+
+ #Find plantUML
+ find_package(PlantUML)
+
+ #Find tools needed for PDF generation.
+ find_package(LATEX COMPONENTS PDFLATEX)
+ if (LATEX_PDFLATEX_FOUND)
+ set (PDFLATEX_COMPILER "${PDFLATEX_COMPILER}" PARENT_SCOPE)
+ endif()
+
+ if (SPHINX_FOUND AND PLANTUML_FOUND AND PY_M2R_FOUND
+ AND PY_SPHINX-RTD-THEME_FOUND)
+ #Export executable locations to global scope.
+ set(SPHINX_EXECUTABLE "${SPHINX_EXECUTABLE}" PARENT_SCOPE)
+ set(PLANTUML_JAR_PATH "${PLANTUML_JAR_PATH}" PARENT_SCOPE)
+ set(SPHINX_NODOC False PARENT_SCOPE)
+ else()
+ message(WARNING "Some tools are missing for Sphinx document generation. Document generation target is not created.")
+ set(SPHINX_NODOC True PARENT_SCOPE)
+ endif()
+endfunction()
+
+#Find the needed tools.
+SphinxFindTools()
+
+#If mandatory tools are missing, skip creating document generation targets.
+#This means missing documentation tools is not a critical error, and building
+#TF-M is still possible.
+if (NOT SPHINX_NODOC)
+ #The Sphinx configuration file needs some project specific configuration.
+ #Variables with SPHINXCFG_ prefix are setting values related to that.
+ #This is where Sphinx output will be written
+ set(SPHINXCFG_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}/doc_sphinx")
+
+ set(SPHINX_TMP_DOC_DIR "${CMAKE_CURRENT_BINARY_DIR}/doc_sphinx_in")
+
+ set(SPHINXCFG_TEMPLATE_FILE "${TFM_ROOT_DIR}/docs/Conf.py.in")
+ set(SPHINXCFG_CONFIGURED_FILE "${SPHINXCFG_OUTPUT_PATH}/Conf.py")
+
+
+ #Version ID of TF-M.
+ #TODO: this shall not be hard-coded here. We need a process to define the
+ # version number of the document (and TF-M).
+ set(SPHINXCFG_TFM_VERSION "1.0.0-Beta")
+ set(SPHINXCFG_TFM_VERSION_FULL "Version 1.0.0-Beta")
+
+ #Using add_custom_command allows CMake to generate proper clean commands
+ #for document generation.
+ add_custom_command(OUTPUT "${SPHINX_TMP_DOC_DIR}"
+ COMMAND "${CMAKE_COMMAND}" -D TFM_ROOT_DIR=${TFM_ROOT_DIR} -D DST_DIR=${SPHINX_TMP_DOC_DIR} -P "${TFM_ROOT_DIR}/cmake/SphinxCopyDoc.cmake"
+ WORKING_DIRECTORY "${TFM_ROOT_DIR}"
+ VERBATIM
+ )
+
+ add_custom_command(OUTPUT "${SPHINXCFG_OUTPUT_PATH}/html"
+ COMMAND "${SPHINX_EXECUTABLE}" -c "${SPHINXCFG_OUTPUT_PATH}" -b html "${SPHINX_TMP_DOC_DIR}" "${SPHINXCFG_OUTPUT_PATH}/html"
+ WORKING_DIRECTORY "${TFM_ROOT_DIR}"
+ DEPENDS "${SPHINX_TMP_DOC_DIR}"
+ COMMENT "Running Sphinx to generate user guide (HTML)."
+ VERBATIM
+ )
+
+ #Create build target to generate HTML documentation.
+ add_custom_target(doc_userguide
+ COMMENT "Generating User Guide with Sphinx..."
+ #Copy document files from the top level dir to docs
+ SOURCES "${SPHINXCFG_OUTPUT_PATH}/html"
+ )
+
+ #Add the HTML documentation to install content
+ install(DIRECTORY ${SPHINXCFG_OUTPUT_PATH}/html DESTINATION doc/user_guide
+ EXCLUDE_FROM_ALL
+ COMPONENT user_guide
+ PATTERN .buildinfo EXCLUDE
+ )
+
+ #If PDF documentation is being made.
+ if (PDFLATEX_COMPILER)
+ set(_PDF_FILE "${SPHINXCFG_OUTPUT_PATH}/latex/tf-m.pdf")
+
+ add_custom_command(OUTPUT "${SPHINXCFG_OUTPUT_PATH}/latex"
+ COMMAND "${SPHINX_EXECUTABLE}" -c "${SPHINXCFG_OUTPUT_PATH}" -b latex "${SPHINX_TMP_DOC_DIR}" "${SPHINXCFG_OUTPUT_PATH}/latex"
+ WORKING_DIRECTORY "${TFM_ROOT_DIR}"
+ DEPENDS "${SPHINX_TMP_DOC_DIR}"
+ COMMENT "Running Sphinx to generate user guide (LaTeX)."
+ VERBATIM
+ )
+
+ add_custom_command(OUTPUT "${_PDF_FILE}"
+ COMMAND "${CMAKE_MAKE_PROGRAM}" all-pdf
+ WORKING_DIRECTORY ${SPHINXCFG_OUTPUT_PATH}/latex
+ DEPENDS "${SPHINXCFG_OUTPUT_PATH}/latex"
+ COMMENT "Generating PDF version of User Guide..."
+ VERBATIM
+ )
+
+ #We do not use the add_custom_command trick here to get proper clean
+ #command since the clean rules "added" above will remove the entire
+ #doc directory, and thus clean the PDF output too.
+ add_custom_target(doc_userguide_pdf
+ COMMENT "Generating PDF version of TF-M User Guide..."
+ SOURCES "${_PDF_FILE}"
+ VERBATIM)
+
+ #Add the pdf documentation to install content
+ install(FILES "${_PDF_FILE}" DESTINATION "doc/user_guide"
+ RENAME "tf-m_user_guide.pdf"
+ COMPONENT user_guide
+ EXCLUDE_FROM_ALL)
+ else()
+ message(WARNING "PDF generation tools are missing. PDF document generation target is not created.")
+ endif()
+
+ #Generate build target which installs the documentation.
+ if (TARGET doc_userguide_pdf)
+ add_custom_target(install_userguide
+ DEPENDS doc_userguide doc_userguide_pdf
+ COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=user_guide
+ -P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
+ else()
+ add_custom_target(install_userguide
+ DEPENDS doc_userguide
+ COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=user_guide
+ -P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
+ endif()
+
+ #Now instantiate a Sphinx configuration file from the template.
+ message(STATUS "Writing Sphinx configuration...")
+ configure_file(${SPHINXCFG_TEMPLATE_FILE} ${SPHINXCFG_CONFIGURED_FILE} @ONLY)
+endif()
diff --git a/cmake/Common/Utils.cmake b/cmake/Common/Utils.cmake
index 0c3b0d0d92..452d0bf914 100644
--- a/cmake/Common/Utils.cmake
+++ b/cmake/Common/Utils.cmake
@@ -1,31 +1,41 @@
#-------------------------------------------------------------------------------
-# Copyright (c) 2017, Arm Limited. All rights reserved.
+# Copyright (c) 2017-2019, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
#-------------------------------------------------------------------------------
-# Append a value to a string if not already present
+
+#Print a message and exit with failure
+#
+#Examples:
+# failure("Something is wrong!")
+
+function(failure)
+ message(FATAL_ERROR "${ARGN}")
+endfunction()
+
+#Append a value to a string if not already present
#
-# Append an item to a string if no item with matching key is already on the string.
-# This function's intended purpose is to append unique flags to command line switches.
+#Append an item to a string if no item with matching key is already on the string.
+#This function's intended purpose is to append unique flags to command line switches.
#
-# Examples:
-# string_append_unique_item(STRING C_FLAGS KEY "--target" VAL "--target=armv8m-arm-none-eabi")
+#Examples:
+# string_append_unique_item(STRING C_FLAGS KEY "--target" VAL "--target=armv8m-arm-none-eabi")
#
-# INPUTS:
-# STRING - (mandatory) - name of the string to operate on
-# KEY - (mandatory) - string to look for
-# VAL - (mandatory) - value to put be added to the string
+#INPUTS:
+# STRING - (mandatory) - name of the string to operate on
+# KEY - (mandatory) - string to look for
+# VAL - (mandatory) - value to put be added to the string
#
-# OUTPUTS
-# STRING is modified as needed.
+#OUTPUTS
+# STRING is modified as needed.
#
function(string_append_unique_item)
#Parse our arguments
- set( _OPTIONS_ARGS ) #No option (on/off) arguments (e.g. IGNORE_CASE)
- set( _ONE_VALUE_ARGS STRING KEY VAL) #Single option arguments (e.g. PATH "./foo/bar")
- set( _MULTI_VALUE_ARGS ) #List arguments (e.g. LANGUAGES C ASM CXX)
+ set( _OPTIONS_ARGS ) #No option (on/off) arguments (e.g. IGNORE_CASE)
+ set( _ONE_VALUE_ARGS STRING KEY VAL) #Single option arguments (e.g. PATH "./foo/bar")
+ set( _MULTI_VALUE_ARGS ) #List arguments (e.g. LANGUAGES C ASM CXX)
cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN} )
#Check mandatory parameters
@@ -42,11 +52,54 @@ function(string_append_unique_item)
if(NOT _MY_PARAMS_VAL)
failure("string_append_unique_item(): Missing VAL parameter!")
endif()
- set(_VAL ${_MY_PARAMS_VAL})
+ set(_VAL ${_MY_PARAMS_VAL})
- #Scan the string.
- STRING(REGEX MATCH "( |^) *${_KEY}" _FOUND "${${_STRING}}")
- if("${_FOUND}" STREQUAL "")
+ #Scan the string.
+ STRING(REGEX MATCH "( |^) *${_KEY}" _FOUND "${${_STRING}}")
+ if("${_FOUND}" STREQUAL "")
set(${_STRING} "${${_STRING}} ${_VAL}" PARENT_SCOPE)
- endif()
+ endif()
+endfunction()
+
+
+#Convert \ directory separators to / on windows systems
+#
+#Convert the directory separators to forward slash on windows. Avoid
+#conversion if path contains any forward slashes to avoid mixing up cygwin or
+#mingw paths where an extra caharacter is escaped (i.e. "/c/Program\ Files/")
+#
+#Examples:
+# set(MY_PATH "C:\foo\bar")
+# win_fix_dir_sep(PATH MY_PATH)
+#
+#INPUTS:
+# PATH - (mandatory) - name of the string variable to operate on
+#
+#OUTPUTS
+# PATH is modified as needed.
+#
+function(win_fix_dir_sep)
+ #Parse our arguments
+ set( _OPTIONS_ARGS ) #No option (on/off) arguments (e.g. IGNORE_CASE)
+ set( _ONE_VALUE_ARGS PATH ) #Single option arguments (e.g. PATH "./foo/bar")
+ set( _MULTI_VALUE_ARGS ) #List arguments (e.g. LANGUAGES C ASM CXX)
+ cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN} )
+
+ #Check mandatory parameters
+ if(NOT _MY_PARAMS_PATH)
+ failure("win_fix_dir_sep(): Missing mandatory parameter PATH!")
+ endif()
+ set(_PATH ${_MY_PARAMS_PATH})
+
+ #To avoid trouble on windows change directory separator.
+ if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
+ #Do not convert directory separator if there are forward slashes
+ #present. This is to avoid mixing up escaped characters in cygwin
+ #or mingw paths (i.e. c:/Program\ Files/something)
+ string(FIND "${${_PATH}}" "/" _is_found)
+ if (_is_found LESS 0)
+ string(REPLACE "\\" "/" ${_PATH} "${${_PATH}}")
+ set(${_PATH} "${${_PATH}}" PARENT_SCOPE)
+ endif()
+ endif()
endfunction()
diff --git a/cmake/FindPlantUML.cmake b/cmake/FindPlantUML.cmake
index a55774c528..ae61be7069 100644
--- a/cmake/FindPlantUML.cmake
+++ b/cmake/FindPlantUML.cmake
@@ -5,30 +5,30 @@
#
#-------------------------------------------------------------------------------
-# FindPlantuml
-# -----------
-# PlantUML is a diagram generation tool. It can generate various UML and non-UML
-# diagrams. See: http://plantuml.com/
+#FindPlantuml
+#-----------
+#PlantUML is a diagram generation tool. It can generate various UML and non-UML
+#diagrams. See: http://plantuml.com/
#
-# This module checks PlantUML availability and checks if the Java runtime is
-# available.
-# For Windows PlantUML is distributed as a jar archive and thus there is no
-# standard install location where it could be searched for.
-# Most Linux distributions come with a proper PlantUML package which installs
-# a shell script to easy starting PlantUML, but the location of the .jar file
-# is hidden.
-# Thus there is no standard location to search for the .jar file and this module
-# depends on user input.
+#This module checks PlantUML availability and checks if the Java runtime is
+#available.
+#For Windows PlantUML is distributed as a jar archive and thus there is no
+#standard install location where it could be searched for.
+#Most Linux distributions come with a proper PlantUML package which installs
+#a shell script to easy starting PlantUML, but the location of the .jar file
+#is hidden.
+#Thus there is no standard location to search for the .jar file and this module
+#depends on user input.
#
-# This module has the following parameters:
-# PLANTUML_JAR_PATH = variable specifying where the PlantUML java archive
-# (plantuml.jar) can be found. If it is not defined,
-# the environment variable with the same name is used.
-# If both is missing, that is an error.
+#This module has the following parameters:
+# PLANTUML_JAR_PATH = variable specifying where the PlantUML java archive
+# (plantuml.jar) can be found. If it is not defined,
+# the environment variable with the same name is used.
+# If both is missing, that is an error.
#
-# This module defines the following variables:
-# PLANTUML_VERSION = The version reported by "plantuml.jar -version"
-# PLANTUML_FOUND = Was the .jar file found and sucesfuly executed.
+#This module defines the following variables:
+# PLANTUML_VERSION = The version reported by "plantuml.jar -version"
+# PLANTUML_FOUND = Was the .jar file found and sucesfuly executed.
#
find_package(Java 1.8 COMPONENTS Runtime)
@@ -44,17 +44,7 @@ if(Java_Runtime_FOUND)
if (NOT DEFINED PLANTUML_JAR_PATH)
message(STATUS "PLANTUML_JAR_PATH variable is missing, PlantUML jar location is unknown.")
else()
- #To avoid trouble on windows change directory separator.
- if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
- #Do not convert directory separator if there are forward slashes
- #present. This is to avoid mixing up escaped characters in cygwin
- #or mingw paths (i.e. c:/Program\ Files/something)
- string(FIND "${PLANTUML_JAR_PATH}" "/" _is_found)
- if (_is_found LESS 0)
- string(REPLACE "\\" "/" PLANTUML_JAR_PATH "${PLANTUML_JAR_PATH}")
- endif()
- endif()
-
+ win_fix_dir_sep(PATH PLANTUML_JAR_PATH)
#Get plantuml version
execute_process(COMMAND "${Java_JAVA_EXECUTABLE}" "-jar" "${PLANTUML_JAR_PATH}" "-version" OUTPUT_VARIABLE _PLANTUML_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
#Parse plantuml output
diff --git a/cmake/FindPythonModules.cmake b/cmake/FindPythonModules.cmake
new file mode 100644
index 0000000000..bb8d4fb209
--- /dev/null
+++ b/cmake/FindPythonModules.cmake
@@ -0,0 +1,64 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#FindPythonModules
+#-----------
+#This module checks availability of Python modules.
+#
+#This module has the following parameters:
+# PYTHON_EXECUTABLE - Location of python interpreter.
+# COMPONENTS - List of python modules to look for.
+#
+#This module defines the following variables:
+# PY_XXX - Cached string variable with the location of the module.
+# PY_XXX_FOUND - Set if the module is available.
+#
+# Where XXX is the upper case name of the module.
+#
+#Examples
+# To look for m2r and report error if not found
+# find_module(PythonModules COMPONENTS m2r)
+# if (PY_M2R_FOUND)
+# do something
+# endif()
+#
+# To look for m2r and do not report error if not found
+# find_module(PythonModules OPTIONAL_COMPONENTS m2r)
+# if (PY_M2R_FOUND)
+# do something
+# endif()
+
+if(NOT DEFINED PYTHON_EXECUTABLE)
+ message(FATAL_ERROR "FindPythonModules: mandatory parameter PYTHON_EXECUTABLE is missing.")
+endif()
+
+include(Common/Utils)
+
+foreach(_mod ${PythonModules_FIND_COMPONENTS})
+ string(TOUPPER ${_mod} _mod_upper)
+ string(REPLACE "-" "_" _modname "${_mod}")
+ if (NOT PY_${_mod_upper})
+ #Execute python and try to include the module.
+ execute_process(
+ COMMAND ${PYTHON_EXECUTABLE} -c "import ${_modname}; print(${_modname}.__file__);"
+ RESULT_VARIABLE ${_mod}_status
+ OUTPUT_VARIABLE ${_mod}_path
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ #If suceeded
+ if(NOT ${_mod}_status)
+ #Avoid trouble with directory separator on windows.
+ win_fix_dir_sep(PATH ${_mod}_path)
+ set("PY_${_mod_upper}" "${${_mod}_path}" CACHE STRING
+ "Location of Python module ${_mod}")
+ endif()
+ endif()
+ find_package_handle_standard_args(PY_${_mod_upper}
+ FOUND_VAR PY_${_mod_upper}_FOUND
+ REQUIRED_VARS PY_${_mod_upper}
+ FAIL_MESSAGE "Can not find Python module ${_mod}")
+endforeach()
diff --git a/cmake/FindSphinx.cmake b/cmake/FindSphinx.cmake
new file mode 100644
index 0000000000..8e3925ef94
--- /dev/null
+++ b/cmake/FindSphinx.cmake
@@ -0,0 +1,92 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#FindSphinx
+#-----------
+#Sphinx is a document generation tool written in Python.
+#See http://www.sphinx-doc.org/en/master/
+#
+#This module checks availability of the Sphinx document generator
+#(sphinx-build) and it's dependences (Python).
+#Sphinx is distributed as pip package or on Linux as a distribution specific
+#package (i.e. python-sphinx for Ubuntu). Independent of the distribution
+#method this module expects sphix-build to be either available on the PATH,
+#or to be located in a host OS specific standard location.
+#
+#This modules has the following parameters:
+# SPHINX_PATH = variable specifying where sphinx-build can be found.
+# If it is not defined the environment variable with
+# the same name is used. If that is also undefined,
+# then OS specific standard locations will be
+# searched.
+#
+# This modules defines the following variables:
+# SPHINX_VERSION = The version reported by "sphinx-build --version"
+# SPHINX_FOUND = True is sphinx-build was found and executed fine
+#
+
+Include(CMakeParseArguments)
+
+#Sphinx needs Python.
+find_package(PythonInterp 3)
+if (NOT PYTHONINTERP_FOUND)
+ message(STATUS "Can not find Python3.x interpreter. Pyhton3 must be installed and available on the PATH.")
+ message(STATUS "Sphinx documentation targets will not be created.")
+ return()
+endif()
+
+if (NOT DEFINED SPHINX_PATH)
+ if (DEFINED $ENV{SPHINX_PATH})
+ set(SPHINX_PATH $ENV{SPHINX_PATH})
+ endif()
+endif()
+
+
+if (DEFINED SPHINX_PATH)
+ #Find the Sphinx executable. Search only at SPHINX_PATH.
+ find_program(SPHINX_EXECUTABLE
+ NAMES sphinx-build
+ DOC "Sphinx Documentation Builder (sphinx-doc.org)"
+ PATH ${SPHINX_PATH}
+ NO_DEFAULT_PATH
+ NO_CMAKE_ENVIRONMENT_PATH
+ NO_CMAKE_PATH
+ NO_SYSTEM_ENVIRONMENT_PATH
+ NO_CMAKE_SYSTEM_PATH
+ NO_CMAKE_FIND_ROOT_PATH
+ )
+ if (SPHINX_EXECUTABLE-NOTFOUND)
+ message(STATUS "Failed to find sphinx-build at ${SPHINX_PATH}.")
+ message(STATUS "Sphinx documentation targets will not be created.")
+ return()
+ endif()
+else()
+ #Find the Sphinx executable. Search OS specific default locations.
+ find_program(SPHINX_EXECUTABLE
+ NAMES sphinx-build
+ DOC "Sphinx Documentation Builder (sphinx-doc.org)"
+ )
+
+ if (SPHINX_EXECUTABLE-NOTFOUND)
+ message(STATUS "Failed to find sphinx-build at OS specific default locations.")
+ message(STATUS "Sphinx documentation targets will not be created.")
+ return()
+ endif()
+endif()
+
+#Get Sphinx version
+execute_process(COMMAND "${SPHINX_EXECUTABLE}" "--version" OUTPUT_VARIABLE _SPHINX_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
+#Parse output
+if(_SPHINX_VERSION)
+ if(_SPHINX_VERSION MATCHES ".*sphinx-build ([0-9.]+).*")
+ string(REGEX REPLACE ".*sphinx-build ([0-9.]+).*" "\\1" SPHINX_VERSION "${_SPHINX_VERSION}")
+ endif()
+endif()
+
+#Set "standard" find module return values
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Sphinx REQUIRED_VARS SPHINX_EXECUTABLE SPHINX_VERSION VERSION_VAR SPHINX_VERSION)
diff --git a/cmake/SphinxCopyDoc.cmake b/cmake/SphinxCopyDoc.cmake
new file mode 100644
index 0000000000..c1f7731ac1
--- /dev/null
+++ b/cmake/SphinxCopyDoc.cmake
@@ -0,0 +1,57 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#Sphinx needs all document files to be under a single directory. This script
+#copies all document files to a temporary directory while keeping the original
+#directory tree (relative location of files) except "docs/index.rst" which is
+#moved to the top level of the new tree.
+#
+# i.e.:
+# <DST_DIR>
+# | All documents from <TFM_ROOT_DIR> plus <TFM_ROOT_DIR>/docs/index.rst
+# |
+# +---docs
+# | |
+# \- all documents from <TFM_ROOT_DIR>/docs except index.rst
+# |
+# +---lib
+# | |
+# | \- All document from <TFM_ROOT_DIR>/lib keeping reativle location
+# ...
+# |
+#
+#Usage:
+# cmake -DDST_RIR=<path to destination> -DTFM_ROOT_DIR=<path to tf-m root> \
+# -P SphinxCopyDoc.cmake
+
+#Check input parameters
+foreach(_PARAM IN ITEMS TFM_ROOT_DIR DST_DIR)
+ if (NOT DEFINED ${_PARAM})
+ message(FATAL_ERROR "Variable ${_PARAM} is undefined. Please add -D${_PARAM}=<...> when calling this script.")
+ endif()
+endforeach()
+
+message(STATUS "Creating document tree for Sphinx under ${DST_DIR}")
+
+#List all document files.
+file(GLOB_RECURSE _COPY_FILES
+ LIST_DIRECTORIES false
+ RELATIVE "${TFM_ROOT_DIR}"
+ "${TFM_ROOT_DIR}/*.md"
+ "${TFM_ROOT_DIR}/*.rst")
+
+#Subtract exluded files from copy files
+list(REMOVE_ITEM _COPY_FILES "docs/index.rst")
+
+#Copy files with directory tree.
+foreach(_FILE ${_COPY_FILES})
+ get_filename_component(_DIR ${_FILE} DIRECTORY)
+ file(COPY ${_FILE} DESTINATION "${DST_DIR}/${_DIR}")
+endforeach()
+
+#Copy index.rst to the top level
+file(COPY "${TFM_ROOT_DIR}/docs/index.rst" DESTINATION "${DST_DIR}")