diff options
author | Brad King <brad.king@kitware.com> | 2023-02-01 14:07:30 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2023-02-01 14:07:58 (GMT) |
commit | a58b0baca2f7ffbd4c9973b9b35a74c463292f40 (patch) | |
tree | 0bef8b7abbc62cda68998761aec35617e532ac16 /Source/cmTarget.cxx | |
parent | 29d19e0e5a6f7d70f9231a9175fb306884c92659 (diff) | |
parent | 33f629184fab88290274854595e44261f5a6dd2d (diff) | |
download | CMake-a58b0baca2f7ffbd4c9973b9b35a74c463292f40.zip CMake-a58b0baca2f7ffbd4c9973b9b35a74c463292f40.tar.gz CMake-a58b0baca2f7ffbd4c9973b9b35a74c463292f40.tar.bz2 |
Merge topic 'cmTarget-refactorings'
33f629184f cmTarget: simplify `CheckLinkLibraryPattern`
22b9ce73e7 cmTarget: refactor INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE usage requirements
332d2f8f52 cmTarget: refactor INTERFACE_LINK_LIBRARIES_DIRECT usage requirements
15eec07500 cmTarget: refactor INTERFACE_LINK_LIBRARIES usage requirements
e80689d101 cmTarget: refactor LINK_LIBRARIES usage requirements
4f009d2121 cmTarget: refactor LINK_DIRECTORIES usage requirements
99e783e735 cmTarget: refactor LINK_OPTIONS usage requirements
fd295dd263 cmTarget: refactor SOURCES usage requirements
...
Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: buildbot <buildbot@kitware.com>
Merge-request: !8127
Diffstat (limited to 'Source/cmTarget.cxx')
-rw-r--r-- | Source/cmTarget.cxx | 724 |
1 files changed, 335 insertions, 389 deletions
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index cd431fa..debf593 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -212,9 +212,16 @@ struct FileSetType FileSetEntries SelfEntries; FileSetEntries InterfaceEntries; + enum class Action + { + Set, + Append, + }; + template <typename ValueType> bool WriteProperties(cmTarget* tgt, cmTargetInternals* impl, - const std::string& prop, ValueType value, bool clear); + const std::string& prop, ValueType value, + Action action); std::pair<bool, cmValue> ReadProperties(cmTarget const* tgt, cmTargetInternals const* impl, const std::string& prop) const; @@ -222,6 +229,50 @@ struct FileSetType void AddFileSet(const std::string& name, cmFileSetVisibility vis, cmListFileBacktrace bt); }; + +struct UsageRequirementProperty +{ + enum class AppendEmpty + { + Yes, + No, + }; + + UsageRequirementProperty(cm::static_string_view name, + AppendEmpty appendEmpty = AppendEmpty::No) + : Name(name) + , AppendBehavior(appendEmpty) + { + } + + void CopyFromDirectory(cmBTStringRange directoryEntries) + { + return cm::append(this->Entries, directoryEntries); + } + + enum class Action + { + Set, + Prepend, + Append, + }; + + template <typename ValueType> + bool Write(cmTargetInternals const* impl, + cm::optional<cmListFileBacktrace> const& bt, + const std::string& prop, ValueType value, Action action); + template <typename ValueType> + void WriteDirect(cmTargetInternals const* impl, + cm::optional<cmListFileBacktrace> const& bt, + ValueType value, Action action); + void WriteDirect(BT<std::string> value, Action action); + std::pair<bool, cmValue> Read(const std::string& prop) const; + + cm::static_string_view const Name; + AppendEmpty const AppendBehavior; + + std::vector<BT<std::string>> Entries; +}; } class cmTargetInternals @@ -251,25 +302,26 @@ public: std::set<std::string> SystemIncludeDirectories; cmTarget::LinkLibraryVectorType OriginalLinkLibraries; std::map<std::string, BTs<std::string>> LanguageStandardProperties; - std::vector<BT<std::string>> IncludeDirectoriesEntries; std::map<cmTargetExport const*, std::vector<std::string>> InstallIncludeDirectoriesEntries; - std::vector<BT<std::string>> CompileOptionsEntries; - std::vector<BT<std::string>> CompileFeaturesEntries; - std::vector<BT<std::string>> CompileDefinitionsEntries; - std::vector<BT<std::string>> PrecompileHeadersEntries; - std::vector<BT<std::string>> SourceEntries; - std::vector<BT<std::string>> LinkOptionsEntries; - std::vector<BT<std::string>> LinkDirectoriesEntries; - std::vector<BT<std::string>> LinkImplementationPropertyEntries; - std::vector<BT<std::string>> LinkInterfacePropertyEntries; - std::vector<BT<std::string>> LinkInterfaceDirectPropertyEntries; - std::vector<BT<std::string>> LinkInterfaceDirectExcludePropertyEntries; std::vector<std::pair<cmTarget::TLLSignature, cmListFileContext>> TLLCommands; std::map<std::string, cmFileSet> FileSets; cmListFileBacktrace Backtrace; + UsageRequirementProperty IncludeDirectories; + UsageRequirementProperty CompileOptions; + UsageRequirementProperty CompileFeatures; + UsageRequirementProperty CompileDefinitions; + UsageRequirementProperty PrecompileHeaders; + UsageRequirementProperty Sources; + UsageRequirementProperty LinkOptions; + UsageRequirementProperty LinkDirectories; + UsageRequirementProperty LinkLibraries; + UsageRequirementProperty InterfaceLinkLibraries; + UsageRequirementProperty InterfaceLinkLibrariesDirect; + UsageRequirementProperty InterfaceLinkLibrariesDirectExclude; + FileSetType HeadersFileSets; FileSetType CxxModulesFileSets; FileSetType CxxModuleHeadersFileSets; @@ -284,11 +336,13 @@ public: template <typename ValueType> void AddDirectoryToFileSet(cmTarget* self, std::string const& fileSetName, ValueType value, cm::string_view fileSetType, - cm::string_view description, bool clear); + cm::string_view description, + FileSetType::Action action); template <typename ValueType> void AddPathToFileSet(cmTarget* self, std::string const& fileSetName, ValueType value, cm::string_view fileSetType, - cm::string_view description, bool clear); + cm::string_view description, + FileSetType::Action action); cmValue GetFileSetDirectories(cmTarget const* self, std::string const& fileSetName, cm::string_view fileSetType) const; @@ -303,7 +357,20 @@ public: }; cmTargetInternals::cmTargetInternals() - : HeadersFileSets("HEADERS"_s, "HEADER_DIRS"_s, "HEADER_SET"_s, + : IncludeDirectories("INCLUDE_DIRECTORIES"_s) + , CompileOptions("COMPILE_OPTIONS"_s) + , CompileFeatures("COMPILE_FEATURES"_s) + , CompileDefinitions("COMPILE_DEFINITIONS"_s) + , PrecompileHeaders("PRECOMPILE_HEADERS"_s) + , Sources("SOURCES"_s, UsageRequirementProperty::AppendEmpty::Yes) + , LinkOptions("LINK_OPTIONS"_s) + , LinkDirectories("LINK_DIRECTORIES"_s) + , LinkLibraries("LINK_LIBRARIES"_s) + , InterfaceLinkLibraries("INTERFACE_LINK_LIBRARIES"_s) + , InterfaceLinkLibrariesDirect("INTERFACE_LINK_LIBRARIES_DIRECT"_s) + , InterfaceLinkLibrariesDirectExclude( + "INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE"_s) + , HeadersFileSets("HEADERS"_s, "HEADER_DIRS"_s, "HEADER_SET"_s, "HEADER_DIRS_"_s, "HEADER_SET_"_s, "Header"_s, "The default header set"_s, "Header set"_s, FileSetEntries("HEADER_SETS"_s), @@ -327,17 +394,17 @@ cmTargetInternals::cmTargetInternals() template <typename ValueType> bool FileSetType::WriteProperties(cmTarget* tgt, cmTargetInternals* impl, const std::string& prop, ValueType value, - bool clear) + Action action) { if (prop == this->DefaultDirectoryProperty) { impl->AddDirectoryToFileSet(tgt, std::string(this->TypeName), value, this->TypeName, this->DefaultDescription, - clear); + action); return true; } if (prop == this->DefaultPathProperty) { impl->AddPathToFileSet(tgt, std::string(this->TypeName), value, - this->TypeName, this->DefaultDescription, clear); + this->TypeName, this->DefaultDescription, action); return true; } if (cmHasPrefix(prop, this->DirectoryPrefix)) { @@ -349,7 +416,8 @@ bool FileSetType::WriteProperties(cmTarget* tgt, cmTargetInternals* impl, } else { impl->AddDirectoryToFileSet( tgt, fileSetName, value, this->TypeName, - cmStrCat(this->ArbitraryDescription, " \"", fileSetName, "\""), clear); + cmStrCat(this->ArbitraryDescription, " \"", fileSetName, "\""), + action); } return true; } @@ -362,7 +430,8 @@ bool FileSetType::WriteProperties(cmTarget* tgt, cmTargetInternals* impl, } else { impl->AddPathToFileSet( tgt, fileSetName, value, this->TypeName, - cmStrCat(this->ArbitraryDescription, " \"", fileSetName, "\""), clear); + cmStrCat(this->ArbitraryDescription, " \"", fileSetName, "\""), + action); } return true; } @@ -432,6 +501,67 @@ void FileSetType::AddFileSet(const std::string& name, cmFileSetVisibility vis, } } +template <typename ValueType> +bool UsageRequirementProperty::Write( + cmTargetInternals const* impl, cm::optional<cmListFileBacktrace> const& bt, + const std::string& prop, ValueType value, Action action) +{ + if (prop == this->Name) { + this->WriteDirect(impl, bt, value, action); + return true; + } + return false; +} + +template <typename ValueType> +void UsageRequirementProperty::WriteDirect( + cmTargetInternals const* impl, cm::optional<cmListFileBacktrace> const& bt, + ValueType value, Action action) +{ + if (action == Action::Set) { + this->Entries.clear(); + } + if (value) { + cmListFileBacktrace lfbt = impl->GetBacktrace(bt); + if (action == Action::Prepend) { + this->Entries.emplace(this->Entries.begin(), value, lfbt); + } else if (action == Action::Set || cmNonempty(value) || + this->AppendBehavior == AppendEmpty::Yes) { + this->Entries.emplace_back(value, lfbt); + } + } +} + +void UsageRequirementProperty::WriteDirect(BT<std::string> value, + Action action) +{ + if (action == Action::Set) { + this->Entries.clear(); + } + if (action == Action::Prepend) { + this->Entries.emplace(this->Entries.begin(), std::move(value)); + } else { + this->Entries.emplace_back(std::move(value)); + } +} + +std::pair<bool, cmValue> UsageRequirementProperty::Read( + const std::string& prop) const +{ + bool did_read = false; + cmValue value = nullptr; + if (prop == this->Name) { + if (!this->Entries.empty()) { + // Storage to back the returned `cmValue`. + static std::string output; + output = cmJoin(this->Entries, ";"); + value = cmValue(output); + } + did_read = true; + } + return { did_read, value }; +} + namespace { #define SETUP_COMMON_LANGUAGE_PROPERTIES(lang) \ initProp(#lang "_COMPILER_LAUNCHER"); \ @@ -774,8 +904,8 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, if (!this->IsImported()) { // Initialize the INCLUDE_DIRECTORIES property based on the current value // of the same directory property: - cm::append(this->impl->IncludeDirectoriesEntries, - this->impl->Makefile->GetIncludeDirectoriesEntries()); + this->impl->IncludeDirectories.CopyFromDirectory( + this->impl->Makefile->GetIncludeDirectoriesEntries()); { auto const& sysInc = this->impl->Makefile->GetSystemIncludeDirectories(); @@ -783,14 +913,12 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, sysInc.end()); } - cm::append(this->impl->CompileOptionsEntries, - this->impl->Makefile->GetCompileOptionsEntries()); - - cm::append(this->impl->LinkOptionsEntries, - this->impl->Makefile->GetLinkOptionsEntries()); - - cm::append(this->impl->LinkDirectoriesEntries, - this->impl->Makefile->GetLinkDirectoriesEntries()); + this->impl->CompileOptions.CopyFromDirectory( + this->impl->Makefile->GetCompileOptionsEntries()); + this->impl->LinkOptions.CopyFromDirectory( + this->impl->Makefile->GetLinkOptionsEntries()); + this->impl->LinkDirectories.CopyFromDirectory( + this->impl->Makefile->GetLinkDirectoriesEntries()); } if (this->impl->TargetType == cmStateEnums::EXECUTABLE) { @@ -917,7 +1045,7 @@ void cmTarget::SetLanguageStandardProperty(std::string const& lang, const std::string& feature) { cmListFileBacktrace featureBacktrace; - for (auto const& entry : this->impl->CompileFeaturesEntries) { + for (auto const& entry : this->impl->CompileFeatures.Entries) { if (entry.Value == feature) { featureBacktrace = entry.Backtrace; break; @@ -1035,15 +1163,15 @@ void cmTarget::AddPostBuildCommand(cmCustomCommand&& cmd) void cmTarget::AddTracedSources(std::vector<std::string> const& srcs) { if (!srcs.empty()) { - cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->SourceEntries.emplace_back(cmJoin(srcs, ";"), lfbt); + this->impl->Sources.WriteDirect(this->impl.get(), {}, + cmValue(cmJoin(srcs, ";")), + UsageRequirementProperty::Action::Append); } } void cmTarget::AddSources(std::vector<std::string> const& srcs) { - std::string srcFiles; - const char* sep = ""; + std::vector<std::string> srcFiles; for (auto filename : srcs) { if (!cmGeneratorExpression::StartsWithGeneratorExpression(filename)) { if (!filename.empty()) { @@ -1054,14 +1182,9 @@ void cmTarget::AddSources(std::vector<std::string> const& srcs) } this->impl->Makefile->GetOrCreateSource(filename); } - srcFiles += sep; - srcFiles += filename; - sep = ";"; - } - if (!srcFiles.empty()) { - cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->SourceEntries.emplace_back(std::move(srcFiles), lfbt); + srcFiles.emplace_back(filename); } + this->AddTracedSources(srcFiles); } std::string cmTargetInternals::ProcessSourceItemCMP0049( @@ -1165,13 +1288,13 @@ cmSourceFile* cmTarget::AddSource(const std::string& src, bool before) { cmSourceFileLocation sfl(this->impl->Makefile, src, cmSourceFileLocationKind::Known); - if (std::find_if( - this->impl->SourceEntries.begin(), this->impl->SourceEntries.end(), - TargetPropertyEntryFinder(sfl)) == this->impl->SourceEntries.end()) { - cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->SourceEntries.insert(before ? this->impl->SourceEntries.begin() - : this->impl->SourceEntries.end(), - BT<std::string>(src, lfbt)); + auto const& sources = this->impl->Sources.Entries; + if (std::find_if(sources.begin(), sources.end(), + TargetPropertyEntryFinder(sfl)) == sources.end()) { + this->impl->Sources.WriteDirect( + this->impl.get(), {}, cmValue(src), + before ? UsageRequirementProperty::Action::Prepend + : UsageRequirementProperty::Action::Append); } if (cmGeneratorExpression::Find(src) != std::string::npos) { return nullptr; @@ -1399,62 +1522,62 @@ cmStringRange cmTarget::GetInstallIncludeDirectoriesEntries( cmBTStringRange cmTarget::GetIncludeDirectoriesEntries() const { - return cmMakeRange(this->impl->IncludeDirectoriesEntries); + return cmMakeRange(this->impl->IncludeDirectories.Entries); } cmBTStringRange cmTarget::GetCompileOptionsEntries() const { - return cmMakeRange(this->impl->CompileOptionsEntries); + return cmMakeRange(this->impl->CompileOptions.Entries); } cmBTStringRange cmTarget::GetCompileFeaturesEntries() const { - return cmMakeRange(this->impl->CompileFeaturesEntries); + return cmMakeRange(this->impl->CompileFeatures.Entries); } cmBTStringRange cmTarget::GetCompileDefinitionsEntries() const { - return cmMakeRange(this->impl->CompileDefinitionsEntries); + return cmMakeRange(this->impl->CompileDefinitions.Entries); } cmBTStringRange cmTarget::GetPrecompileHeadersEntries() const { - return cmMakeRange(this->impl->PrecompileHeadersEntries); + return cmMakeRange(this->impl->PrecompileHeaders.Entries); } cmBTStringRange cmTarget::GetSourceEntries() const { - return cmMakeRange(this->impl->SourceEntries); + return cmMakeRange(this->impl->Sources.Entries); } cmBTStringRange cmTarget::GetLinkOptionsEntries() const { - return cmMakeRange(this->impl->LinkOptionsEntries); + return cmMakeRange(this->impl->LinkOptions.Entries); } cmBTStringRange cmTarget::GetLinkDirectoriesEntries() const { - return cmMakeRange(this->impl->LinkDirectoriesEntries); + return cmMakeRange(this->impl->LinkDirectories.Entries); } cmBTStringRange cmTarget::GetLinkImplementationEntries() const { - return cmMakeRange(this->impl->LinkImplementationPropertyEntries); + return cmMakeRange(this->impl->LinkLibraries.Entries); } cmBTStringRange cmTarget::GetLinkInterfaceEntries() const { - return cmMakeRange(this->impl->LinkInterfacePropertyEntries); + return cmMakeRange(this->impl->InterfaceLinkLibraries.Entries); } cmBTStringRange cmTarget::GetLinkInterfaceDirectEntries() const { - return cmMakeRange(this->impl->LinkInterfaceDirectPropertyEntries); + return cmMakeRange(this->impl->InterfaceLinkLibrariesDirect.Entries); } cmBTStringRange cmTarget::GetLinkInterfaceDirectExcludeEntries() const { - return cmMakeRange(this->impl->LinkInterfaceDirectExcludePropertyEntries); + return cmMakeRange(this->impl->InterfaceLinkLibrariesDirectExclude.Entries); } cmBTStringRange cmTarget::GetHeaderSetsEntries() const @@ -1540,26 +1663,6 @@ std::string ConvertToString<cmValue>(cmValue value) return std::string(*value); } -template <typename ValueType> -bool StringIsEmpty(ValueType const& value); - -template <> -bool StringIsEmpty<const char*>(const char* const& value) -{ - return cmValue::IsEmpty(value); -} - -template <> -bool StringIsEmpty<cmValue>(cmValue const& value) -{ - return value.IsEmpty(); -} - -template <> -bool StringIsEmpty<std::string>(std::string const& value) -{ - return value.empty(); -} } template <typename ValueType> @@ -1603,80 +1706,42 @@ void cmTarget::StoreProperty(const std::string& prop, ValueType value) return; } - if (prop == propINCLUDE_DIRECTORIES) { - this->impl->IncludeDirectoriesEntries.clear(); - if (value) { - cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->IncludeDirectoriesEntries.emplace_back(value, lfbt); - } - } else if (prop == propCOMPILE_OPTIONS) { - this->impl->CompileOptionsEntries.clear(); - if (value) { - cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->CompileOptionsEntries.emplace_back(value, lfbt); - } - } else if (prop == propCOMPILE_FEATURES) { - this->impl->CompileFeaturesEntries.clear(); - if (value) { - cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->CompileFeaturesEntries.emplace_back(value, lfbt); - } - } else if (prop == propCOMPILE_DEFINITIONS) { - this->impl->CompileDefinitionsEntries.clear(); - if (value) { - cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->CompileDefinitionsEntries.emplace_back(value, lfbt); - } - } else if (prop == propLINK_OPTIONS) { - this->impl->LinkOptionsEntries.clear(); - if (value) { - cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->LinkOptionsEntries.emplace_back(value, lfbt); - } - } else if (prop == propLINK_DIRECTORIES) { - this->impl->LinkDirectoriesEntries.clear(); - if (value) { - cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->LinkDirectoriesEntries.emplace_back(value, lfbt); - } - } else if (prop == propPRECOMPILE_HEADERS) { - this->impl->PrecompileHeadersEntries.clear(); - if (value) { - cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->PrecompileHeadersEntries.emplace_back(value, lfbt); - } - } else if (prop == propLINK_LIBRARIES) { - this->impl->LinkImplementationPropertyEntries.clear(); - if (value) { - cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->LinkImplementationPropertyEntries.emplace_back(value, lfbt); - } - } else if (prop == propINTERFACE_LINK_LIBRARIES) { - this->impl->LinkInterfacePropertyEntries.clear(); - if (value) { - cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->LinkInterfacePropertyEntries.emplace_back(value, lfbt); - } - } else if (prop == propINTERFACE_LINK_LIBRARIES_DIRECT) { - this->impl->LinkInterfaceDirectPropertyEntries.clear(); - if (value) { - cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->LinkInterfaceDirectPropertyEntries.emplace_back(value, lfbt); - } - } else if (prop == propINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE) { - this->impl->LinkInterfaceDirectExcludePropertyEntries.clear(); - if (value) { - cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->LinkInterfaceDirectExcludePropertyEntries.emplace_back(value, - lfbt); + UsageRequirementProperty* usageRequirements[] = { + &this->impl->IncludeDirectories, + &this->impl->CompileOptions, + &this->impl->CompileFeatures, + &this->impl->CompileDefinitions, + &this->impl->PrecompileHeaders, + &this->impl->Sources, + &this->impl->LinkOptions, + &this->impl->LinkDirectories, + &this->impl->LinkLibraries, + &this->impl->InterfaceLinkLibraries, + &this->impl->InterfaceLinkLibrariesDirect, + &this->impl->InterfaceLinkLibrariesDirectExclude, + }; + + for (auto* usageRequirement : usageRequirements) { + if (usageRequirement->Write(this->impl.get(), {}, prop, value, + UsageRequirementProperty::Action::Set)) { + return; } - } else if (prop == propSOURCES) { - this->impl->SourceEntries.clear(); - if (value) { - cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); - this->impl->SourceEntries.emplace_back(value, lfbt); + } + + FileSetType* fileSetTypes[] = { + &this->impl->HeadersFileSets, + &this->impl->CxxModulesFileSets, + &this->impl->CxxModuleHeadersFileSets, + }; + + for (auto* fileSetType : fileSetTypes) { + if (fileSetType->WriteProperties(this, this->impl.get(), prop, value, + FileSetType::Action::Set)) { + return; } - } else if (prop == propIMPORTED_GLOBAL) { + } + + if (prop == propIMPORTED_GLOBAL) { if (!cmIsOn(value)) { std::ostringstream e; e << "IMPORTED_GLOBAL property can't be set to FALSE on targets (\"" @@ -1744,15 +1809,6 @@ void cmTarget::StoreProperty(const std::string& prop, ValueType value) } else { this->impl->LanguageStandardProperties.erase(prop); } - } else if (this->impl->HeadersFileSets.WriteProperties( - this, this->impl.get(), prop, value, true)) { - /* Handled in the `if` condition. */ - } else if (this->impl->CxxModulesFileSets.WriteProperties( - this, this->impl.get(), prop, value, true)) { - /* Handled in the `if` condition. */ - } else if (this->impl->CxxModuleHeadersFileSets.WriteProperties( - this, this->impl.get(), prop, value, true)) { - /* Handled in the `if` condition. */ } else { this->impl->Properties.SetProperty(prop, value); } @@ -1790,74 +1846,52 @@ void cmTarget::AppendProperty(const std::string& prop, this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); return; } - if (prop == "INCLUDE_DIRECTORIES") { - if (!value.empty()) { - cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt); - this->impl->IncludeDirectoriesEntries.emplace_back(value, lfbt); - } - } else if (prop == "COMPILE_OPTIONS") { - if (!value.empty()) { - cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt); - this->impl->CompileOptionsEntries.emplace_back(value, lfbt); - } - } else if (prop == "COMPILE_FEATURES") { - if (!value.empty()) { - cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt); - this->impl->CompileFeaturesEntries.emplace_back(value, lfbt); - } - } else if (prop == "COMPILE_DEFINITIONS") { - if (!value.empty()) { - cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt); - this->impl->CompileDefinitionsEntries.emplace_back(value, lfbt); - } - } else if (prop == "LINK_OPTIONS") { - if (!value.empty()) { - cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt); - this->impl->LinkOptionsEntries.emplace_back(value, lfbt); - } - } else if (prop == "LINK_DIRECTORIES") { - if (!value.empty()) { - cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt); - this->impl->LinkDirectoriesEntries.emplace_back(value, lfbt); - } - } else if (prop == "PRECOMPILE_HEADERS") { - if (this->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM")) { - std::ostringstream e; - e << "PRECOMPILE_HEADERS_REUSE_FROM property is already set on target " - "(\"" - << this->impl->Name << "\")\n"; - this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + if (prop == propPRECOMPILE_HEADERS && + this->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM")) { + std::ostringstream e; + e << "PRECOMPILE_HEADERS_REUSE_FROM property is already set on target " + "(\"" + << this->impl->Name << "\")\n"; + this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + return; + } + + UsageRequirementProperty* usageRequirements[] = { + &this->impl->IncludeDirectories, + &this->impl->CompileOptions, + &this->impl->CompileFeatures, + &this->impl->CompileDefinitions, + &this->impl->PrecompileHeaders, + &this->impl->Sources, + &this->impl->LinkOptions, + &this->impl->LinkDirectories, + &this->impl->LinkLibraries, + &this->impl->InterfaceLinkLibraries, + &this->impl->InterfaceLinkLibrariesDirect, + &this->impl->InterfaceLinkLibrariesDirectExclude, + }; + + for (auto* usageRequirement : usageRequirements) { + if (usageRequirement->Write(this->impl.get(), bt, prop, cmValue(value), + UsageRequirementProperty::Action::Append)) { + return; + } + } + + FileSetType* fileSetTypes[] = { + &this->impl->HeadersFileSets, + &this->impl->CxxModulesFileSets, + &this->impl->CxxModuleHeadersFileSets, + }; + + for (auto* fileSetType : fileSetTypes) { + if (fileSetType->WriteProperties(this, this->impl.get(), prop, value, + FileSetType::Action::Append)) { return; } - if (!value.empty()) { - cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt); - this->impl->PrecompileHeadersEntries.emplace_back(value, lfbt); - } - } else if (prop == "LINK_LIBRARIES") { - if (!value.empty()) { - cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt); - this->impl->LinkImplementationPropertyEntries.emplace_back(value, lfbt); - } - } else if (prop == propINTERFACE_LINK_LIBRARIES) { - if (!value.empty()) { - cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt); - this->impl->LinkInterfacePropertyEntries.emplace_back(value, lfbt); - } - } else if (prop == propINTERFACE_LINK_LIBRARIES_DIRECT) { - if (!value.empty()) { - cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt); - this->impl->LinkInterfaceDirectPropertyEntries.emplace_back(value, lfbt); - } - } else if (prop == propINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE) { - if (!value.empty()) { - cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt); - this->impl->LinkInterfaceDirectExcludePropertyEntries.emplace_back(value, - lfbt); - } - } else if (prop == "SOURCES") { - cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt); - this->impl->SourceEntries.emplace_back(value, lfbt); - } else if (cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME")) { + } + + if (cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME")) { this->impl->Makefile->IssueMessage( MessageType::FATAL_ERROR, prop + " property may not be APPENDed."); } else if (prop == "C_STANDARD" || prop == "CXX_STANDARD" || @@ -1865,16 +1899,6 @@ void cmTarget::AppendProperty(const std::string& prop, prop == "OBJC_STANDARD" || prop == "OBJCXX_STANDARD") { this->impl->Makefile->IssueMessage( MessageType::FATAL_ERROR, prop + " property may not be appended."); - } else if (this->impl->HeadersFileSets.WriteProperties( - this, this->impl.get(), prop, value, - false)) { // NOLINT(bugprone-branch-clone) - /* Handled in the `if` condition. */ - } else if (this->impl->CxxModulesFileSets.WriteProperties( - this, this->impl.get(), prop, value, false)) { - /* Handled in the `if` condition. */ - } else if (this->impl->CxxModuleHeadersFileSets.WriteProperties( - this, this->impl.get(), prop, value, false)) { - /* Handled in the `if` condition. */ } else { this->impl->Properties.AppendProperty(prop, value, asString); } @@ -1890,9 +1914,12 @@ void cmTarget::SetProperty(const std::string& prop, cmValue value) } template <typename ValueType> -void cmTargetInternals::AddDirectoryToFileSet( - cmTarget* self, std::string const& fileSetName, ValueType value, - cm::string_view fileSetType, cm::string_view description, bool clear) +void cmTargetInternals::AddDirectoryToFileSet(cmTarget* self, + std::string const& fileSetName, + ValueType value, + cm::string_view fileSetType, + cm::string_view description, + FileSetType::Action action) { auto* fileSet = self->GetFileSet(fileSetName); if (!fileSet) { @@ -1908,19 +1935,22 @@ void cmTargetInternals::AddDirectoryToFileSet( "\".")); return; } - if (clear) { + if (action == FileSetType::Action::Set) { fileSet->ClearDirectoryEntries(); } - if (!StringIsEmpty(value)) { + if (cmNonempty(value)) { fileSet->AddDirectoryEntry( BT<std::string>(value, this->Makefile->GetBacktrace())); } } template <typename ValueType> -void cmTargetInternals::AddPathToFileSet( - cmTarget* self, std::string const& fileSetName, ValueType value, - cm::string_view fileSetType, cm::string_view description, bool clear) +void cmTargetInternals::AddPathToFileSet(cmTarget* self, + std::string const& fileSetName, + ValueType value, + cm::string_view fileSetType, + cm::string_view description, + FileSetType::Action action) { auto* fileSet = self->GetFileSet(fileSetName); if (!fileSet) { @@ -1936,10 +1966,10 @@ void cmTargetInternals::AddPathToFileSet( "\".")); return; } - if (clear) { + if (action == FileSetType::Action::Set) { fileSet->ClearFileEntries(); } - if (!StringIsEmpty(value)) { + if (cmNonempty(value)) { fileSet->AddFileEntry( BT<std::string>(value, this->Makefile->GetBacktrace())); } @@ -2013,8 +2043,7 @@ void cmTarget::AppendBuildInterfaceIncludes() } namespace { -bool CheckLinkLibraryPattern(cm::string_view property, - const std::vector<BT<std::string>>& value, +bool CheckLinkLibraryPattern(UsageRequirementProperty const& usage, cmake* context) { // Look for <LINK_LIBRARY:> and </LINK_LIBRARY:> internal tags @@ -2023,7 +2052,7 @@ bool CheckLinkLibraryPattern(cm::string_view property, bool isValid = true; - for (const auto& item : value) { + for (const auto& item : usage.Entries) { if (!linkPattern.find(item.Value)) { continue; } @@ -2034,8 +2063,8 @@ bool CheckLinkLibraryPattern(cm::string_view property, context->IssueMessage( MessageType::FATAL_ERROR, cmStrCat( - "Property ", property, " contains the invalid item \"", - linkPattern.match(2), "\". The ", property, + "Property ", usage.Name, " contains the invalid item \"", + linkPattern.match(2), "\". The ", usage.Name, " property may contain the generator-expression \"$<LINK_", linkPattern.match(3), ":...>\" which may be used to specify how the libraries are linked."), @@ -2054,14 +2083,11 @@ void cmTarget::FinalizeTargetConfiguration( return; } - if (!CheckLinkLibraryPattern("LINK_LIBRARIES"_s, - this->impl->LinkImplementationPropertyEntries, + if (!CheckLinkLibraryPattern(this->impl->LinkLibraries, this->GetMakefile()->GetCMakeInstance()) || - !CheckLinkLibraryPattern("INTERFACE_LINK_LIBRARIES"_s, - this->impl->LinkInterfacePropertyEntries, + !CheckLinkLibraryPattern(this->impl->InterfaceLinkLibraries, this->GetMakefile()->GetCMakeInstance()) || - !CheckLinkLibraryPattern("INTERFACE_LINK_LIBRARIES_DIRECT"_s, - this->impl->LinkInterfaceDirectPropertyEntries, + !CheckLinkLibraryPattern(this->impl->InterfaceLinkLibrariesDirect, this->GetMakefile()->GetCMakeInstance())) { return; } @@ -2105,44 +2131,46 @@ void cmTarget::FinalizeTargetConfiguration( void cmTarget::InsertInclude(BT<std::string> const& entry, bool before) { - auto position = before ? this->impl->IncludeDirectoriesEntries.begin() - : this->impl->IncludeDirectoriesEntries.end(); - - this->impl->IncludeDirectoriesEntries.insert(position, entry); + this->impl->IncludeDirectories.WriteDirect( + entry, + before ? UsageRequirementProperty::Action::Prepend + : UsageRequirementProperty::Action::Append); } void cmTarget::InsertCompileOption(BT<std::string> const& entry, bool before) { - auto position = before ? this->impl->CompileOptionsEntries.begin() - : this->impl->CompileOptionsEntries.end(); - - this->impl->CompileOptionsEntries.insert(position, entry); + this->impl->CompileOptions.WriteDirect( + entry, + before ? UsageRequirementProperty::Action::Prepend + : UsageRequirementProperty::Action::Append); } void cmTarget::InsertCompileDefinition(BT<std::string> const& entry) { - this->impl->CompileDefinitionsEntries.push_back(entry); + this->impl->CompileDefinitions.WriteDirect( + entry, UsageRequirementProperty::Action::Append); } void cmTarget::InsertLinkOption(BT<std::string> const& entry, bool before) { - auto position = before ? this->impl->LinkOptionsEntries.begin() - : this->impl->LinkOptionsEntries.end(); - - this->impl->LinkOptionsEntries.insert(position, entry); + this->impl->LinkOptions.WriteDirect( + entry, + before ? UsageRequirementProperty::Action::Prepend + : UsageRequirementProperty::Action::Append); } void cmTarget::InsertLinkDirectory(BT<std::string> const& entry, bool before) { - auto position = before ? this->impl->LinkDirectoriesEntries.begin() - : this->impl->LinkDirectoriesEntries.end(); - - this->impl->LinkDirectoriesEntries.insert(position, entry); + this->impl->LinkDirectories.WriteDirect( + entry, + before ? UsageRequirementProperty::Action::Prepend + : UsageRequirementProperty::Action::Append); } void cmTarget::InsertPrecompileHeader(BT<std::string> const& entry) { - this->impl->PrecompileHeadersEntries.push_back(entry); + this->impl->PrecompileHeaders.WriteDirect( + entry, UsageRequirementProperty::Action::Append); } namespace { @@ -2287,102 +2315,33 @@ cmValue cmTarget::GetProperty(const std::string& prop) const } return cmValue(propertyIter->second.Value); } - if (prop == propLINK_LIBRARIES) { - if (this->impl->LinkImplementationPropertyEntries.empty()) { - return nullptr; - } - static std::string output; - output = cmJoin(this->impl->LinkImplementationPropertyEntries, ";"); - return cmValue(output); - } - if (prop == propINTERFACE_LINK_LIBRARIES) { - if (this->impl->LinkInterfacePropertyEntries.empty()) { - return nullptr; - } + UsageRequirementProperty const* usageRequirements[] = { + &this->impl->IncludeDirectories, + &this->impl->CompileOptions, + &this->impl->CompileFeatures, + &this->impl->CompileDefinitions, + &this->impl->PrecompileHeaders, + &this->impl->Sources, + &this->impl->LinkOptions, + &this->impl->LinkDirectories, + &this->impl->LinkLibraries, + &this->impl->InterfaceLinkLibraries, + &this->impl->InterfaceLinkLibrariesDirect, + &this->impl->InterfaceLinkLibrariesDirectExclude, + }; - static std::string output; - output = cmJoin(this->impl->LinkInterfacePropertyEntries, ";"); - return cmValue(output); - } - if (prop == propINTERFACE_LINK_LIBRARIES_DIRECT) { - if (this->impl->LinkInterfaceDirectPropertyEntries.empty()) { - return nullptr; + for (auto const* usageRequirement : usageRequirements) { + auto value = usageRequirement->Read(prop); + if (value.first) { + return value.second; } - - static std::string output; - output = cmJoin(this->impl->LinkInterfaceDirectPropertyEntries, ";"); - return cmValue(output); } - if (prop == propINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE) { - if (this->impl->LinkInterfaceDirectExcludePropertyEntries.empty()) { - return nullptr; - } - static std::string output; - output = - cmJoin(this->impl->LinkInterfaceDirectExcludePropertyEntries, ";"); - return cmValue(output); - } // the type property returns what type the target is if (prop == propTYPE) { return cmValue(cmState::GetTargetTypeName(this->GetType())); } - if (prop == propINCLUDE_DIRECTORIES) { - if (this->impl->IncludeDirectoriesEntries.empty()) { - return nullptr; - } - - static std::string output; - output = cmJoin(this->impl->IncludeDirectoriesEntries, ";"); - return cmValue(output); - } - if (prop == propCOMPILE_FEATURES) { - if (this->impl->CompileFeaturesEntries.empty()) { - return nullptr; - } - - static std::string output; - output = cmJoin(this->impl->CompileFeaturesEntries, ";"); - return cmValue(output); - } - if (prop == propCOMPILE_OPTIONS) { - if (this->impl->CompileOptionsEntries.empty()) { - return nullptr; - } - - static std::string output; - output = cmJoin(this->impl->CompileOptionsEntries, ";"); - return cmValue(output); - } - if (prop == propCOMPILE_DEFINITIONS) { - if (this->impl->CompileDefinitionsEntries.empty()) { - return nullptr; - } - - static std::string output; - output = cmJoin(this->impl->CompileDefinitionsEntries, ";"); - return cmValue(output); - } - if (prop == propLINK_OPTIONS) { - if (this->impl->LinkOptionsEntries.empty()) { - return nullptr; - } - - static std::string output; - output = cmJoin(this->impl->LinkOptionsEntries, ";"); - return cmValue(output); - } - if (prop == propLINK_DIRECTORIES) { - if (this->impl->LinkDirectoriesEntries.empty()) { - return nullptr; - } - - static std::string output; - output = cmJoin(this->impl->LinkDirectoriesEntries, ";"); - - return cmValue(output); - } if (prop == propMANUALLY_ADDED_DEPENDENCIES) { if (this->impl->Utilities.empty()) { return nullptr; @@ -2400,15 +2359,6 @@ cmValue cmTarget::GetProperty(const std::string& prop) const output = cmJoin(utilities, ";"); return cmValue(output); } - if (prop == propPRECOMPILE_HEADERS) { - if (this->impl->PrecompileHeadersEntries.empty()) { - return nullptr; - } - - static std::string output; - output = cmJoin(this->impl->PrecompileHeadersEntries, ";"); - return cmValue(output); - } if (prop == propIMPORTED) { return this->IsImported() ? cmValue(propTRUE) : cmValue(propFALSE); } @@ -2433,21 +2383,17 @@ cmValue cmTarget::GetProperty(const std::string& prop) const // Check fileset properties. { - auto headers = - this->impl->HeadersFileSets.ReadProperties(this, this->impl.get(), prop); - if (headers.first) { - return headers.second; - } - auto cxx_modules = this->impl->CxxModulesFileSets.ReadProperties( - this, this->impl.get(), prop); - if (cxx_modules.first) { - return cxx_modules.second; - } - auto cxx_module_headers = - this->impl->CxxModuleHeadersFileSets.ReadProperties( - this, this->impl.get(), prop); - if (cxx_module_headers.first) { - return cxx_module_headers.second; + FileSetType* fileSetTypes[] = { + &this->impl->HeadersFileSets, + &this->impl->CxxModulesFileSets, + &this->impl->CxxModuleHeadersFileSets, + }; + + for (auto* fileSetType : fileSetTypes) { + auto value = fileSetType->ReadProperties(this, this->impl.get(), prop); + if (value.first) { + return value.second; + } } } |