Pārlūkot izejas kodu

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 gadi atpakaļ
vecāks
revīzija
7d498d6b43

+ 13 - 2
Help/dev/documentation.rst

@@ -136,6 +136,10 @@ documentation:
  A CMake native build system generator.
  A CMake native build system generator.
  See the `cmake(1)`_ command-line tool's ``-G`` option.
  See the `cmake(1)`_ command-line tool's ``-G`` option.
 
 
+``genex``
+ A CMake generator expression.
+ See the `cmake-generator-expressions(7)`_ manual.
+
 ``manual``
 ``manual``
  A CMake manual page, like the `cmake(1)`_ 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
 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>``.
 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
 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
 Second, the CMake Domain provides directives to define objects inside
 other documents:
 other documents:
@@ -187,6 +193,10 @@ other documents:
 
 
   This indented block documents <envvar-name>.
   This indented block documents <envvar-name>.
 
 
+ .. genex:: <genex-name>
+
+  This indented block documents <genex-name>.
+
  .. variable:: <variable-name>
  .. variable:: <variable-name>
 
 
   This indented block documents <variable-name>.
   This indented block documents <variable-name>.
@@ -197,6 +207,7 @@ the first approach above.
 .. _`Sphinx Domain`: http://sphinx-doc.org/domains.html
 .. _`Sphinx Domain`: http://sphinx-doc.org/domains.html
 .. _`cmake(1)`: https://cmake.org/cmake/help/latest/manual/cmake.1.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-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-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-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
 .. _`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)
   , Markup(MarkupNone)
   , Directive(DirectiveNone)
   , Directive(DirectiveNone)
   , CMakeDirective("^.. (cmake:)?("
   , CMakeDirective("^.. (cmake:)?("
-                   "command|envvar|variable"
+                   "command|envvar|genex|variable"
                    ")::[ \t]+([^ \t\n]+)$")
                    ")::[ \t]+([^ \t\n]+)$")
   , CMakeModuleDirective("^.. cmake-module::[ \t]+([^ \t\n]+)$")
   , CMakeModuleDirective("^.. cmake-module::[ \t]+([^ \t\n]+)$")
   , ParsedLiteralDirective("^.. parsed-literal::[ \t]*(.*)$")
   , ParsedLiteralDirective("^.. parsed-literal::[ \t]*(.*)$")
@@ -37,7 +37,8 @@ cmRST::cmRST(std::ostream& os, std::string docroot)
   , NoteDirective("^.. note::[ \t]*(.*)$")
   , NoteDirective("^.. note::[ \t]*(.*)$")
   , ModuleRST(R"(^#\[(=*)\[\.rst:$)")
   , ModuleRST(R"(^#\[(=*)\[\.rst:$)")
   , CMakeRole("(:cmake)?:("
   , 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_cache|prop_dir|prop_gbl|prop_inst|prop_sf|"
               "prop_test|prop_tgt|"
               "prop_test|prop_tgt|"
               "manual"
               "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.
 Environment variable ``some env var`` with space and target.
 Generator ``Some Generator`` with space.
 Generator ``Some Generator`` with space.
 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 literal ``~!@#$%^&*( )_+-=\\[]{}'":;,<>.?/``.
 Inline link Link Text.
 Inline link Link Text.
 Inline link Link Text <With \-escaped Brackets>.
 Inline link Link Text <With \-escaped Brackets>.
@@ -56,6 +62,14 @@ Bracket Comment Content
 
 
    Environment variable other_var description.
    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
 .. cmake:variable:: some_var
 
 
    Variable some_var description.
    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.
 Environment variable :envvar:`some env var <SOME_ENV_VAR>` with space and target.
 Generator :generator:`Some Generator` with space.
 Generator :generator:`Some Generator` with space.
 Generator :cpack_gen:`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 literal ``~!@#$%^&*( )_+-=\\[]{}'":;,<>.?/``.
 Inline link `Link Text <ExternalDest>`_.
 Inline link `Link Text <ExternalDest>`_.
 Inline link `Link Text \<With \\-escaped Brackets\> <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.
    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
 .. cmake:variable:: some_var
 
 
    Variable some_var description.
    Variable some_var description.

+ 19 - 2
Utilities/Sphinx/cmake.py

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

+ 1 - 0
Utilities/Sphinx/create_identifiers.py

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