diff options
author | Kyle Edwards <kyle.edwards@kitware.com> | 2021-06-16 17:09:59 -0400 |
---|---|---|
committer | Kyle Edwards <kyle.edwards@kitware.com> | 2021-10-27 15:17:23 -0400 |
commit | f2a44a8afabe6d0d87f1b5d4acf31b2049a021fd (patch) | |
tree | f1630cf49f0372ad7a8d1e7e14ee2d38076cb537 /Source/cmTarget.cxx | |
parent | 447fbf061a5f27abbad59a9fc943de4f8351f9fe (diff) | |
download | cmake-f2a44a8afabe6d0d87f1b5d4acf31b2049a021fd.tar.gz |
cmTarget: Add cmFileSet and associated properties
Diffstat (limited to 'Source/cmTarget.cxx')
-rw-r--r-- | Source/cmTarget.cxx | 321 |
1 files changed, 320 insertions, 1 deletions
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 97d60cf030..4f0dc6071c 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -14,11 +14,13 @@ #include <cm/memory> #include <cmext/algorithm> +#include <cmext/string_view> #include "cmsys/RegularExpression.hxx" #include "cmAlgorithms.h" #include "cmCustomCommand.h" +#include "cmFileSet.h" #include "cmGeneratorExpression.h" #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" @@ -200,8 +202,11 @@ public: std::vector<BT<std::string>> LinkOptionsEntries; std::vector<BT<std::string>> LinkDirectoriesEntries; std::vector<BT<std::string>> LinkImplementationPropertyEntries; + std::vector<BT<std::string>> HeaderSetsEntries; + std::vector<BT<std::string>> InterfaceHeaderSetsEntries; std::vector<std::pair<cmTarget::TLLSignature, cmListFileContext>> TLLCommands; + std::map<std::string, cmFileSet> FileSets; cmListFileBacktrace Backtrace; bool CheckImportedLibName(std::string const& prop, @@ -1110,6 +1115,16 @@ cmBTStringRange cmTarget::GetLinkImplementationEntries() const return cmMakeRange(this->impl->LinkImplementationPropertyEntries); } +cmBTStringRange cmTarget::GetHeaderSetsEntries() const +{ + return cmMakeRange(this->impl->HeaderSetsEntries); +} + +cmBTStringRange cmTarget::GetInterfaceHeaderSetsEntries() const +{ + return cmMakeRange(this->impl->InterfaceHeaderSetsEntries); +} + namespace { #define MAKE_PROP(PROP) const std::string prop##PROP = #PROP MAKE_PROP(C_STANDARD); @@ -1139,6 +1154,10 @@ MAKE_PROP(BINARY_DIR); MAKE_PROP(SOURCE_DIR); MAKE_PROP(FALSE); MAKE_PROP(TRUE); +MAKE_PROP(HEADER_DIRS); +MAKE_PROP(HEADER_SET); +MAKE_PROP(HEADER_SETS); +MAKE_PROP(INTERFACE_HEADER_SETS); #undef MAKE_PROP } @@ -1158,6 +1177,21 @@ std::string ConvertToString<cmValue>(cmValue value) { return std::string(*value); } + +template <typename ValueType> +bool StringIsEmpty(ValueType value); + +template <> +bool StringIsEmpty<const char*>(const char* value) +{ + return cmValue::IsEmpty(value); +} + +template <> +bool StringIsEmpty<cmValue>(cmValue value) +{ + return value.IsEmpty(); +} } template <typename ValueType> @@ -1321,6 +1355,104 @@ void cmTarget::StoreProperty(const std::string& prop, ValueType value) } else { this->impl->LanguageStandardProperties.erase(prop); } + } else if (prop == propHEADER_DIRS) { + auto* fileSet = this->GetFileSet("HEADERS"); + if (!fileSet) { + this->impl->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + "The default header set has not yet been created."); + return; + } + fileSet->ClearDirectoryEntries(); + if (!StringIsEmpty(value)) { + fileSet->AddDirectoryEntry( + BT<std::string>(value, this->impl->Makefile->GetBacktrace())); + } + } else if (prop == propHEADER_SET) { + auto* fileSet = this->GetFileSet("HEADERS"); + if (!fileSet) { + this->impl->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + "The default header set has not yet been created."); + return; + } + fileSet->ClearFileEntries(); + if (!StringIsEmpty(value)) { + fileSet->AddFileEntry( + BT<std::string>(value, this->impl->Makefile->GetBacktrace())); + } + } else if (cmHasLiteralPrefix(prop, "HEADER_DIRS_")) { + auto fileSetName = prop.substr(cmStrLen("HEADER_DIRS_")); + if (fileSetName.empty()) { + this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, + "Header set name cannot be empty."); + return; + } + auto* fileSet = this->GetFileSet(fileSetName); + if (!fileSet) { + this->impl->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Header set \"", fileSetName, + "\" has not yet been created.")); + return; + } + fileSet->ClearDirectoryEntries(); + if (!StringIsEmpty(value)) { + fileSet->AddDirectoryEntry( + BT<std::string>(value, this->impl->Makefile->GetBacktrace())); + } + } else if (cmHasLiteralPrefix(prop, "HEADER_SET_")) { + auto fileSetName = prop.substr(cmStrLen("HEADER_SET_")); + if (fileSetName.empty()) { + this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, + "Header set name cannot be empty."); + return; + } + auto* fileSet = this->GetFileSet(fileSetName); + if (!fileSet) { + this->impl->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Header set \"", fileSetName, + "\" has not yet been created.")); + return; + } + fileSet->ClearFileEntries(); + if (!StringIsEmpty(value)) { + fileSet->AddFileEntry( + BT<std::string>(value, this->impl->Makefile->GetBacktrace())); + } + } else if (prop == propHEADER_SETS) { + if (value) { + for (auto const& name : cmExpandedList(value)) { + if (!this->GetFileSet(name)) { + this->impl->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Header set \"", name, "\" has not yet been created.")); + return; + } + } + } + this->impl->HeaderSetsEntries.clear(); + if (!StringIsEmpty(value)) { + this->impl->HeaderSetsEntries.emplace_back( + value, this->impl->Makefile->GetBacktrace()); + } + } else if (prop == propINTERFACE_HEADER_SETS) { + if (value) { + for (auto const& name : cmExpandedList(value)) { + if (!this->GetFileSet(name)) { + this->impl->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Header set \"", name, "\" has not yet been created.")); + return; + } + } + } + this->impl->InterfaceHeaderSetsEntries.clear(); + if (!StringIsEmpty(value)) { + this->impl->InterfaceHeaderSetsEntries.emplace_back( + value, this->impl->Makefile->GetBacktrace()); + } } else { this->impl->Properties.SetProperty(prop, value); } @@ -1415,6 +1547,82 @@ 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 (prop == "HEADER_DIRS") { + auto* fileSet = this->GetFileSet("HEADERS"); + if (!fileSet) { + this->impl->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + "The default header set has not yet been created."); + return; + } + fileSet->AddDirectoryEntry( + BT<std::string>(value, this->impl->Makefile->GetBacktrace())); + } else if (cmHasLiteralPrefix(prop, "HEADER_DIRS_")) { + auto fileSetName = prop.substr(cmStrLen("HEADER_DIRS_")); + if (fileSetName.empty()) { + this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, + "Header set name cannot be empty."); + return; + } + auto* fileSet = this->GetFileSet(fileSetName); + if (!fileSet) { + this->impl->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Header set \"", fileSetName, + "\" has not yet been created.")); + return; + } + fileSet->AddDirectoryEntry( + BT<std::string>(value, this->impl->Makefile->GetBacktrace())); + } else if (prop == "HEADER_SET") { + auto* fileSet = this->GetFileSet("HEADERS"); + if (!fileSet) { + this->impl->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + "The default header set has not yet been created."); + return; + } + fileSet->AddFileEntry( + BT<std::string>(value, this->impl->Makefile->GetBacktrace())); + } else if (cmHasLiteralPrefix(prop, "HEADER_SET_")) { + auto fileSetName = prop.substr(cmStrLen("HEADER_SET_")); + if (fileSetName.empty()) { + this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, + "Header set name cannot be empty."); + return; + } + auto* fileSet = this->GetFileSet(fileSetName); + if (!fileSet) { + this->impl->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Header set \"", fileSetName, + "\" has not yet been created.")); + return; + } + fileSet->AddFileEntry( + BT<std::string>(value, this->impl->Makefile->GetBacktrace())); + } else if (prop == "HEADER_SETS") { + for (auto const& name : cmExpandedList(value)) { + if (!this->GetFileSet(name)) { + this->impl->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Header set \"", name, "\" has not yet been created.")); + return; + } + } + this->impl->HeaderSetsEntries.emplace_back( + value, this->impl->Makefile->GetBacktrace()); + } else if (prop == "INTERFACE_HEADER_SETS") { + for (auto const& name : cmExpandedList(value)) { + if (!this->GetFileSet(name)) { + this->impl->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Header set \"", name, "\" has not yet been created.")); + return; + } + } + this->impl->InterfaceHeaderSetsEntries.emplace_back( + value, this->impl->Makefile->GetBacktrace()); } else { this->impl->Properties.AppendProperty(prop, value, asString); } @@ -1633,7 +1841,11 @@ cmValue cmTarget::GetProperty(const std::string& prop) const propNAME, propBINARY_DIR, propSOURCE_DIR, - propSOURCES + propSOURCES, + propHEADER_DIRS, + propHEADER_SET, + propHEADER_SETS, + propINTERFACE_HEADER_SETS, }; if (specialProps.count(prop)) { if (prop == propC_STANDARD || prop == propCXX_STANDARD || @@ -1759,6 +1971,60 @@ cmValue cmTarget::GetProperty(const std::string& prop) const .GetDirectory() .GetCurrentSource()); } + if (prop == propHEADER_DIRS) { + auto const* fileSet = this->GetFileSet("HEADERS"); + if (!fileSet) { + return nullptr; + } + static std::string output; + output = cmJoin(fileSet->GetDirectoryEntries(), ";"_s); + return cmValue(output); + } + if (prop == propHEADER_SET) { + auto const* fileSet = this->GetFileSet("HEADERS"); + if (!fileSet) { + return nullptr; + } + static std::string output; + output = cmJoin(fileSet->GetFileEntries(), ";"_s); + return cmValue(output); + } + if (prop == propHEADER_SETS) { + static std::string output; + output = cmJoin(this->impl->HeaderSetsEntries, ";"_s); + return cmValue(output); + } + if (prop == propINTERFACE_HEADER_SETS) { + static std::string output; + output = cmJoin(this->impl->InterfaceHeaderSetsEntries, ";"_s); + return cmValue(output); + } + } + if (cmHasLiteralPrefix(prop, "HEADER_DIRS_")) { + std::string fileSetName = prop.substr(cmStrLen("HEADER_DIRS_")); + if (fileSetName.empty()) { + return nullptr; + } + auto const* fileSet = this->GetFileSet(fileSetName); + if (!fileSet) { + return nullptr; + } + static std::string output; + output = cmJoin(fileSet->GetDirectoryEntries(), ";"_s); + return cmValue(output); + } + if (cmHasLiteralPrefix(prop, "HEADER_SET_")) { + std::string fileSetName = prop.substr(cmStrLen("HEADER_SET_")); + if (fileSetName.empty()) { + return nullptr; + } + auto const* fileSet = this->GetFileSet(fileSetName); + if (!fileSet) { + return nullptr; + } + static std::string output; + output = cmJoin(fileSet->GetFileEntries(), ";"_s); + return cmValue(output); } cmValue retVal = this->impl->Properties.GetPropertyValue(prop); @@ -2015,6 +2281,59 @@ std::string cmTarget::ImportedGetFullPath( return result; } +const cmFileSet* cmTarget::GetFileSet(const std::string& name) const +{ + auto it = this->impl->FileSets.find(name); + return it == this->impl->FileSets.end() ? nullptr : &it->second; +} + +cmFileSet* cmTarget::GetFileSet(const std::string& name) +{ + auto it = this->impl->FileSets.find(name); + return it == this->impl->FileSets.end() ? nullptr : &it->second; +} + +std::pair<cmFileSet*, bool> cmTarget::GetOrCreateFileSet( + const std::string& name, const std::string& type) +{ + auto result = + this->impl->FileSets.emplace(std::make_pair(name, cmFileSet(name, type))); + return std::make_pair(&result.first->second, result.second); +} + +std::string cmTarget::GetFileSetsPropertyName(const std::string& type) +{ + if (type == "HEADERS") { + return "HEADER_SETS"; + } + return ""; +} + +std::string cmTarget::GetInterfaceFileSetsPropertyName(const std::string& type) +{ + if (type == "HEADERS") { + return "INTERFACE_HEADER_SETS"; + } + return ""; +} + +std::vector<std::string> cmTarget::GetAllInterfaceFileSets() const +{ + std::vector<std::string> result; + auto inserter = std::back_inserter(result); + + auto appendEntries = [=](const std::vector<BT<std::string>>& entries) { + for (auto const& entry : entries) { + auto expanded = cmExpandedList(entry.Value); + std::copy(expanded.begin(), expanded.end(), inserter); + } + }; + + appendEntries(this->impl->InterfaceHeaderSetsEntries); + + return result; +} + bool cmTargetInternals::CheckImportedLibName(std::string const& prop, std::string const& value) const { |