Ver código fonte

cmCoreTryCompile: parse `SOURCES_TYPE` argument

This will serve to add context for the source listing in order to
properly mark sources as `FILE_SET TYPE CXX_MODULES` in the generated
code.
Ben Boeckel 2 anos atrás
pai
commit
c9ca5f6326

+ 22 - 0
Help/command/try_compile.rst

@@ -65,6 +65,7 @@ Try Compiling Source Files
 .. code-block:: cmake
 
   try_compile(<compileResultVar>
+              [SOURCES_TYPE <type>]
               <SOURCES <srcfile...>                 |
                SOURCE_FROM_CONTENT <name> <content> |
                SOURCE_FROM_VAR <name> <var>         |
@@ -244,6 +245,27 @@ The options are:
 
   ``SOURCE_FROM_VAR`` may be specified multiple times.
 
+``SOURCES_TYPE <type>``
+  .. versionadded:: 3.28
+
+  Sources may be classified using the ``SOURCES_TYPE`` argument. Once
+  specified, all subsequent sources specified will be treated as that type
+  until another ``SOURCES_TYPE`` is given. Available types are:
+
+  ``NORMAL``
+    Sources are not added to any ``FILE_SET`` in the generated project.
+
+  ``CXX_MODULE``
+    Sources are added to a ``FILE_SET`` of type ``CXX_MODULES`` in the
+    generated project.
+
+  .. note ::
+
+    Experimental. Sources of type ``CXX_MODULE`` are gated by
+    ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
+
+  The default type of sources is ``NORMAL``.
+
 ``<LANG>_STANDARD <std>``
   .. versionadded:: 3.8
 

+ 1 - 0
Help/command/try_run.rst

@@ -13,6 +13,7 @@ Try Compiling and Running Source Files
 .. code-block:: cmake
 
   try_run(<runResultVar> <compileResultVar>
+          [SOURCES_TYPE <type>]
           <SOURCES <srcfile...>                 |
            SOURCE_FROM_CONTENT <name> <content> |
            SOURCE_FROM_VAR <name> <var>         |

+ 39 - 1
Source/cmCoreTryCompile.cxx

@@ -167,6 +167,7 @@ auto const TryCompileBaseArgParser =
 
 auto const TryCompileBaseSourcesArgParser =
   cmArgumentParser<Arguments>{ TryCompileBaseArgParser }
+    .Bind("SOURCES_TYPE"_s, &Arguments::SetSourceType)
     .Bind("SOURCES"_s, &Arguments::Sources)
     .Bind("COMPILE_DEFINITIONS"_s, TryCompileCompileDefs,
           ArgumentParser::ExpectAtLeast{ 0 })
@@ -221,12 +222,44 @@ auto const TryRunOldArgParser = makeTryRunParser(TryCompileOldArgParser);
 std::string const TryCompileDefaultConfig = "DEBUG";
 }
 
+ArgumentParser::Continue cmCoreTryCompile::Arguments::SetSourceType(
+  cm::string_view sourceType)
+{
+  bool matched = false;
+  if (sourceType == "NORMAL"_s) {
+    this->SourceTypeContext = SourceType::Normal;
+    matched = true;
+  } else if (sourceType == "CXX_MODULE"_s) {
+    bool const supportCxxModuleSources = cmExperimental::HasSupportEnabled(
+      *this->Makefile, cmExperimental::Feature::CxxModuleCMakeApi);
+    if (supportCxxModuleSources) {
+      this->SourceTypeContext = SourceType::CxxModule;
+      matched = true;
+    }
+  }
+
+  if (!matched && this->SourceTypeError.empty()) {
+    bool const supportCxxModuleSources = cmExperimental::HasSupportEnabled(
+      *this->Makefile, cmExperimental::Feature::CxxModuleCMakeApi);
+    auto const* message = "'SOURCE'";
+    if (supportCxxModuleSources) {
+      message = "one of 'SOURCE' or 'CXX_MODULE'";
+    }
+    // Only remember one error at a time; all other errors related to argument
+    // parsing are "indicate one error and return" anyways.
+    this->SourceTypeError =
+      cmStrCat("Invalid 'SOURCE_TYPE' '", sourceType, "'; must be ", message);
+  }
+  return ArgumentParser::Continue::Yes;
+}
+
 Arguments cmCoreTryCompile::ParseArgs(
   const cmRange<std::vector<std::string>::const_iterator>& args,
   const cmArgumentParser<Arguments>& parser,
   std::vector<std::string>& unparsedArguments)
 {
-  auto arguments = parser.Parse(args, &unparsedArguments, 0);
+  Arguments arguments{ this->Makefile };
+  parser.Parse(arguments, args, &unparsedArguments, 0);
   if (!arguments.MaybeReportError(*(this->Makefile)) &&
       !unparsedArguments.empty()) {
     std::string m = "Unknown arguments:";
@@ -434,6 +467,11 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
         "SOURCE_FROM_FILE requires exactly two arguments");
       return cm::nullopt;
     }
+    if (!arguments.SourceTypeError.empty()) {
+      this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
+                                   arguments.SourceTypeError);
+      return cm::nullopt;
+    }
   } else {
     // only valid for srcfile signatures
     if (!arguments.LangProps.empty()) {

+ 19 - 0
Source/cmCoreTryCompile.h

@@ -9,6 +9,7 @@
 #include <vector>
 
 #include <cm/optional>
+#include <cm/string_view>
 
 #include "cmArgumentParser.h"
 #include "cmArgumentParserTypes.h"
@@ -51,6 +52,20 @@ public:
 
   struct Arguments : public ArgumentParser::ParseResult
   {
+    Arguments(cmMakefile const* mf)
+      : Makefile(mf)
+    {
+    }
+
+    cmMakefile const* Makefile;
+
+    enum class SourceType
+    {
+      Normal,
+      CxxModule,
+      Directory,
+    };
+
     cm::optional<std::string> CompileResultVariable;
     cm::optional<std::string> BinaryDirectory;
     cm::optional<std::string> SourceDirectoryOrFile;
@@ -79,6 +94,10 @@ public:
     bool NoCache = false;
     bool NoLog = false;
 
+    ArgumentParser::Continue SetSourceType(cm::string_view sourceType);
+    SourceType SourceTypeContext = SourceType::Normal;
+    std::string SourceTypeError;
+
     // Argument for try_run only.
     // Keep in sync with warnings in cmCoreTryCompile::ParseArgs.
     cm::optional<std::string> CompileOutputVariable;