Help: Add preset role

Add a new CMake domain role for referencing fields in CMake presets.
This has two main purposes. First, it replaces generic references (which
were excessively long and required explicit titles) and acts as an
improved version of the `ref` role by allowing the always-present
`CMakePresets.` prefix to be elided. Second, unlike generic references
which silently degrade to broken links that are only caught by
`linkcheck`, broken references are flagged immediately in regular Sphinx
builds. Therefore, this both improves presentation by bringing line
lengths back under control, and reduces errors by making bad references
immediately detectable.

There is also a small change in rendering, as field references are now
rendered as literals. This is consistent with how fields are mentioned
in prose when they are not linked.
This commit is contained in:
Matthew Woehlke
2026-04-08 12:14:41 -04:00
parent f26e9fcbae
commit 46ede9b46d
3 changed files with 43 additions and 36 deletions

View File

@@ -377,14 +377,10 @@ they were added and a summary of the new features and changes is given below.
`Build <Build Preset_>`_, and `Test Presets <Test Preset_>`_.
* Changes to `Configure Presets <Configure Preset_>`_
* The `installDir <CMakePresets.configurePresets.installDir_>`_ field was
added.
* The `toolchainFile <CMakePresets.configurePresets.toolchainFile_>`_
field was added.
* The `binaryDir <CMakePresets.configurePresets.binaryDir_>`_ field is
now optional.
* The `generator <CMakePresets.configurePresets.generator_>`_ field is
now optional.
* The :preset:`configurePresets.installDir` field was added.
* The :preset:`configurePresets.toolchainFile` field was added.
* The :preset:`configurePresets.binaryDir` field is now optional.
* The :preset:`configurePresets.generator` field is now optional.
* Changes to `Macro Expansion`_
@@ -398,9 +394,7 @@ they were added and a summary of the new features and changes is given below.
``CMakePresets.json`` and ``CMakeUserPresets.json``.
* Changes to `Build Presets <Build Preset_>`_
* The
`resolvePackageReferences <CMakePresets.buildPresets.resolvePackageReferences_>`_
field was added.
* The :preset:`buildPresets.resolvePackageReferences` field was added.
* Changes to `Macro Expansion`_
@@ -411,9 +405,8 @@ they were added and a summary of the new features and changes is given below.
* Changes to `Test Presets <Test Preset_>`_
* The `testOutputTruncation <CMakePresets.testPresets.output.testOutputTruncation_>`_
field was added to the `output <CMakePresets.testPresets.output_>`_
object.
* The :preset:`testPresets.output.testOutputTruncation` field was added
to the :preset:`testPresets.output` object.
* Changes to `Macro Expansion`_
@@ -426,16 +419,15 @@ they were added and a summary of the new features and changes is given below.
* `Workflow Presets <Workflow Preset_>`_ were added.
* Changes to `Test Presets <Test Preset_>`_
* The `outputJUnitFile <CMakePresets.testPresets.output.outputJUnitFile_>`_
field was added to the `output <CMakePresets.testPresets.output_>`_
object.
* The :preset:`testPresets.output.outputJUnitFile` field was added to the
:preset:`testPresets.output` object.
``7``
.. versionadded:: 3.27
* Changes to `Configure Presets <Configure Preset_>`_
* The `trace <CMakePresets.configurePresets.trace_>`_ field was added.
* The :preset:`configurePresets.trace` field was added.
* Changes to `Includes`_
@@ -444,8 +436,7 @@ they were added and a summary of the new features and changes is given below.
``8``
.. versionadded:: 3.28
* The `$schema <CMakePresets.$schema_>`_ field was added to the root
object.
* The :preset:`$schema` field was added to the root object.
``9``
.. versionadded:: 3.30
@@ -461,17 +452,15 @@ they were added and a summary of the new features and changes is given below.
throughout ``CMakePresets.json`` and ``CMakeUserPresets.json``.
* Changes to `Configure Presets <Configure Preset_>`_:
* The `graphviz <CMakePresets.configurePresets.graphviz_>`_ field was
added.
* The :preset:`configurePresets.graphviz` field was added.
``11``
.. versionadded:: 4.3
* Changes to `Test Presets <Test Preset_>`_
* The `jobs <CMakePresets.testPresets.execution.jobs_>`_ field now
accepts an empty string representing
:ctest-option:`--parallel` with ``<jobs>`` omitted.
* The :preset:`testPresets.execution.jobs` field now accepts an empty
string representing :ctest-option:`--parallel` with ``<jobs>`` omitted.
``12``
.. versionadded:: 4.4
@@ -485,8 +474,8 @@ they were added and a summary of the new features and changes is given below.
* Changes to `Test Presets <Test Preset_>`_
* The `testPassthroughArguments <CMakePresets.testPresets.execution.testPassthroughArguments_>`_
field was added to forward arguments to test executables.
* The :preset:`testPresets.execution.testPassthroughArguments` field was
added to forward arguments to test executables.
Schema
======

View File

@@ -60,6 +60,5 @@ See Also
* The :option:`--install-prefix <cmake --install-prefix>` option.
* The :genex:`$<INSTALL_PREFIX>` generator expression.
* The :ref:`installDir <CMakePresets.configurePresets.installDir>` field in
CMake configure presets.
* The :preset:`configurePresets.installDir` field in CMake configure presets.
* The :variable:`CPACK_PACKAGING_INSTALL_PREFIX` variable.

View File

@@ -574,6 +574,8 @@ class CMakeXRefRole(CMakeReferenceRole[XRefRole]):
m = CMakeXRefRole._re_guide.match(text)
if m:
text = f'{m.group(2)} <{text}>'
elif typ == 'cmake:preset':
text = f'CMakePresets.{text}'
return super().__call__(typ, rawtext, text, *args, **kwargs)
# We cannot insert index nodes using the result_nodes method
@@ -703,6 +705,7 @@ class CMakeDomain(Domain):
'prop_test': CMakeXRefRole(),
'prop_tgt': CMakeXRefRole(),
'manual': CMakeXRefRole(),
'preset': CMakeXRefRole(lowercase=True, warn_dangling=True),
# Roles for program-specific command-line options without the program
# name (which add the name to form the ref).
'cmake-option': CMakeOptionXRefRole('cmake'),
@@ -742,13 +745,29 @@ class CMakeDomain(Domain):
targetid = f'{typ}:{target}'
obj = self.data['objects'].get(targetid)
if obj is None and typ == 'command':
# If 'command(args)' wasn't found, try just 'command'.
# TODO: remove this fallback? warn?
# logger.warning(f'no match for {targetid}')
command = target.split('(')[0]
targetid = f'{typ}:{command}'
obj = self.data['objects'].get(targetid)
if obj is None:
if typ == 'command':
# If 'command(args)' wasn't found, try just 'command'.
# TODO: remove this fallback? warn?
# logger.warning(f'no match for {targetid}')
command = target.split('(')[0]
targetid = f'{typ}:{command}'
obj = self.data['objects'].get(targetid)
elif typ == 'preset':
# Preset references are really just references to plain old
# explicit targets.
labels = env.get_domain('std').labels
docname, labelid, sectname = labels.get(target, ('', '', ''))
if not docname:
return None
return make_refnode(builder, fromdocname, docname, labelid,
nodes.literal('', sectname), target)
import sys
print(typ, target, node, file=sys.stderr)
print(docname, labelid, sectname, file=sys.stderr)
if obj is None:
# TODO: warn somehow?