Введение в QDoc
QDoc — это инструмент, используемый разработчиками Qt для генерации документации для программных проектов. Он работает, извлекая комментарии QDoc из исходных файлов проекта, а затем форматируя эти комментарии в виде HTML-страниц или документов DITA XML. QDoc находит комментарии QDoc в .cpp файлах и в .qdoc файлах. QDoc не ищет комментарии QDoc в .h файлах. Комментарий QDoc всегда начинается с восклицательного знака (!)). Например:
/ *!
\class QObject
\brief The QObject class is the base class of all Qt objects.
\ingroup objectmodel
\reentrant
QObject is the heart of the Qt \l{Object Model}. The
central feature in this model is a very powerful mechanism
for seamless object communication called \l{signals and
slots}. You can connect a signal to a slot with connect()
and destroy the connection with disconnect(). To avoid
never ending notification loops you can temporarily block
signals with blockSignals(). The protected functions
connectNotify() and disconnectNotify() make it possible to
track connections.
QObjects organize themselves in \l {Object Trees &
Ownership} {object trees}. When you create a QObject with
another object as parent, the object will automatically
add itself to the parent's \c children() list. The parent
takes ownership of the object. It will automatically
delete its children in its destructor. You can look for an
object by name and optionally type using findChild() or
findChildren().
Every object has an objectName() and its class name can be
found via the corresponding metaObject() (see
QMetaObject::className()). You can determine whether the
object's class inherits another class in the QObject
inheritance hierarchy by using the \c inherits() function.
....
* / По комментарию QDoc выше, QDoc генерирует страницу справки класса QObject.
В этом руководстве объясняется, как использовать команды QDoc в комментариях QDoc для вставки хорошей документации в ваши исходные файлы. Также в нём объясняется, как создать файл конфигурации QDoc, который вы передадите QDoc в командной строке.
Запуск QDoc
Имя программы QDoc — qdoc. Чтобы запустить qdoc из командной строки, укажите имя файла конфигурации:
$ ../../bin/qdoc ./config.qdocconf
QDoc распознаёт суффикс .qdocconf как файл конфигурации QDoc. В файле конфигурации вы указываете QDoc, где найти исходные файлы проекта, заголовочные файлы и .qdoc файлы. Также в нём вы указываете QDoc, какой тип выходных данных сгенерировать (HTML, DITA XML,...) и куда поместить сгенерированную документацию. Файл конфигурации также содержит другую информацию для QDoc.
См. Файл конфигурации QDoc для инструкций по настройке файла конфигурации QDoc.
Запуск QDoc в режиме единого выполнения
Начиная с Qt 5.5, доступен новый способ запуска QDoc, который сокращает время генерации документации Qt5 до 90%. Новый способ запуска QDoc — это режим единого выполнения. Режим единого выполнения в настоящее время недоступен в системе сборки Qt5, которая всё ещё использует режим стандартного выполнения. Режим единого выполнения доступен только при самостоятельном запуске QDoc, что вам часто потребуется при документировании своего модуля и интеграции вашей документации с другими модулями Qt.
Чтобы запустить QDoc в режиме единого выполнения, добавьте -single-exec в командную строку и передайте QDoc главный файл qdocconf , который просто представляет собой список путей к файлам qdocconf для всех модулей Qt5. Например:
/Users/me/qt5/qtbase/bin/qdoc -outputdir /Users/me/qt5/qtbase/doc -installdir /Users/me/qt5/qtbase/doc /Users/me/qt5/master.qdocconf -single-exec
Файл qdocconf, master.qdocconf, просто перечисляет файлы qdocconf для всех модулей Qt5, которые должны быть обработаны:
/Users/me/qt5/qtbase/src/corelib/doc/qtcore.qdocconf /Users/me/qt5/qtbase/src/network/doc/qtnetwork.qdocconf /Users/me/qt5/qtbase/src/sql/doc/qtsql.qdocconf /Users/me/qt5/qtbase/src/xml/doc/qtxml.qdocconf /Users/me/qt5/qtbase/src/testlib/doc/qttestlib.qdocconf /Users/me/qt5/qtbase/src/concurrent/doc/qtconcurrent.qdocconf /Users/me/qt5/qtbase/src/gui/doc/qtgui.qdocconf /Users/me/qt5/qtbase/src/platformheaders/doc/qtplatformheaders.qdocconf /Users/me/qt5/qtbase/src/widgets/doc/qtwidgets.qdocconf /Users/me/qt5/qtbase/src/opengl/doc/qtopengl.qdocconf /Users/me/qt5/qtbase/src/printsupport/doc/qtprintsupport.qdocconf /Users/me/qt5/qtbase/src/tools/qdoc/doc/config/qdoc.qdocconf /Users/me/qt5/qtbase/qmake/doc/qmake.qdocconf /Users/me/qt5/qtsvg/src/svg/doc/qtsvg.qdocconf /Users/me/qt5/qtxmlpatterns/src/xmlpatterns/doc/qtxmlpatterns.qdocconf /Users/me/qt5/qtdeclarative/src/qml/doc/qtqml.qdocconf /Users/me/qt5/qtdeclarative/src/quick/doc/qtquick.qdocconf /Users/me/qt5/qtquickcontrols/src/controls/doc/qtquickcontrols.qdocconf /Users/me/qt5/qtquickcontrols/src/layouts/doc/qtquicklayouts.qdocconf /Users/me/qt5/qtquickcontrols/src/dialogs/doc/qtquickdialogs.qdocconf /Users/me/qt5/qtmultimedia/src/multimedia/doc/qtmultimedia.qdocconf /Users/me/qt5/qtmultimedia/src/multimediawidgets/doc/qtmultimediawidgets.qdocconf /Users/me/qt5/qtactiveqt/src/activeqt/doc/activeqt.qdocconf /Users/me/qt5/qtsensors/src/sensors/doc/qtsensors.qdocconf /Users/me/qt5/qtwebkit/Source/qtwebkit.qdocconf /Users/me/qt5/qttools/src/assistant/help/doc/qthelp.qdocconf /Users/me/qt5/qttools/src/assistant/assistant/doc/qtassistant.qdocconf /Users/me/qt5/qttools/src/designer/src/uitools/doc/qtuitools.qdocconf /Users/me/qt5/qttools/src/designer/src/designer/doc/qtdesigner.qdocconf /Users/me/qt5/qttools/src/linguist/linguist/doc/qtlinguist.qdocconf /Users/me/qt5/qtwebkit-examples/doc/qtwebkitexamples.qdocconf /Users/me/qt5/qtimageformats/src/imageformats/doc/qtimageformats.qdocconf /Users/me/qt5/qtgraphicaleffects/src/effects/doc/qtgraphicaleffects.qdocconf /Users/me/qt5/qtscript/src/script/doc/qtscript.qdocconf /Users/me/qt5/qtscript/src/scripttools/doc/qtscripttools.qdocconf /Users/me/qt5/qtserialport/src/serialport/doc/qtserialport.qdocconf /Users/me/qt5/qtdoc/doc/config/qtdoc.qdocconf
Почему режим стандартного выполнения медленный
В настоящее время система сборки Qt5 не использует режим единого выполнения QDoc для генерации документации Qt5. Она запускает QDoc в режиме стандартного выполнения. Режим стандартного выполнения возник потому, что это был самый простой способ адаптировать QDoc Qt4 для обработки модульной структуры Qt в Qt5. В Qt4 QDoc выполнялся один раз над всеми исходными кодами Qt4 для генерации HTML-документации для Qt. Во время генерации документации Qt, QDoc Qt4 также генерировал индексный файл для Qt. Этот индексный файл предназначался для использования в последующих запусках QDoc для генерации HTML-документации для других программных библиотек/продуктов, основанных на Qt. Индексный файл Qt позволял QDoc связывать документацию, написанную для этих других библиотек/продуктов, с документацией Qt4.
Когда появился Qt5, Qt был разделен на модули. С тех пор было добавлено множество новых модулей в Qt. По состоянию на версию 5.5 в Qt5 насчитывается более 40 отдельных модулей, каждый со своей документацией, которая ссылается на (зависит от) документацию других модулей Qt.
В режиме стандартного выполнения QDoc выполняется дважды для каждого модуля. Первый запуск QDoc для определённого модуля Qt анализирует все исходные файлы модуля, а затем использует эту информацию для генерации индексного файла модуля. Это называется фазой подготовки, потому что она подготавливает индексный файл модуля. Второй запуск QDoc для модуля также анализирует все исходные файлы модуля и генерирует страницы документации модуля. Это называется фазой генерации, потому что она генерирует документацию модуля.
Документация модуля, скорее всего, будет содержать HTML-ссылки на документацию одного или нескольких других модулей Qt. Например, большинство модулей Qt5 содержат ссылки на документацию в QtCore. Когда модуль Qt содержит ссылки на документацию других модулей Qt, этот модуль считается зависимым от этих других модулей Qt. Поэтому, когда QDoc выполняет фазу генерации для этого модуля, ему необходимо загрузить индексные файлы этих модулей, чтобы он мог создать эти элементы.
Таким образом, при генерации документации Qt системой сборки Qt QDoc сначала выполняется один раз для каждого модуля, чтобы выполнить фазу подготовки для генерации всех индексных файлов. Затем QDoc выполняется один раз для каждого модуля для выполнения фазы генерации, где он использует зависимые индексные файлы для генерации документации модуля, включая любые межмодульные ссылки, которые он находит. Каждое выполнение QDoc, как фаза подготовки, так и фаза генерации, анализирует все исходные файлы, которые включены в модуль, а в фазе генерации также анализирует индексные файлы зависимых модулей. Ничто не сохраняется и не может быть сохранено между запусками QDoc.
Почему режим единого выполнения намного быстрее
Как следует из названия, режим единого выполнения использует один процесс QDoc для генерации всей документации Qt5. Один процесс QDoc всё ещё выполняет фазу подготовки для каждого модуля, а затем фазу генерации для каждого модуля, но есть несколько отличий. Он начинает с чтения главного файла qdocconf. Затем он читает каждый файл qdocconf в главном списке и выполняет фазу подготовки для каждого модуля. Во время фазы подготовки анализируются все исходные файлы модуля для построения синтаксического дерева модуля. Затем генерируется индексный файл модуля, хотя QDoc не будет повторно читать индексные файлы в фазе генерации. Важное различие заключается в том, что синтаксическое дерево модуля сохраняется после генерации индексного файла, так что после выполнения фазы подготовки для всех модулей QDoc всё ещё имеет все построенные синтаксические деревья.
Затем QDoc обрабатывает каждый модуль снова для фазы генерации. Но теперь QDoc не нужно повторно анализировать исходные файлы каждого модуля, потому что синтаксическое дерево модуля всё ещё находится в памяти. QDoc также не нужно повторно читать индексные файлы зависимых модулей, опять же потому, что он всё ещё имеет синтаксические деревья этих модулей в памяти. Осталось только пройтись по синтаксическому дереву каждого модуля для генерации страниц документации.
Таким образом, QDoc анализирует каждый исходный файл один раз и только один раз и не нуждается в чтении индексных файлов. Именно это делает режим единого выполнения намного быстрее, чем режим стандартного выполнения. Ожидается, что система сборки Qt в конечном итоге будет запускать QDoc в режиме единого выполнения. Однако могут потребоваться изменения в главном файле qdocconf, поэтому описанный выше метод запуска QDoc в режиме единого выполнения может потребоваться изменить. Следите за обновлениями.
Как работает QDoc
QDoc начинает с чтения файла конфигурации, указанного в командной строке. Он сохраняет все переменные из файла конфигурации для дальнейшего использования. Одна из первых переменных, которую он использует, это outputformats. Эта переменная указывает QDoc, какие генераторы выходных данных будут запущены. Значение по умолчанию — HTML, поэтому если вы не зададите outputformats в файле конфигурации, QDoc сгенерирует HTML-выходные данные. Это обычно то, что вам нужно, но вы также можете указать DITAXML, чтобы получить выходные данные в формате DITA XML вместо этого.
Далее QDoc использует значения переменной headerdirs и/или переменной headers, чтобы найти и проанализировать все заголовочные файлы вашего проекта. QDoc не сканирует заголовочные файлы на наличие комментариев QDoc. Он анализирует заголовочные файлы, чтобы построить главное дерево всех элементов, которые должны быть задокументированы, то есть элементов, для которых QDoc должен найти комментарии QDoc.
После анализа всех заголовочных файлов и построения главного дерева элементов, которые должны быть задокументированы, QDoc использует значение переменной sourcedirs и/или значение переменной sources для поиска и анализа всех .cpp и .qdoc файлов вашего проекта. Это те файлы, которые QDoc сканирует на наличие комментариев QDoc. Помните, что комментарий QDoc начинается с восклицательного знака: /*! .
Для каждого найденного комментария QDoc ищет элемент в главном дереве, где должна быть размещена документация. Затем он интерпретирует команды qdoc в комментарии и сохраняет интерпретированные команды и текст комментария в узле дерева для элемента.
Наконец, QDoc проходит по главному дереву. Для каждого узла, если в узле есть сохранённая документация, QDoc вызывает генератор выходных данных, указанный переменной outputformats, для форматирования и записи документации в директорию, указанную в файле конфигурации в переменной outputdir.
Типы команд
QDoc интерпретирует три типа команд:
Команды темы идентифицируют элемент, который вы документируете, например, класс C++, функцию, тип или дополнительную страницу текста, которая не отображается на основе элемента C++.
Команды контекста сообщают QDoc, как документ, который документируется, связан с другими документированными элементами, например, ссылки на следующую и предыдущую страницы, включение в группы страниц или модули библиотек. Команды контекста также могут предоставить информацию об элементе, который документируется, которую QDoc не может получить из исходных файлов, например, является ли элемент потокобезопасным, является ли это перегруженной или переопределённой функцией или была ли она устаревшей.
Команды разметки сообщают QDoc, как следует отображать элементы текста и изображения в документе, или о структуре оглавления документа.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.12/01-qdoc-manual.html