mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-11 08:20:18 -06:00
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.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
// 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.
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
cmValue scandepRule =
|
||||
this->Target->GetMakefile()->GetDefinition("CMAKE_CXX_SCANDEP_SOURCE");
|
||||
this->Makefile->GetDefinition("CMAKE_CXX_SCANDEP_SOURCE");
|
||||
if (!scandepRule) {
|
||||
return Cxx20SupportLevel::MissingRule;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user