aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside6/doc/CMakeLists.txt
blob: f900b96ebbc94e48a0b9ba37ab79566018c6786b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
cmake_minimum_required(VERSION 3.16)
cmake_policy(VERSION 3.16)

project(doc)

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 (FULLDOCSBUILD)
    # Fetch and transform the snippets from Qt
    message(STATUS "Fetching and converting snippets")
    if ("${QT_SRC_DIR}" STREQUAL "")
        message(FATAL_ERROR "There is no value set on QT_SRC_DIR, the snippet conversion will fail")
    endif()
    set(PYSIDE_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../../../")
    set(SNIPPETS_TOOL "${CMAKE_CURRENT_SOURCE_DIR}/../../../tools/snippets_translate/main.py")
    # Note QT_SRC_DIR points to 'qtbase',
    # so we use the general SRC directory to copy all the other snippets
    execute_process(COMMAND ${PYTHON_EXECUTABLE} ${SNIPPETS_TOOL}
        --qt ${QT_SRC_DIR}/.. --pyside ${PYSIDE_ROOT} -w
        WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
        ERROR_VARIABLE SNIPPETS_ERROR)
    if (SNIPPETS_ERROR)
        message(FATAL_ERROR "The 'snippets_translate' tool failed: ${SNIPPETS_ERROR}")
    endif()
endif()

# Generate example gallery
message(STATUS "Generating example gallery")
if (QUIET_BUILD)
    set (EXAMPLE_TOOL_OPTIONS "-q")
endif()
set(EXAMPLE_TOOL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../tools/example_gallery/main.py")
execute_process(COMMAND ${PYTHON_EXECUTABLE} ${EXAMPLE_TOOL_DIR} ${EXAMPLE_TOOL_OPTIONS}
    WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})

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 <Qt${module}/${globalHeader}>")
                set(typeSystemDocXmlContents "${typeSystemDocXmlContents}\n<load-typesystem name=\"Qt${module}/typesystem_${lowerModule}.xml\" generate=\"yes\"/>")
            endforeach()
        endif()
    endforeach()

    set(typeSystemDocXmlContents "${typeSystemDocXmlContents}\n</typesystem>\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}")

    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 pyside.qdocconf -single-exec -installdir ${DOC_DATA_DIR} -outputdir ${DOC_DATA_DIR}
                       COMMENT "Running qdoc against Qt source code...")
endif()

# conditional tag for sphinx build
#string(JOIN "_" SPHINX_TAG ${DOC_OUTPUT_FORMAT} "format")
# Python script to replace the virtualFolder string in the QHP
set(py_cmd "
import fileinput
import re
try:
\tfor line in fileinput.input('html/PySide.qhp',inplace=True,backup='.bak'):
\t\tline_copy=line.strip()
\t\tif not line_copy: # check for empty line
\t\t\tcontinue
\t\tmatch=re.match('(^.*virtualFolder.)doc(.*$)',line)
\t\tif match:
\t\t\trepl=''.join([match.group(1),'pyside6',match.group(2)])
\t\t\tprint(line.replace(match.group(0),repl),end='')
\t\telse:
\t\t\tprint(line)
except:
\tpass\n")
file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/py_script.py CONTENT ${py_cmd})

add_custom_target(apidoc
                  COMMAND ${SHIBOKEN_PYTHON_INTERPRETER} ${SPHINX_BUILD} -b ${DOC_OUTPUT_FORMAT} ${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()
    file(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR}/html/PySide.qhp QHP_FILE)
    add_custom_command(TARGET apidoc POST_BUILD
            COMMAND ${PYTHON_EXECUTABLE} py_script.py
            COMMAND qhelpgenerator ${QHP_FILE}
            COMMENT "Generating QCH from a QHP file..."
            VERBATIM)
endif()

# create conf.py based on conf.py.in
configure_file("conf.py.in" "rst/conf.py" @ONLY)

add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/rst/PySide6/QtCore/index.rst"
                   COMMAND Shiboken6::shiboken6 --generator-set=qtdoc ${docHeader}
                           --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=${CMAKE_CURRENT_BINARY_DIR}/rst/codesnippets/doc/src/snippets${PATH_SEP}${CMAKE_CURRENT_BINARY_DIR}/rst/codesnippets/examples
                           --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/codesnippets"
                   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/codesnippets")

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..."
)

if (FULLDOCSBUILD)
    add_dependencies(apidoc docrsts licensedocrsts)
    add_dependencies(licensedocrsts docrsts)
    add_dependencies(docrsts doc_copy qdoc)
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)