mirror of
https://github.com/Kitware/CMake.git
synced 2026-06-24 08:47:59 +00:00
Help: Add developer documentation for new diagnostics
Add a developer-targeted document explaining the basics of how to use CMake 4.4's new diagnostic framework.
This commit is contained in:
@@ -41,12 +41,14 @@ CMake developer documentation is provided by the following documents:
|
||||
* The `CMake Testing Guide`_.
|
||||
* The `CMake Experimental Features Guide`_.
|
||||
* The `CMake Debugging Guide`_.
|
||||
* The `CMake Diagnostics Guide`_.
|
||||
|
||||
.. _`CMake Source Code Guide`: source.rst
|
||||
.. _`CMake Documentation Guide`: documentation.rst
|
||||
.. _`CMake Testing Guide`: testing.rst
|
||||
.. _`CMake Experimental Features Guide`: experimental.rst
|
||||
.. _`CMake Debugging Guide`: debug.rst
|
||||
.. _`CMake Diagnostics Guide`: diagnostics.rst
|
||||
|
||||
Maintainer Documentation
|
||||
========================
|
||||
|
||||
157
Help/dev/diagnostics.rst
Normal file
157
Help/dev/diagnostics.rst
Normal file
@@ -0,0 +1,157 @@
|
||||
CMake Diagnostics Guide
|
||||
***********************
|
||||
|
||||
The following is a guide on how CMake should issue diagnostics.
|
||||
See documentation on `CMake Development`_ for more information.
|
||||
|
||||
.. _`CMake Development`: README.rst
|
||||
|
||||
TL;DR Porting Guide (from CMake < 4.4)
|
||||
======================================
|
||||
|
||||
I want to write ``IssueMessage(MessageType::AUTHOR_WARNING, ...``:
|
||||
Write ``IssueDiagnostic(cmDiagnostics::CMD_AUTHOR, ...`` instead.
|
||||
|
||||
I want to write ``IssueMessage(MessageType::DEPRECATION_WARNING, ...``:
|
||||
Write ``IssueDiagnostic(cmDiagnostics::CMD_DEPRECATED, ...`` instead.
|
||||
|
||||
I want to write ``IssueMessage(MessageType::AUTHOR_ERROR, ...``:
|
||||
No, you don't. Under the old system, there isn't a meaningful difference
|
||||
between ``AUTHOR_WARNING`` and ``AUTHOR_ERROR``; at least, not as arguments
|
||||
to ``IssueMessage``.
|
||||
|
||||
I want to write ``IssueMessage(MessageType::DEPRECATION_ERROR, ...``:
|
||||
See ``AUTHOR_ERROR``.
|
||||
|
||||
History
|
||||
=======
|
||||
|
||||
Prior to CMake 4.4, CMake did not have a formal system for issuing diagnostics.
|
||||
The messaging system had message types for author diagnostics and deprecation
|
||||
diagnostics which conflated category and severity. Worse, although these types
|
||||
*purported* to allow the caller to specify severity, this information is not
|
||||
actually honored. Other diagnostics existed which did not use these types.
|
||||
|
||||
More importantly, the mechanisms for managing severity differed depending on
|
||||
the diagnostic. Variables to control a diagnostic might be documented,
|
||||
undocumented, or non-existent. Spelling of command-line options to control
|
||||
diagnostics was inconsistent, as was the ability to make diagnostics fatal.
|
||||
Adding new categories required significant effort, as the logic to handle a
|
||||
diagnostic was bespoke at every layer.
|
||||
|
||||
CMake Diagnostic Framework
|
||||
==========================
|
||||
|
||||
CMake 4.4 introduced a structured framework for issuing and managing
|
||||
diagnostics. The ``cmDiagnostics.h`` header enumerates all available
|
||||
diagnostic categories. All code to manage diagnostics leverages either this
|
||||
table or helper code generated from the same, such that it is the *only*
|
||||
non-documentation location that needs to be updated to add a new diagnostic
|
||||
category. The framework is also responsible for determining the severity of a
|
||||
diagnostic, based on the combination of category defaults and user preferences,
|
||||
and for presenting the user with a consistent set of control mechanisms.
|
||||
|
||||
Numeric identifiers associated with diagnostic categories are only used
|
||||
internally and are never persisted. This means that numbers can be reassigned
|
||||
at any time. This also permits ensuring that numbers are consecutive, which
|
||||
allows iterating over all categories using a simple ``for`` loop. (Note that
|
||||
such loops will typically start from ``1``, not ``0``, as ``0`` is reserved
|
||||
for the 'NONE' category which is used primarily as a virtual parent.) Where
|
||||
necessary, macros provided by ``cmDiagnostics.h`` can generate code for each
|
||||
diagnostic category.
|
||||
|
||||
Refer to ``Help/manual/cmake-diagnostics.7.rst`` for user-facing documentation.
|
||||
|
||||
Issuing Diagnostics
|
||||
===================
|
||||
|
||||
Diagnostics are the CMake equivalent of compiler warnings, with categorization
|
||||
providing both additional information and additional response control to users.
|
||||
|
||||
Diagnostics are issued via the ``IssueDiagnostic`` method. This method is
|
||||
provided on various objects, with ``cmMakefile`` being the most prominent, and
|
||||
typically exists alongside an ``IssueMessage`` method. The latter is not
|
||||
deprecated, and should still be used to issue messages outside of the
|
||||
diagnostic categories, such as hard errors or informational messages.
|
||||
|
||||
The historic ``{AUTHOR,DEPRECATION}_{WARNING,ERROR}`` message types, however,
|
||||
have been removed. These are replaced by ``IssueDiagnostic`` and the
|
||||
``CMD_{AUTHOR,DEPRECATED}`` diagnostic categories. Because the methods have
|
||||
similar signatures, porting in many cases can be accomplished by replacing the
|
||||
method name and first argument (the former message type, newly the diagnostic
|
||||
category). For example, where prior versions of CMake wrote:
|
||||
|
||||
.. code:: c++
|
||||
|
||||
mf->IssueMessage(MessageType::AUTHOR_WARNING, ...);
|
||||
|
||||
CMake 4.4 and later should write:
|
||||
|
||||
.. code:: c++
|
||||
|
||||
mf->IssueDiagnostic(cmDiagnostics::CMD_AUTHOR, ...);
|
||||
|
||||
(Note that the ``"cmDiagnostics.h"`` header may need to be newly included.)
|
||||
|
||||
As previously mentioned, the purported severity was ignored by ``cmMessenger``,
|
||||
which instead used its own internal state to decide whether a message should
|
||||
be a warning or an error. This logic overrode the severity component of the
|
||||
message type as passed into the method. As a result, although the new method
|
||||
does not accept a severity, this is actually consistent with the historic
|
||||
behavior and does not represent any loss of functionality.
|
||||
|
||||
.. note::
|
||||
|
||||
When issuing diagnostics targeted at build-system authors, please consult the
|
||||
complete list of available diagnostics, as a more specific category may be
|
||||
available. In some cases, it may even make sense to add a new category.
|
||||
|
||||
Adding Diagnostic Categories
|
||||
============================
|
||||
|
||||
Adding new diagnostic categories involves four steps.
|
||||
|
||||
1. The new category must be added to ``cmDiagnostics.h``. The diagnostics
|
||||
table looks like this:
|
||||
|
||||
.. code:: c++
|
||||
|
||||
#define CM_FOR_EACH_DIAGNOSTIC_TABLE(ACTION, SELECT) \
|
||||
SELECT(ACTION, Warn, CMD_NONE, CMD_AUTHOR, 12) \
|
||||
SELECT(ACTION, Warn, CMD_AUTHOR, CMD_DEPRECATED, 1) \
|
||||
...
|
||||
|
||||
Add a new entry. All entries must begin with ``SELECT(ACTION,``. The
|
||||
second argument is the *default* state of the diagnostic and should
|
||||
typically be ``Warn``, but may be ``Ignore`` if the diagnostic should be
|
||||
opt-in. Defaulting to ``SendError`` would be exceptional, and defaulting
|
||||
to ``FatalError`` is not recommended under any circumstances. The third
|
||||
argument is the *parent* of the diagnostic (see below). The fourth is the
|
||||
actual name of the diagnostic. The fifth and final argument is the CMake
|
||||
preset version corresponding to the introduction of the argument, which
|
||||
should be the latest preset version as used by the version of CMake under
|
||||
development.
|
||||
|
||||
.. note::
|
||||
|
||||
In the event that the development version has not already introduced a
|
||||
new preset version, adding a new diagnostic will additionally require
|
||||
introducing a new preset version.
|
||||
|
||||
Diagnostics are hierarchical and **must** be listed in order of a
|
||||
depth-first search. (If you imagine the order of items in a typical tree
|
||||
view which has been fully expanded, that is depth-first order.) Each
|
||||
diagnostic has a direct parent. Recursive alterations to a diagnostic will
|
||||
also affect all descendant diagnostics.
|
||||
|
||||
2. A documentation page for the new diagnostic must be created under
|
||||
``Help/diagnostic``, and a link to the same added to the Diagnostics
|
||||
manual, ``Help/manual/cmake-diagnostics.7.rst``.
|
||||
|
||||
3. The new presets fields must be mentioned in the CMake presets version
|
||||
history, found at the bottom of ``Help/manual/cmake-presets.7.rst``. Note
|
||||
that the documentation of the fields themselves is generated.
|
||||
|
||||
4. The ``Utilities/Scripts/regenerate-presets.py`` script must be run to
|
||||
generate the updated presets schema and documentation. Don't forget to
|
||||
review and commit the changes made by this script.
|
||||
Reference in New Issue
Block a user