From c9ca5f6326136d02c8d12b0a749076ff375dae4c Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Wed, 19 Jul 2023 18:55:59 -0400 Subject: 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. --- Help/command/try_compile.rst | 22 ++++++++++++++++++++++ Help/command/try_run.rst | 1 + Source/cmCoreTryCompile.cxx | 40 +++++++++++++++++++++++++++++++++++++++- Source/cmCoreTryCompile.h | 19 +++++++++++++++++++ 4 files changed, 81 insertions(+), 1 deletion(-) 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( + [SOURCES_TYPE ] | SOURCE_FROM_CONTENT | SOURCE_FROM_VAR | @@ -244,6 +245,27 @@ The options are: ``SOURCE_FROM_VAR`` may be specified multiple times. +``SOURCES_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``. + ``_STANDARD `` .. 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( + [SOURCES_TYPE ] | SOURCE_FROM_CONTENT | SOURCE_FROM_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{ 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::const_iterator>& args, const cmArgumentParser& parser, std::vector& 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 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 #include +#include #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 CompileResultVariable; cm::optional BinaryDirectory; cm::optional 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 CompileOutputVariable; -- cgit v0.12