cmake_minimum_required(VERSION 3.16) cmake_policy(VERSION 3.16) project(doc) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../../shiboken6/cmake") include(FindDocTools) # When the doc project is built as part of the pyside project, we show informational message # and return early if requirements are not met. if(NOT CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME) if(QT_SRC_DIR AND SPHINX_BUILD AND DOT_EXEC AND BUILD_DOCS) # All requirements met, proceed. else() set(reasons "") if(NOT QT_SRC_DIR) list(APPEND reasons " QT_SRC_DIR variable not set\n") endif() if(NOT SPHINX_BUILD) list(APPEND reasons " sphinx-build command not found\n") endif() if(NOT DOT_EXEC) list(APPEND reasons " graphviz not found\n") endif() if(NOT BUILD_DOCS) list(APPEND reasons " BUILD_DOCS was set to FALSE (default)\n") endif() message(STATUS "apidoc generation targets disabled due to the following reasons:\n" ${reasons}) return() endif() else() # We are building the docs as a standalone project, likely via setup.py build_rst_docs # command. Perform stricter sanity checks. if(NOT SPHINX_BUILD) message(FATAL_ERROR "sphinx-build command not found. Please set the SPHINX_BUILD variable.") endif() endif() # Generate html by default. if(NOT DOC_OUTPUT_FORMAT) set(DOC_OUTPUT_FORMAT "html") endif() if (WIN32) set(PATH_SEP "\;") else() set(PATH_SEP ":") endif() set(DOC_DATA_DIR "${CMAKE_CURRENT_BINARY_DIR}/qdoc-output") get_filename_component(ROOT ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY) set(TS_ROOT "${ROOT}/PySide6") file(REMOVE ${CMAKE_CURRENT_LIST_DIR}/pyside.qdocconf ${CMAKE_CURRENT_LIST_DIR}/pyside.qdocconf.in) # We need to find the interpreter when running this only # for a rst_build_docs case, and not a full doc build if (NOT FULLDOCSBUILD) find_package(Python COMPONENTS Interpreter) set(PYTHON_EXECUTABLE ${Python_EXECUTABLE}) endif() if (QT_SRC_DIR) file(REAL_PATH ${QT_SRC_DIR}/.. QT_ROOT_PATH) else() set(QT_ROOT_PATH "") endif() if(PYSIDE_IS_CROSS_BUILD) set(python_executable "${QFP_PYTHON_HOST_PATH}") else() set(python_executable "${PYTHON_EXECUTABLE}") endif() if (FULLDOCSBUILD) # Fetch and transform the snippets from Qt set(SNIPPETS_TOOL "${CMAKE_CURRENT_SOURCE_DIR}/../../../tools/snippets_translate/main.py") set(SNIPPETS_TARGET ${CMAKE_CURRENT_BINARY_DIR}/rst/codesnippets) # Note QT_SRC_DIR points to 'qtbase', # so we use the general SRC directory to copy all the other snippets add_custom_target("snippets_translate" DEPENDS "${SNIPPETS_TARGET}") add_custom_command(OUTPUT "${SNIPPETS_TARGET}" COMMAND ${python_executable} ${SNIPPETS_TOOL} --qt ${QT_ROOT_PATH} --target ${SNIPPETS_TARGET} -w WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} COMMENT "Fetching and converting snippets...") endif() # Generate example gallery set(EXAMPLE_TOOL_TARGET "${CMAKE_CURRENT_BINARY_DIR}/rst/examples") set(EXAMPLE_TOOL_OPTIONS --target "${EXAMPLE_TOOL_TARGET}") if (QUIET_BUILD) list(APPEND EXAMPLE_TOOL_OPTIONS "-q") endif() set(EXAMPLE_TOOL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../tools/example_gallery/main.py") add_custom_target("example_gallery" DEPENDS "${EXAMPLE_TOOL_TARGET}") add_custom_command(OUTPUT "${EXAMPLE_TOOL_TARGET}" COMMAND ${python_executable} ${EXAMPLE_TOOL_DIR} ${EXAMPLE_TOOL_OPTIONS} WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} COMMENT "Generating example gallery...") set(SHIBOKEN_INTERSPHINX_FILE "${ROOT}/pyside6/shiboken6/objects.inv") set(HAS_WEBENGINE_WIDGETS 0) set(SKIP_SPHINX_WARNINGS 1) if (FULLDOCSBUILD) set(SKIP_SPHINX_WARNINGS 0) set(SHIBOKEN_INTERSPHINX_FILE "${CMAKE_BINARY_DIR}/doc/html/shiboken6/doc/html/objects.inv") # For Qt modules that are part of the documentation build: # - Configure the module docconf file # - Write shiboken header consisting of pyside6_global.h and module includes # - Build include path for qdoc for shiboken # The last element of the include list is the mkspec directory containing qplatformdefs.h list(GET Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS -1 mkspecInclude) configure_file("pyside-config.qdocconf.in" "${CMAKE_CURRENT_LIST_DIR}/pyside-config.qdocconf" @ONLY) file(READ "${pyside6_BINARY_DIR}/pyside6_global.h" docHeaderContents) file(READ "typesystem_doc.xml.in" typeSystemDocXmlContents) foreach(moduleIn ${all_module_shortnames}) string(TOLOWER "${moduleIn}" lowerModuleIn) set(docConf "${CMAKE_CURRENT_LIST_DIR}/qtmodules/pyside-qt${lowerModuleIn}.qdocconf.in") if(EXISTS "${docConf}") string(REGEX REPLACE "(^.*)\.in" "\\1" OUTFILE ${docConf}) get_filename_component(BASENAME ${OUTFILE} NAME) configure_file(${docConf} "${CMAKE_CURRENT_LIST_DIR}/qtmodules/${BASENAME}" @ONLY) file(APPEND "pyside.qdocconf.in" "\@CMAKE_CURRENT_LIST_DIR\@/qtmodules/${BASENAME}\n") # Handle docconf files in Qt that contain multiple modules if ("${moduleIn}" STREQUAL "3DExtras") set(modules 3DCore 3DRender 3DInput 3DLogic 3DAnimation "${moduleIn}") elseif ("${moduleIn}" STREQUAL "OpenGL") set(modules "${moduleIn}" OpenGLWidgets) elseif ("${moduleIn}" STREQUAL "QuickWidgets") set(modules Qml Quick "${moduleIn}") elseif ("${moduleIn}" STREQUAL "MultimediaWidgets") set(modules Multimedia "${moduleIn}") elseif ("${moduleIn}" STREQUAL "Scxml") set(modules StateMachine "${moduleIn}") elseif ("${moduleIn}" STREQUAL "Svg") set(modules "${moduleIn}" SvgWidgets) elseif ("${moduleIn}" STREQUAL "WebEngineWidgets") set(modules WebEngineCore WebEngineWidgets WebEngineQuick "${moduleIn}") set(HAS_WEBENGINE_WIDGETS 1) else() set(modules "${moduleIn}") endif() foreach(module ${modules}) string(TOLOWER "${module}" lowerModule) # -- @TODO fix this for macOS frameworks. file(APPEND "${CMAKE_CURRENT_LIST_DIR}/pyside-config.qdocconf" " -I${QT_INCLUDE_DIR}/Qt${module} \\\n" " -I${QT_INCLUDE_DIR}/Qt${module}/${Qt${QT_MAJOR_VERSION}Core_VERSION} \\\n" " -I${QT_INCLUDE_DIR}/Qt${module}/${Qt${QT_MAJOR_VERSION}Core_VERSION}/Qt${module} \\\n") set(globalHeader "Qt${module}") set(docHeaderContents "${docHeaderContents}\n#include ") set(typeSystemDocXmlContents "${typeSystemDocXmlContents}\n") endforeach() endif() endforeach() set(typeSystemDocXmlContents "${typeSystemDocXmlContents}\n\n") file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/typesystem_doc.xml" "${typeSystemDocXmlContents}") set(docHeader "${pyside6_BINARY_DIR}/qdoc.h") file(WRITE ${docHeader} "${docHeaderContents}") configure_file("pyside.qdocconf.in" "pyside.qdocconf" @ONLY) set(QDOC_TYPESYSTEM_PATH "${pyside6_SOURCE_DIR}${PATH_SEP}${pyside6_BINARY_DIR}") if(NOT qdoc_binary) message(FATAL_ERROR "No qdoc binary was found which full documentation generation requires. " "Please either add qdoc to PATH or specify the QDOC_EXECUTABLE variable." ) endif() add_custom_target(qdoc DEPENDS "${DOC_DATA_DIR}/webxml/qtcore-index.webxml") add_custom_command(OUTPUT "${DOC_DATA_DIR}/webxml/qtcore-index.webxml" # Use dummy Qt version information, QDoc needs it but has no effect on WebXML output COMMAND ${CMAKE_COMMAND} -E env BUILDDIR=${CMAKE_CURRENT_LIST_DIR}/src QT_INSTALL_DOCS=${QT_SRC_DIR}/doc QT_VERSION=${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}.${QT_VERSION_PATCH} QT_VER=${QT_VERSION_MAJOR}.${QT_VERSION_MINOR} QT_VERSION_TAG=${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}.${QT_VERSION_PATCH} "${qdoc_binary}" pyside.qdocconf -single-exec -installdir ${DOC_DATA_DIR} -outputdir ${DOC_DATA_DIR} COMMENT "Running qdoc against Qt source code...") endif() add_custom_target(apidoc COMMAND ${SHIBOKEN_PYTHON_INTERPRETER} ${SPHINX_BUILD} -b ${DOC_OUTPUT_FORMAT} -j auto ${CMAKE_CURRENT_BINARY_DIR}/rst html COMMENT "Generating PySide htmls..." ) # create a custom commands to copy the shiboken docs # and generate offline help based on the output format. if(DOC_OUTPUT_FORMAT STREQUAL "html") add_custom_command(TARGET apidoc POST_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/html/shiboken6 COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_BINARY_DIR}/../../shiboken6/doc/html ${CMAKE_CURRENT_BINARY_DIR}/html/shiboken6 COMMENT "Copying Shiboken docs..." VERBATIM) else() if(qhelpgenerator_binary) message(STATUS "qhelpgenerator - found") # Python script that will be called to update the QHP set(PATCH_QHP_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/../../shiboken6/doc/scripts/patch_qhp.py") file(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR}/html/PySide.qhp QHP_FILE) add_custom_command(TARGET apidoc POST_BUILD COMMAND ${python_executable} ${PATCH_QHP_SCRIPT} -f ${QHP_FILE} -v pyside6 COMMAND "${qhelpgenerator_binary}" ${QHP_FILE} COMMENT "Generating QCH from a QHP file..." VERBATIM ) else() message(WARNING "qhelpgenerator - not found! qch generation disabled") endif() endif() # create conf.py based on conf.py.in configure_file("conf.py.in" "rst/conf.py" @ONLY) set(CODE_SNIPPET_ROOT "${CMAKE_CURRENT_BINARY_DIR}/rst/codesnippets") add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/rst/PySide6/QtCore/index.rst" COMMAND Shiboken6::shiboken6 --generator-set=qtdoc ${docHeader} --enable-pyside-extensions --include-paths="${QT_INCLUDE_DIR}${PATH_SEP}${pyside6_SOURCE_DIR}${PATH_SEP}${TS_ROOT}" --api-version=${SUPPORTED_QT_VERSION} --typesystem-paths="${QDOC_TYPESYSTEM_PATH}" --library-source-dir=${QT_SRC_DIR} --documentation-data-dir=${DOC_DATA_DIR}/webxml --output-directory=${CMAKE_CURRENT_BINARY_DIR}/rst --documentation-code-snippets-dir=${CODE_SNIPPET_ROOT} --snippets-path-rewrite=${QT_ROOT_PATH}:${CODE_SNIPPET_ROOT} --documentation-extra-sections-dir=${CMAKE_CURRENT_BINARY_DIR}/rst/extras --additional-documentation=${CMAKE_CURRENT_BINARY_DIR}/rst/additionaldocs.lst ${CMAKE_CURRENT_BINARY_DIR}/typesystem_doc.xml WORKING_DIRECTORY ${${module}_SOURCE_DIR} COMMENT "Running generator to generate documentation...") add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/rst/extras" COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/rst COMMENT "Copying docs...") add_custom_target("doc_copy" DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/rst/extras") add_custom_target("docrsts" DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/rst/PySide6/QtCore/index.rst") add_custom_target("licensedocrsts" COMMAND ${python_executable} ${CMAKE_CURRENT_LIST_DIR}/qtattributionsscannertorst.py ${CMAKE_CURRENT_LIST_DIR}/../../.. ${CMAKE_CURRENT_BINARY_DIR}/rst/licenses.rst COMMENT "Creating 3rdparty license documentation..." ) add_dependencies(docrsts example_gallery) if (FULLDOCSBUILD) add_dependencies(apidoc docrsts licensedocrsts) add_dependencies(licensedocrsts docrsts) add_dependencies(docrsts doc_copy qdoc snippets_translate) endif() #install files add_custom_target(apidocinstall COMMAND mkdir -p ${CMAKE_INSTALL_PREFIX}/share/doc/PySide6-${BINDING_API_VERSION} && cp -rv ${CMAKE_CURRENT_BINARY_DIR}/html/* ${CMAKE_INSTALL_PREFIX}/share/doc/PySide-${BINDING_API_VERSION} ) add_dependencies(apidocinstall apidoc)