diff options
author | Brad King <brad.king@kitware.com> | 2023-10-03 19:19:44 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2023-10-03 20:06:46 (GMT) |
commit | 7ac696549a8608490e871ee77efe4086daf28add (patch) | |
tree | 57cce92f87b2cfa9c747661d61cd057591e6556b | |
parent | 8bd2c8d1fdd5b2dad9e65835a9c704ebe9b7371a (diff) | |
download | CMake-7ac696549a8608490e871ee77efe4086daf28add.zip CMake-7ac696549a8608490e871ee77efe4086daf28add.tar.gz CMake-7ac696549a8608490e871ee77efe4086daf28add.tar.bz2 |
cxxmodules: Fix CMP0155 NEW behavior when C++ compile features are not known
With CMP0155 NEW behavior, we scan C++ sources in targets using C++ 20,
i.e., in which the `cxx_std_20` feature is available. However, our
check for C++ feature availability may incorrectly succeed in two cases:
* MSVC versions from VS 2013 do not model C++ standard levels,
so we assume all features are available as a heuristic to let
projects at least try compiling with them.
* During ABI detection the `CMAKE_CXX20_COMPILE_FEATURES` variable is not
populated so we assume all features are available, knowing that our
ABI detection project does not need them.
For purposes of detecting targets using C++ 20, we do not want to assume
`cxx_std_20` is available, so verify that we really know it is.
-rw-r--r-- | Source/cmGeneratorTarget.cxx | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 96fcf7e..422d927 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -9093,20 +9093,27 @@ cmGeneratorTarget::Cxx20SupportLevel cmGeneratorTarget::HaveCxxModuleSupport( if (!state->GetLanguageEnabled("CXX")) { return Cxx20SupportLevel::MissingCxx; } + cmValue standardDefault = - this->Target->GetMakefile()->GetDefinition("CMAKE_CXX_STANDARD_DEFAULT"); - if (standardDefault && !standardDefault->empty()) { - cmStandardLevelResolver standardResolver(this->Makefile); - if (!standardResolver.HaveStandardAvailable(this, "CXX", config, - "cxx_std_20")) { - return Cxx20SupportLevel::NoCxx20; - } + this->Makefile->GetDefinition("CMAKE_CXX_STANDARD_DEFAULT"); + if (!standardDefault || standardDefault->empty()) { + // We do not know any meaningful C++ standard levels for this compiler. + return Cxx20SupportLevel::NoCxx20; + } + + cmStandardLevelResolver standardResolver(this->Makefile); + if (!standardResolver.HaveStandardAvailable(this, "CXX", config, + "cxx_std_20") || + // During the ABI detection step we do not know the compiler's features. + // HaveStandardAvailable may return true as a fallback, but in this code + // path we do not want to assume C++ 20 is available. + this->Makefile->GetDefinition("CMAKE_CXX20_COMPILE_FEATURES") + .IsEmpty()) { + return Cxx20SupportLevel::NoCxx20; } - // Else, an empty CMAKE_CXX_STANDARD_DEFAULT means CMake does not detect and - // set a default standard level for this compiler, so assume all standards - // are available. + cmValue scandepRule = - this->Target->GetMakefile()->GetDefinition("CMAKE_CXX_SCANDEP_SOURCE"); + this->Makefile->GetDefinition("CMAKE_CXX_SCANDEP_SOURCE"); if (!scandepRule) { return Cxx20SupportLevel::MissingRule; } |