diff options
-rw-r--r-- | Help/command/try_compile.rst | 22 | ||||
-rw-r--r-- | Help/command/try_run.rst | 1 | ||||
-rw-r--r-- | Source/cmCoreTryCompile.cxx | 40 | ||||
-rw-r--r-- | Source/cmCoreTryCompile.h | 19 |
4 files changed, 81 insertions, 1 deletions
diff --git a/Help/command/try_compile.rst b/Help/command/try_compile.rst index 8abb6e0..fbc4221 100644 --- a/Help/command/try_compile.rst +++ b/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 diff --git a/Help/command/try_run.rst b/Help/command/try_run.rst index 3a4e203..d48ab3d 100644 --- a/Help/command/try_run.rst +++ b/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> | diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index 32f2e3b..57a9180 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/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()) { diff --git a/Source/cmCoreTryCompile.h b/Source/cmCoreTryCompile.h index c185c68..7d5a4f8 100644 --- a/Source/cmCoreTryCompile.h +++ b/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; |