diff options
Diffstat (limited to 'Source/cmGeneratorTarget.cxx')
-rw-r--r-- | Source/cmGeneratorTarget.cxx | 60 |
1 files changed, 49 insertions, 11 deletions
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 422d927..01af14f 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -50,6 +50,7 @@ #include "cmSourceFileLocation.h" #include "cmSourceFileLocationKind.h" #include "cmSourceGroup.h" +#include "cmStandardLevel.h" #include "cmStandardLevelResolver.h" #include "cmState.h" #include "cmStringAlgorithms.h" @@ -5024,10 +5025,44 @@ void cmGeneratorTarget::ComputeTargetManifest(const std::string& config) const } } -bool cmGeneratorTarget::ComputeCompileFeatures(std::string const& config) const +cm::optional<cmStandardLevel> cmGeneratorTarget::GetExplicitStandardLevel( + std::string const& lang, std::string const& config) const +{ + cm::optional<cmStandardLevel> level; + std::string key = cmStrCat(cmSystemTools::UpperCase(config), '-', lang); + auto i = this->ExplicitStandardLevel.find(key); + if (i != this->ExplicitStandardLevel.end()) { + level = i->second; + } + return level; +} + +void cmGeneratorTarget::UpdateExplicitStandardLevel(std::string const& lang, + std::string const& config, + cmStandardLevel level) +{ + auto e = this->ExplicitStandardLevel.emplace( + cmStrCat(cmSystemTools::UpperCase(config), '-', lang), level); + if (!e.second && e.first->second < level) { + e.first->second = level; + } +} + +bool cmGeneratorTarget::ComputeCompileFeatures(std::string const& config) { - // Compute the language standard based on the compile features. cmStandardLevelResolver standardResolver(this->Makefile); + + for (std::string const& lang : + this->Makefile->GetState()->GetEnabledLanguages()) { + if (cmValue languageStd = this->GetLanguageStandard(lang, config)) { + if (cm::optional<cmStandardLevel> langLevel = + standardResolver.LanguageStandardLevel(lang, *languageStd)) { + this->UpdateExplicitStandardLevel(lang, config, *langLevel); + } + } + } + + // Compute the language standard based on the compile features. std::vector<BT<std::string>> features = this->GetCompileFeatures(config); for (BT<std::string> const& f : features) { std::string lang; @@ -5039,13 +5074,18 @@ bool cmGeneratorTarget::ComputeCompileFeatures(std::string const& config) const std::string key = cmStrCat(cmSystemTools::UpperCase(config), '-', lang); cmValue currentLanguageStandard = this->GetLanguageStandard(lang, config); + cm::optional<cmStandardLevel> featureLevel; std::string newRequiredStandard; if (!standardResolver.GetNewRequiredStandard( this->Target->GetName(), f.Value, currentLanguageStandard, - newRequiredStandard)) { + featureLevel, newRequiredStandard)) { return false; } + if (featureLevel) { + this->UpdateExplicitStandardLevel(lang, config, *featureLevel); + } + if (!newRequiredStandard.empty()) { BTs<std::string>& languageStandardProperty = this->LanguageStandardMap[key]; @@ -5061,7 +5101,7 @@ bool cmGeneratorTarget::ComputeCompileFeatures(std::string const& config) const } bool cmGeneratorTarget::ComputeCompileFeatures( - std::string const& config, std::set<LanguagePair> const& languagePairs) const + std::string const& config, std::set<LanguagePair> const& languagePairs) { for (const auto& language : languagePairs) { BTs<std::string> const* generatorTargetLanguageStandard = @@ -9102,13 +9142,11 @@ cmGeneratorTarget::Cxx20SupportLevel cmGeneratorTarget::HaveCxxModuleSupport( } 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()) { + cmStandardLevel const cxxStd20 = + *standardResolver.LanguageStandardLevel("CXX", "20"); + cm::optional<cmStandardLevel> explicitLevel = + this->GetExplicitStandardLevel("CXX", config); + if (!explicitLevel || *explicitLevel < cxxStd20) { return Cxx20SupportLevel::NoCxx20; } |