From ba835874a43599bcc5ee2f8321662eb34fb341aa Mon Sep 17 00:00:00 2001 From: Justin Goshi Date: Thu, 18 Jun 2020 15:42:15 -0700 Subject: Add backtrace support for language standard --- Source/cmGeneratorTarget.cxx | 37 +++++++++++++++++------- Source/cmGeneratorTarget.h | 5 +++- Source/cmMakefile.cxx | 6 ++-- Source/cmTarget.cxx | 69 ++++++++++++++++++++++++++++++++++++++++++++ Source/cmTarget.h | 7 +++++ 5 files changed, 109 insertions(+), 15 deletions(-) diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index d537be7..992682f 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -947,8 +947,8 @@ bool cmGeneratorTarget::HasExplicitObjectName(cmSourceFile const* file) const return it != this->ExplicitObjectName.end(); } -cmProp cmGeneratorTarget::GetLanguageStandard(std::string const& lang, - std::string const& config) const +BT const* cmGeneratorTarget::GetLanguageStandardProperty( + std::string const& lang, std::string const& config) const { std::string key = cmStrCat(cmSystemTools::UpperCase(config), '-', lang); auto langStandardIter = this->LanguageStandardMap.find(key); @@ -956,7 +956,21 @@ cmProp cmGeneratorTarget::GetLanguageStandard(std::string const& lang, return &langStandardIter->second; } - return this->Target->GetProperty(cmStrCat(lang, "_STANDARD")); + return this->Target->GetLanguageStandardProperty( + cmStrCat(lang, "_STANDARD")); +} + +cmProp cmGeneratorTarget::GetLanguageStandard(std::string const& lang, + std::string const& config) const +{ + BT const* languageStandard = + this->GetLanguageStandardProperty(lang, config); + + if (languageStandard) { + return &(languageStandard->Value); + } + + return nullptr; } cmProp cmGeneratorTarget::GetPropertyWithPairedLanguageSupport( @@ -4469,7 +4483,8 @@ bool cmGeneratorTarget::ComputeCompileFeatures(std::string const& config) const } if (!newRequiredStandard.empty()) { - this->LanguageStandardMap[key] = newRequiredStandard; + this->LanguageStandardMap[key] = + BT(newRequiredStandard, f.Backtrace); } } @@ -4480,15 +4495,15 @@ bool cmGeneratorTarget::ComputeCompileFeatures( std::string const& config, std::set const& languagePairs) const { for (const auto& language : languagePairs) { - cmProp generatorTargetLanguageStandard = - this->GetLanguageStandard(language.first, config); + BT const* generatorTargetLanguageStandard = + this->GetLanguageStandardProperty(language.first, config); if (!generatorTargetLanguageStandard) { // If the standard isn't explicitly set we copy it over from the // specified paired language. std::string key = cmStrCat(cmSystemTools::UpperCase(config), '-', language.first); - cmProp standardToCopy = - this->GetLanguageStandard(language.second, config); + BT const* standardToCopy = + this->GetLanguageStandardProperty(language.second, config); if (standardToCopy != nullptr) { this->LanguageStandardMap[key] = *standardToCopy; generatorTargetLanguageStandard = &this->LanguageStandardMap[key]; @@ -4496,7 +4511,7 @@ bool cmGeneratorTarget::ComputeCompileFeatures( cmProp defaultStandard = this->Makefile->GetDef( cmStrCat("CMAKE_", language.second, "_STANDARD_DEFAULT")); if (defaultStandard != nullptr) { - this->LanguageStandardMap[key] = *defaultStandard; + this->LanguageStandardMap[key] = BT(*defaultStandard); generatorTargetLanguageStandard = &this->LanguageStandardMap[key]; } } @@ -4504,8 +4519,8 @@ bool cmGeneratorTarget::ComputeCompileFeatures( // Custom updates for the CUDA standard. if (generatorTargetLanguageStandard != nullptr && language.first == "CUDA") { - if (*generatorTargetLanguageStandard == "98") { - this->LanguageStandardMap[key] = "03"; + if (generatorTargetLanguageStandard->Value == "98") { + this->LanguageStandardMap[key].Value = "03"; } } } diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index cd53611..20f3a07 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -148,6 +148,9 @@ public: bool HasExplicitObjectName(cmSourceFile const* file) const; void AddExplicitObjectName(cmSourceFile const* sf); + BT const* GetLanguageStandardProperty( + std::string const& lang, std::string const& config) const; + cmProp GetLanguageStandard(std::string const& lang, std::string const& config) const; @@ -1050,7 +1053,7 @@ private: bool GetRPATH(const std::string& config, const std::string& prop, std::string& rpath) const; - mutable std::map LanguageStandardMap; + mutable std::map> LanguageStandardMap; cmProp GetPropertyWithPairedLanguageSupport(std::string const& lang, const char* suffix) const; diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 1f1c06a..3161e38 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -5070,7 +5070,7 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target, target->GetProperty(cmStrCat(lang, "_STANDARD")), newRequiredStandard, error)) { if (!newRequiredStandard.empty()) { - target->SetProperty(cmStrCat(lang, "_STANDARD"), newRequiredStandard); + target->SetLanguageStandardProperty(lang, newRequiredStandard, feature); } return true; } @@ -5251,7 +5251,7 @@ bool cmMakefile::AddRequiredTargetCudaFeature(cmTarget* target, target->GetProperty(cmStrCat(lang, "_STANDARD")), newRequiredStandard, error)) { if (!newRequiredStandard.empty()) { - target->SetProperty(cmStrCat(lang, "_STANDARD"), newRequiredStandard); + target->SetLanguageStandardProperty(lang, newRequiredStandard, feature); } return true; } @@ -5356,7 +5356,7 @@ bool cmMakefile::AddRequiredTargetCFeature(cmTarget* target, target->GetProperty(cmStrCat(lang, "_STANDARD")), newRequiredStandard, error)) { if (!newRequiredStandard.empty()) { - target->SetProperty(cmStrCat(lang, "_STANDARD"), newRequiredStandard); + target->SetLanguageStandardProperty(lang, newRequiredStandard, feature); } return true; } diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 36e1ad5..d3b37cb 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -185,6 +186,7 @@ public: std::vector InstallGenerators; std::set SystemIncludeDirectories; cmTarget::LinkLibraryVectorType OriginalLinkLibraries; + std::map> LanguageStandardProperties; std::vector IncludeDirectoriesEntries; std::vector IncludeDirectoriesBacktraces; std::vector CompileOptionsEntries; @@ -598,6 +600,35 @@ cmGlobalGenerator* cmTarget::GetGlobalGenerator() const return impl->Makefile->GetGlobalGenerator(); } +BT const* cmTarget::GetLanguageStandardProperty( + const std::string& propertyName) const +{ + auto entry = impl->LanguageStandardProperties.find(propertyName); + if (entry != impl->LanguageStandardProperties.end()) { + return &entry->second; + } + + return nullptr; +} + +void cmTarget::SetLanguageStandardProperty(std::string const& lang, + std::string const& value, + const std::string& feature) +{ + cmListFileBacktrace featureBacktrace; + for (size_t i = 0; i < impl->CompileFeaturesEntries.size(); i++) { + if (impl->CompileFeaturesEntries[i] == feature) { + if (i < impl->CompileFeaturesBacktraces.size()) { + featureBacktrace = impl->CompileFeaturesBacktraces[i]; + } + break; + } + } + + impl->LanguageStandardProperties[cmStrCat(lang, "_STANDARD")] = + BT(value, featureBacktrace); +} + void cmTarget::AddUtility(std::string const& name, bool cross, cmMakefile* mf) { impl->Utilities.insert(BT>( @@ -1127,6 +1158,11 @@ void cmTarget::SetProperty(const std::string& prop, const char* value) return; } #define MAKE_STATIC_PROP(PROP) static const std::string prop##PROP = #PROP + MAKE_STATIC_PROP(C_STANDARD); + MAKE_STATIC_PROP(CXX_STANDARD); + MAKE_STATIC_PROP(CUDA_STANDARD); + MAKE_STATIC_PROP(OBJC_STANDARD); + MAKE_STATIC_PROP(OBJCXX_STANDARD); MAKE_STATIC_PROP(COMPILE_DEFINITIONS); MAKE_STATIC_PROP(COMPILE_FEATURES); MAKE_STATIC_PROP(COMPILE_OPTIONS); @@ -1310,6 +1346,15 @@ void cmTarget::SetProperty(const std::string& prop, const char* value) cmProp tmp = reusedTarget->GetProperty("COMPILE_PDB_NAME"); this->SetProperty("COMPILE_PDB_NAME", tmp ? tmp->c_str() : nullptr); this->AddUtility(reusedFrom, false, impl->Makefile); + } else if (prop == propC_STANDARD || prop == propCXX_STANDARD || + prop == propCUDA_STANDARD || prop == propOBJC_STANDARD || + prop == propOBJCXX_STANDARD) { + if (value) { + impl->LanguageStandardProperties[prop] = + BT(value, impl->Makefile->GetBacktrace()); + } else { + impl->LanguageStandardProperties.erase(prop); + } } else { impl->Properties.SetProperty(prop, value); } @@ -1413,6 +1458,11 @@ void cmTarget::AppendProperty(const std::string& prop, } else if (cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME")) { impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, prop + " property may not be APPENDed."); + } else if (prop == "C_STANDARD" || prop == "CXX_STANDARD" || + prop == "CUDA_STANDARD" || prop == "OBJC_STANDARD" || + prop == "OBJCXX_STANDARD") { + impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, + prop + " property may not be appended."); } else { impl->Properties.AppendProperty(prop, value, asString); } @@ -1626,6 +1676,11 @@ cmProp cmTarget::GetComputedProperty(const std::string& prop, cmProp cmTarget::GetProperty(const std::string& prop) const { #define MAKE_STATIC_PROP(PROP) static const std::string prop##PROP = #PROP + MAKE_STATIC_PROP(C_STANDARD); + MAKE_STATIC_PROP(CXX_STANDARD); + MAKE_STATIC_PROP(CUDA_STANDARD); + MAKE_STATIC_PROP(OBJC_STANDARD); + MAKE_STATIC_PROP(OBJCXX_STANDARD); MAKE_STATIC_PROP(LINK_LIBRARIES); MAKE_STATIC_PROP(TYPE); MAKE_STATIC_PROP(INCLUDE_DIRECTORIES); @@ -1646,6 +1701,11 @@ cmProp cmTarget::GetProperty(const std::string& prop) const MAKE_STATIC_PROP(TRUE); #undef MAKE_STATIC_PROP static std::unordered_set const specialProps{ + propC_STANDARD, + propCXX_STANDARD, + propCUDA_STANDARD, + propOBJC_STANDARD, + propOBJCXX_STANDARD, propLINK_LIBRARIES, propTYPE, propINCLUDE_DIRECTORIES, @@ -1664,6 +1724,15 @@ cmProp cmTarget::GetProperty(const std::string& prop) const propSOURCES }; if (specialProps.count(prop)) { + if (prop == propC_STANDARD || prop == propCXX_STANDARD || + prop == propCUDA_STANDARD || prop == propOBJC_STANDARD || + prop == propOBJCXX_STANDARD) { + auto propertyIter = impl->LanguageStandardProperties.find(prop); + if (propertyIter == impl->LanguageStandardProperties.end()) { + return nullptr; + } + return &(propertyIter->second.Value); + } if (prop == propLINK_LIBRARIES) { if (impl->LinkImplementationPropertyEntries.empty()) { return nullptr; diff --git a/Source/cmTarget.h b/Source/cmTarget.h index f0ddb68..175822d 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -233,6 +233,13 @@ public: void AddSystemIncludeDirectories(std::set const& incs); std::set const& GetSystemIncludeDirectories() const; + BT const* GetLanguageStandardProperty( + const std::string& propertyName) const; + + void SetLanguageStandardProperty(std::string const& lang, + std::string const& value, + const std::string& feature); + cmStringRange GetIncludeDirectoriesEntries() const; cmBacktraceRange GetIncludeDirectoriesBacktraces() const; -- cgit v0.12