#------------------------------------------------------------------------------- # Copyright (c) 2019-2020, 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. # LATEX_PDFLATEX_FOUND - true if pdflatex executable found # SPHINX_EXECUTABLE - path to sphinx-build # PLANTUML_JAR_PATH - path to PlantUML #Examples # SphinxFindTools() # function(SphinxFindTools) #Find Sphinx find_package(Sphinx) #Find additional needed Sphinx dependencies. find_package(PythonModules COMPONENTS m2r sphinx-rtd-theme sphinxcontrib.plantuml) #Find plantUML find_package(PlantUML) #Find tools needed for PDF generation. find_package(LATEX COMPONENTS PDFLATEX) set (LATEX_PDFLATEX_FOUND "${LATEX_PDFLATEX_FOUND}" PARENT_SCOPE) if (SPHINX_FOUND AND PLANTUML_FOUND AND PY_M2R_FOUND AND PY_SPHINX-RTD-THEME_FOUND AND PY_SPHINXCONTRIB.PLANTUML) #Export executable locations to global scope. set(SPHINX_EXECUTABLE "${SPHINX_EXECUTABLE}" PARENT_SCOPE) set(PLANTUML_JAR_PATH "${PLANTUML_JAR_PATH}" PARENT_SCOPE) set(Java_JAVA_EXECUTABLE "${Java_JAVA_EXECUTABLE}" 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") set(SPHINX_DESIGN_DOC_ROOT "${TFM_ROOT_DIR}/docs/design_documents") set(SPHINX_TEMPLATE_INDEX_FILE "${SPHINX_DESIGN_DOC_ROOT}/index.rst.in") set(SPHINX_CONFIGURED_INDEX_FILE "${SPHINX_TMP_DOC_DIR}/docs/design_documents/index.rst") set(SPHINX_MAIN_INDEX_FILE "docs/index.rst") #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 "v1.1") set(SPHINXCFG_TFM_VERSION_FULL "Version 1.1") get_filename_component(_NDX_FILE_DIR ${SPHINX_CONFIGURED_INDEX_FILE} DIRECTORY ) #This command does not generates the specified output file and thus it will #always be run. Any other command or target depending on the "run-allways" #output will be always executed too. add_custom_command(OUTPUT run-allways COMMAND "${CMAKE_COMMAND}" -E echo) #Using add_custom_command allows CMake to generate proper clean commands #for document generation. add_custom_command(OUTPUT "${SPHINX_TMP_DOC_DIR}" "${SPHINX_CONFIGURED_INDEX_FILE}" #Create target directory for SPHINX_CONFIGURED_INDEX_FILE. Needed #by the next command. COMMAND "${CMAKE_COMMAND}" -E make_directory "${_NDX_FILE_DIR}" #Fill out index.rst template COMMAND "${CMAKE_COMMAND}" -D TFM_ROOT_DIR=${TFM_ROOT_DIR} -D SPHINX_TEMPLATE_INDEX_FILE=${SPHINX_TEMPLATE_INDEX_FILE} -D SPHINX_CONFIGURED_INDEX_FILE=${SPHINX_CONFIGURED_INDEX_FILE} -D SPHINX_DESIGN_DOC_ROOT=${SPHINX_DESIGN_DOC_ROOT} -P "${TFM_ROOT_DIR}/cmake/SphinxDesignDocStatus.cmake" #Copy document files to temp direcotry COMMAND "${CMAKE_COMMAND}" -D TFM_ROOT_DIR=${TFM_ROOT_DIR} -D DST_DIR=${SPHINX_TMP_DOC_DIR} -D BINARY_DIR=${CMAKE_BINARY_DIR} -D MASTER_IDX=${SPHINX_MAIN_INDEX_FILE} -P "${TFM_ROOT_DIR}/cmake/SphinxCopyDoc.cmake" WORKING_DIRECTORY "${TFM_ROOT_DIR}" DEPENDS run-allways VERBATIM ) add_custom_target(create_sphinx_input SOURCES "${SPHINX_TMP_DOC_DIR}" ) 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 create_sphinx_input run-allways 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 (LATEX_PDFLATEX_FOUND) if (NOT CMAKE_GENERATOR MATCHES "Makefiles") message(WARNING "Generator is not make based. PDF document generation target is not created.") else() #This file shall not be included before cmake did finish finding the make tool and thus #setting CMAKE_MAKE_PROGRAM. Currently the search is triggered by the project() command. if(NOT CMAKE_MAKE_PROGRAM) message(FATAL_ERROR "CMAKE_MAKE_PROGRAM is not set. This file must be included after the project command is run.") endif() 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 create_sphinx_input 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) endif() 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()