Browse Source

Utilities/Sphinx: Add role and directive for 'genex' in CMake domain

This enables cross-reference syntax for CMake generator expressions:

    :genex:`SOME_GENEX`
    :genex:`$<SOME_GENEX>`
    :genex:`$<SOME_GENEX:...>`

and definition of CMake generator expressions via a directive:

    .. genex:: SOME_GENEX
    .. genex:: $<SOME_GENEX>
    .. genex:: $<SOME_GENEX:...>

It also adds generator expressions defined by the directive and by
`Help/genex/SOME_GENEX.rst` documents to the index.
Brad King 4 năm trước cách đây
mục cha
commit
7d498d6b43

+ 13 - 2
Help/dev/documentation.rst

@@ -136,6 +136,10 @@ documentation:
  A CMake native build system generator.
  See the `cmake(1)`_ command-line tool's ``-G`` option.
 
+``genex``
+ A CMake generator expression.
+ See the `cmake-generator-expressions(7)`_ manual.
+
 ``manual``
  A CMake manual page, like the `cmake(1)`_ manual.
 
@@ -169,10 +173,12 @@ which is expected to be of the form::
  -------------
 
 and to appear at or near the top of the ``.rst`` file before any other
-lines starting in a letter, digit, or ``<``.  If no such title appears
+lines starting in a letter, digit, ``<``, or ``$``.  If no such title appears
 literally in the ``.rst`` file, the object name is the ``<file-name>``.
 If a title does appear, it is expected that ``<file-name>`` is equal
-to ``<object-name>`` with any ``<`` and ``>`` characters removed.
+to ``<object-name>`` with any ``<`` and ``>`` characters removed,
+or in the case of a ``$<genex-name>`` or ``$<genex-name:...>``, the
+``genex-name``.
 
 Second, the CMake Domain provides directives to define objects inside
 other documents:
@@ -187,6 +193,10 @@ other documents:
 
   This indented block documents <envvar-name>.
 
+ .. genex:: <genex-name>
+
+  This indented block documents <genex-name>.
+
  .. variable:: <variable-name>
 
   This indented block documents <variable-name>.
@@ -197,6 +207,7 @@ the first approach above.
 .. _`Sphinx Domain`: http://sphinx-doc.org/domains.html
 .. _`cmake(1)`: https://cmake.org/cmake/help/latest/manual/cmake.1.html
 .. _`cmake-env-variables(7)`: https://cmake.org/cmake/help/latest/manual/cmake-env-variables.7.html
+.. _`cmake-generator-expressions(7)`: https://cmake.org/cmake/help/latest/manual/cmake-generator-expressions.7.html
 .. _`cmake-modules(7)`: https://cmake.org/cmake/help/latest/manual/cmake-modules.7.html
 .. _`cmake-policies(7)`: https://cmake.org/cmake/help/latest/manual/cmake-policies.7.html
 .. _`cmake-properties(7)`: https://cmake.org/cmake/help/latest/manual/cmake-properties.7.html

+ 3 - 2
Source/cmRST.cxx

@@ -25,7 +25,7 @@ cmRST::cmRST(std::ostream& os, std::string docroot)
   , Markup(MarkupNone)
   , Directive(DirectiveNone)
   , CMakeDirective("^.. (cmake:)?("
-                   "command|envvar|variable"
+                   "command|envvar|genex|variable"
                    ")::[ \t]+([^ \t\n]+)$")
   , CMakeModuleDirective("^.. cmake-module::[ \t]+([^ \t\n]+)$")
   , ParsedLiteralDirective("^.. parsed-literal::[ \t]*(.*)$")
@@ -37,7 +37,8 @@ cmRST::cmRST(std::ostream& os, std::string docroot)
   , NoteDirective("^.. note::[ \t]*(.*)$")
   , ModuleRST(R"(^#\[(=*)\[\.rst:$)")
   , CMakeRole("(:cmake)?:("
-              "command|cpack_gen|generator|variable|envvar|module|policy|"
+              "command|cpack_gen|generator|genex|"
+              "variable|envvar|module|policy|"
               "prop_cache|prop_dir|prop_gbl|prop_inst|prop_sf|"
               "prop_test|prop_tgt|"
               "manual"

+ 14 - 0
Tests/CMakeLib/testRST.expect

@@ -20,6 +20,12 @@ Environment variable ``SOME_ENV_VAR``.
 Environment variable ``some env var`` with space and target.
 Generator ``Some Generator`` with space.
 Generator ``Some Generator`` with space.
+Generator expression ``SOME_GENEX``.
+Generator expression ``$<SOME_GENEX>`` with brackets.
+Generator expression ``$<SOME_GENEX:...>`` with brackets and parameter.
+Generator expression ``some genex`` with space and target.
+Generator expression ``$<SOME_GENEX>`` with brackets, space, and target.
+Generator expression ``$<SOME_GENEX:...>`` with brackets, parameter, space, and target.
 Inline literal ``~!@#$%^&*( )_+-=\\[]{}'":;,<>.?/``.
 Inline link Link Text.
 Inline link Link Text <With \-escaped Brackets>.
@@ -56,6 +62,14 @@ Bracket Comment Content
 
    Environment variable other_var description.
 
+.. cmake:genex:: SOME_GENEX
+
+   Generator expression SOME_GENEX description.
+
+.. genex:: $<OTHER_GENEX>
+
+   Generator expression $<OTHER_GENEX> description.
+
 .. cmake:variable:: some_var
 
    Variable some_var description.

+ 14 - 0
Tests/CMakeLib/testRST.rst

@@ -27,6 +27,12 @@ Environment variable :envvar:`SOME_ENV_VAR`.
 Environment variable :envvar:`some env var <SOME_ENV_VAR>` with space and target.
 Generator :generator:`Some Generator` with space.
 Generator :cpack_gen:`Some Generator` with space.
+Generator expression :genex:`SOME_GENEX`.
+Generator expression :genex:`$<SOME_GENEX>` with brackets.
+Generator expression :genex:`$<SOME_GENEX:...>` with brackets and parameter.
+Generator expression :genex:`some genex <SOME_GENEX>` with space and target.
+Generator expression :genex:`$<SOME_GENEX> <SOME_GENEX>` with brackets, space, and target.
+Generator expression :genex:`$<SOME_GENEX:...> <SOME_GENEX>` with brackets, parameter, space, and target.
 Inline literal ``~!@#$%^&*( )_+-=\\[]{}'":;,<>.?/``.
 Inline link `Link Text <ExternalDest>`_.
 Inline link `Link Text \<With \\-escaped Brackets\> <ExternalDest>`_.
@@ -59,6 +65,14 @@ Inline literal ``__`` followed by inline link `Link Text <InternalDest_>`_.
 
    Environment variable other_var description.
 
+.. cmake:genex:: SOME_GENEX
+
+   Generator expression SOME_GENEX description.
+
+.. genex:: $<OTHER_GENEX>
+
+   Generator expression $<OTHER_GENEX> description.
+
 .. cmake:variable:: some_var
 
    Variable some_var description.

+ 19 - 2
Utilities/Sphinx/cmake.py

@@ -191,6 +191,7 @@ _cmake_index_objs = {
     'cpack_gen':  _cmake_index_entry('cpack generator'),
     'envvar':     _cmake_index_entry('envvar'),
     'generator':  _cmake_index_entry('generator'),
+    'genex':      _cmake_index_entry('genex'),
     'guide':      _cmake_index_entry('guide'),
     'manual':     _cmake_index_entry('manual'),
     'module':     _cmake_index_entry('module'),
@@ -224,7 +225,7 @@ class CMakeTransform(Transform):
         self.titles = {}
 
     def parse_title(self, docname):
-        """Parse a document title as the first line starting in [A-Za-z0-9<]
+        """Parse a document title as the first line starting in [A-Za-z0-9<$]
            or fall back to the document basename if no such line exists.
            The cmake --help-*-list commands also depend on this convention.
            Return the title or False if the document file does not exist.
@@ -239,7 +240,7 @@ class CMakeTransform(Transform):
                 title = False
             else:
                 for line in f:
-                    if len(line) > 0 and (line[0].isalnum() or line[0] == '<'):
+                    if len(line) > 0 and (line[0].isalnum() or line[0] == '<' or line[0] == '$'):
                         title = line.rstrip()
                         break
                 f.close()
@@ -260,6 +261,10 @@ class CMakeTransform(Transform):
             if objtype == 'command':
                 targetname = title.lower()
             else:
+                if objtype == 'genex':
+                    m = CMakeXRefRole._re_genex.match(title)
+                    if m:
+                        title = m.group(1)
                 targetname = title
             targetid = '%s:%s' % (objtype, targetname)
             targetnode = nodes.target('', '', ids=[targetid])
@@ -277,6 +282,10 @@ class CMakeObject(ObjectDescription):
     def handle_signature(self, sig, signode):
         # called from sphinx.directives.ObjectDescription.run()
         signode += addnodes.desc_name(sig, sig)
+        if self.objtype == 'genex':
+            m = CMakeXRefRole._re_genex.match(sig)
+            if m:
+                sig = m.group(1)
         return sig
 
     def add_target_and_index(self, name, sig, signode):
@@ -302,6 +311,7 @@ class CMakeXRefRole(XRefRole):
     # See sphinx.util.nodes.explicit_title_re; \x00 escapes '<'.
     _re = re.compile(r'^(.+?)(\s*)(?<!\x00)<(.*?)>$', re.DOTALL)
     _re_sub = re.compile(r'^([^()\s]+)\s*\(([^()]*)\)$', re.DOTALL)
+    _re_genex = re.compile(r'^\$<([^<>:]+)(:[^<>]+)?>$', re.DOTALL)
 
     def __call__(self, typ, rawtext, text, *args, **keys):
         # Translate CMake command cross-references of the form:
@@ -312,6 +322,10 @@ class CMakeXRefRole(XRefRole):
             m = CMakeXRefRole._re_sub.match(text)
             if m:
                 text = '%s <%s>' % (text, m.group(1))
+        elif typ == 'cmake:genex':
+            m = CMakeXRefRole._re_genex.match(text)
+            if m:
+                text = '%s <%s>' % (text, m.group(1))
         # CMake cross-reference targets frequently contain '<' so escape
         # any explicit `<target>` with '<' not preceded by whitespace.
         while True:
@@ -374,6 +388,7 @@ class CMakeDomain(Domain):
         'cpack_gen':  ObjType('cpack_gen',  'cpack_gen'),
         'envvar':     ObjType('envvar',     'envvar'),
         'generator':  ObjType('generator',  'generator'),
+        'genex':      ObjType('genex',      'genex'),
         'guide':      ObjType('guide',      'guide'),
         'variable':   ObjType('variable',   'variable'),
         'module':     ObjType('module',     'module'),
@@ -390,6 +405,7 @@ class CMakeDomain(Domain):
     directives = {
         'command':    CMakeObject,
         'envvar':     CMakeObject,
+        'genex':      CMakeObject,
         'variable':   CMakeObject,
         # Other object types cannot be created except by the CMakeTransform
         # 'generator':  CMakeObject,
@@ -409,6 +425,7 @@ class CMakeDomain(Domain):
         'cpack_gen':  CMakeXRefRole(),
         'envvar':     CMakeXRefRole(),
         'generator':  CMakeXRefRole(),
+        'genex':      CMakeXRefRole(),
         'guide':      CMakeXRefRole(),
         'variable':   CMakeXRefRole(),
         'module':     CMakeXRefRole(),

+ 1 - 0
Utilities/Sphinx/create_identifiers.py

@@ -25,6 +25,7 @@ for line in lines:
              ("envvar", "envvar"),
              ("variable", "variable"),
              ("generator", "generator"),
+             ("genex", "genex"),
              ("guide", "guide"),
              ("target property", "prop_tgt"),
              ("test property", "prop_test"),