| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying | |
| file LICENSE.rst or https://cmake.org/licensing for details. */ | |
| #include "cmStateDirectory.h" | |
| #include <algorithm> | |
| #include <cassert> | |
| #include <vector> | |
| #include <cm/iterator> | |
| #include <cm/string_view> | |
| #include <cmext/algorithm> | |
| #include <cmext/string_view> | |
| #include "cmAlgorithms.h" | |
| #include "cmList.h" | |
| #include "cmListFileCache.h" | |
| #include "cmProperty.h" | |
| #include "cmPropertyMap.h" | |
| #include "cmRange.h" | |
| #include "cmState.h" | |
| #include "cmStatePrivate.h" | |
| #include "cmValue.h" | |
| static std::string const kBINARY_DIR = "BINARY_DIR"; | |
| static std::string const kBUILDSYSTEM_TARGETS = "BUILDSYSTEM_TARGETS"; | |
| static std::string const kSOURCE_DIR = "SOURCE_DIR"; | |
| static std::string const kSUBDIRECTORIES = "SUBDIRECTORIES"; | |
| std::string const& cmStateDirectory::GetCurrentSource() const | |
| { | |
| return this->DirectoryState->Location; | |
| } | |
| void cmStateDirectory::SetCurrentSource(std::string const& dir) | |
| { | |
| this->DirectoryState->Location = dir; | |
| this->Snapshot_.SetDefinition("CMAKE_CURRENT_SOURCE_DIR", | |
| this->DirectoryState->Location); | |
| } | |
| std::string const& cmStateDirectory::GetCurrentBinary() const | |
| { | |
| return this->DirectoryState->OutputLocation; | |
| } | |
| void cmStateDirectory::SetCurrentBinary(std::string const& dir) | |
| { | |
| this->DirectoryState->OutputLocation = dir; | |
| this->Snapshot_.SetDefinition("CMAKE_CURRENT_BINARY_DIR", | |
| this->DirectoryState->OutputLocation); | |
| } | |
| cmStateDirectory::cmStateDirectory( | |
| cmLinkedTree<cmStateDetail::BuildsystemDirectoryStateType>::iterator iter, | |
| cmStateSnapshot const& snapshot) | |
| : DirectoryState(iter) | |
| , Snapshot_(snapshot) | |
| { | |
| } | |
| template <typename T, typename U> | |
| cmBTStringRange GetPropertyContent(T const& content, U contentEndPosition) | |
| { | |
| auto end = content.begin() + contentEndPosition; | |
| auto rbegin = cm::make_reverse_iterator(end); | |
| rbegin = std::find(rbegin, content.rend(), cmStateDetail::PropertySentinel); | |
| return cmMakeRange(rbegin.base(), end); | |
| } | |
| template <typename T, typename U> | |
| void AppendEntry(T& content, U& endContentPosition, | |
| const BT<std::string>& value) | |
| { | |
| if (value.Value.empty()) { | |
| return; | |
| } | |
| assert(endContentPosition == content.size()); | |
| content.push_back(value); | |
| endContentPosition = content.size(); | |
| } | |
| template <typename T, typename U> | |
| void SetContent(T& content, U& endContentPosition, const BT<std::string>& vec) | |
| { | |
| assert(endContentPosition == content.size()); | |
| content.resize(content.size() + 2); | |
| content.back() = vec; | |
| endContentPosition = content.size(); | |
| } | |
| template <typename T, typename U> | |
| void ClearContent(T& content, U& endContentPosition) | |
| { | |
| assert(endContentPosition == content.size()); | |
| content.resize(content.size() + 1); | |
| endContentPosition = content.size(); | |
| } | |
| cmBTStringRange cmStateDirectory::GetIncludeDirectoriesEntries() const | |
| { | |
| return GetPropertyContent( | |
| this->DirectoryState->IncludeDirectories, | |
| this->Snapshot_.Position->IncludeDirectoryPosition); | |
| } | |
| void cmStateDirectory::AppendIncludeDirectoriesEntry( | |
| const BT<std::string>& vec) | |
| { | |
| AppendEntry(this->DirectoryState->IncludeDirectories, | |
| this->Snapshot_.Position->IncludeDirectoryPosition, vec); | |
| } | |
| void cmStateDirectory::PrependIncludeDirectoriesEntry( | |
| const BT<std::string>& vec) | |
| { | |
| auto entryEnd = this->DirectoryState->IncludeDirectories.begin() + | |
| this->Snapshot_.Position->IncludeDirectoryPosition; | |
| auto rend = this->DirectoryState->IncludeDirectories.rend(); | |
| auto rbegin = cm::make_reverse_iterator(entryEnd); | |
| rbegin = std::find(rbegin, rend, cmStateDetail::PropertySentinel); | |
| auto entryIt = rbegin.base(); | |
| this->DirectoryState->IncludeDirectories.insert(entryIt, vec); | |
| this->Snapshot_.Position->IncludeDirectoryPosition = | |
| this->DirectoryState->IncludeDirectories.size(); | |
| } | |
| void cmStateDirectory::SetIncludeDirectories(const BT<std::string>& vec) | |
| { | |
| SetContent(this->DirectoryState->IncludeDirectories, | |
| this->Snapshot_.Position->IncludeDirectoryPosition, vec); | |
| } | |
| void cmStateDirectory::ClearIncludeDirectories() | |
| { | |
| ClearContent(this->DirectoryState->IncludeDirectories, | |
| this->Snapshot_.Position->IncludeDirectoryPosition); | |
| } | |
| cmBTStringRange cmStateDirectory::GetCompileDefinitionsEntries() const | |
| { | |
| return GetPropertyContent( | |
| this->DirectoryState->CompileDefinitions, | |
| this->Snapshot_.Position->CompileDefinitionsPosition); | |
| } | |
| void cmStateDirectory::AppendCompileDefinitionsEntry( | |
| const BT<std::string>& vec) | |
| { | |
| AppendEntry(this->DirectoryState->CompileDefinitions, | |
| this->Snapshot_.Position->CompileDefinitionsPosition, vec); | |
| } | |
| void cmStateDirectory::SetCompileDefinitions(const BT<std::string>& vec) | |
| { | |
| SetContent(this->DirectoryState->CompileDefinitions, | |
| this->Snapshot_.Position->CompileDefinitionsPosition, vec); | |
| } | |
| void cmStateDirectory::ClearCompileDefinitions() | |
| { | |
| ClearContent(this->DirectoryState->CompileDefinitions, | |
| this->Snapshot_.Position->CompileDefinitionsPosition); | |
| } | |
| cmBTStringRange cmStateDirectory::GetCompileOptionsEntries() const | |
| { | |
| return GetPropertyContent(this->DirectoryState->CompileOptions, | |
| this->Snapshot_.Position->CompileOptionsPosition); | |
| } | |
| void cmStateDirectory::AppendCompileOptionsEntry(const BT<std::string>& vec) | |
| { | |
| AppendEntry(this->DirectoryState->CompileOptions, | |
| this->Snapshot_.Position->CompileOptionsPosition, vec); | |
| } | |
| void cmStateDirectory::SetCompileOptions(const BT<std::string>& vec) | |
| { | |
| SetContent(this->DirectoryState->CompileOptions, | |
| this->Snapshot_.Position->CompileOptionsPosition, vec); | |
| } | |
| void cmStateDirectory::ClearCompileOptions() | |
| { | |
| ClearContent(this->DirectoryState->CompileOptions, | |
| this->Snapshot_.Position->CompileOptionsPosition); | |
| } | |
| cmBTStringRange cmStateDirectory::GetLinkOptionsEntries() const | |
| { | |
| return GetPropertyContent(this->DirectoryState->LinkOptions, | |
| this->Snapshot_.Position->LinkOptionsPosition); | |
| } | |
| void cmStateDirectory::AppendLinkOptionsEntry(const BT<std::string>& vec) | |
| { | |
| AppendEntry(this->DirectoryState->LinkOptions, | |
| this->Snapshot_.Position->LinkOptionsPosition, vec); | |
| } | |
| void cmStateDirectory::SetLinkOptions(const BT<std::string>& vec) | |
| { | |
| SetContent(this->DirectoryState->LinkOptions, | |
| this->Snapshot_.Position->LinkOptionsPosition, vec); | |
| } | |
| void cmStateDirectory::ClearLinkOptions() | |
| { | |
| ClearContent(this->DirectoryState->LinkOptions, | |
| this->Snapshot_.Position->LinkOptionsPosition); | |
| } | |
| cmBTStringRange cmStateDirectory::GetLinkDirectoriesEntries() const | |
| { | |
| return GetPropertyContent(this->DirectoryState->LinkDirectories, | |
| this->Snapshot_.Position->LinkDirectoriesPosition); | |
| } | |
| void cmStateDirectory::AppendLinkDirectoriesEntry(const BT<std::string>& vec) | |
| { | |
| AppendEntry(this->DirectoryState->LinkDirectories, | |
| this->Snapshot_.Position->LinkDirectoriesPosition, vec); | |
| } | |
| void cmStateDirectory::PrependLinkDirectoriesEntry(const BT<std::string>& vec) | |
| { | |
| auto entryEnd = this->DirectoryState->LinkDirectories.begin() + | |
| this->Snapshot_.Position->LinkDirectoriesPosition; | |
| auto rend = this->DirectoryState->LinkDirectories.rend(); | |
| auto rbegin = cm::make_reverse_iterator(entryEnd); | |
| rbegin = std::find(rbegin, rend, cmStateDetail::PropertySentinel); | |
| auto entryIt = rbegin.base(); | |
| this->DirectoryState->LinkDirectories.insert(entryIt, vec); | |
| this->Snapshot_.Position->LinkDirectoriesPosition = | |
| this->DirectoryState->LinkDirectories.size(); | |
| } | |
| void cmStateDirectory::SetLinkDirectories(const BT<std::string>& vec) | |
| { | |
| SetContent(this->DirectoryState->LinkDirectories, | |
| this->Snapshot_.Position->LinkDirectoriesPosition, vec); | |
| } | |
| void cmStateDirectory::ClearLinkDirectories() | |
| { | |
| ClearContent(this->DirectoryState->LinkDirectories, | |
| this->Snapshot_.Position->LinkDirectoriesPosition); | |
| } | |
| void cmStateDirectory::SetProperty(std::string const& prop, cmValue value, | |
| cmListFileBacktrace const& lfbt) | |
| { | |
| if (prop == "INCLUDE_DIRECTORIES") { | |
| if (!value) { | |
| this->ClearIncludeDirectories(); | |
| return; | |
| } | |
| this->SetIncludeDirectories(BT<std::string>(value, lfbt)); | |
| return; | |
| } | |
| if (prop == "COMPILE_OPTIONS") { | |
| if (!value) { | |
| this->ClearCompileOptions(); | |
| return; | |
| } | |
| this->SetCompileOptions(BT<std::string>(value, lfbt)); | |
| return; | |
| } | |
| if (prop == "COMPILE_DEFINITIONS") { | |
| if (!value) { | |
| this->ClearCompileDefinitions(); | |
| return; | |
| } | |
| this->SetCompileDefinitions(BT<std::string>(value, lfbt)); | |
| return; | |
| } | |
| if (prop == "LINK_OPTIONS") { | |
| if (!value) { | |
| this->ClearLinkOptions(); | |
| return; | |
| } | |
| this->SetLinkOptions(BT<std::string>(value, lfbt)); | |
| return; | |
| } | |
| if (prop == "LINK_DIRECTORIES") { | |
| if (!value) { | |
| this->ClearLinkDirectories(); | |
| return; | |
| } | |
| this->SetLinkDirectories(BT<std::string>(value, lfbt)); | |
| return; | |
| } | |
| this->DirectoryState->Properties.SetProperty(prop, value); | |
| } | |
| void cmStateDirectory::AppendProperty(std::string const& prop, | |
| std::string const& value, bool asString, | |
| cmListFileBacktrace const& lfbt) | |
| { | |
| if (prop == "INCLUDE_DIRECTORIES") { | |
| this->AppendIncludeDirectoriesEntry(BT<std::string>(value, lfbt)); | |
| return; | |
| } | |
| if (prop == "COMPILE_OPTIONS") { | |
| this->AppendCompileOptionsEntry(BT<std::string>(value, lfbt)); | |
| return; | |
| } | |
| if (prop == "COMPILE_DEFINITIONS") { | |
| this->AppendCompileDefinitionsEntry(BT<std::string>(value, lfbt)); | |
| return; | |
| } | |
| if (prop == "LINK_OPTIONS") { | |
| this->AppendLinkOptionsEntry(BT<std::string>(value, lfbt)); | |
| return; | |
| } | |
| if (prop == "LINK_DIRECTORIES") { | |
| this->AppendLinkDirectoriesEntry(BT<std::string>(value, lfbt)); | |
| return; | |
| } | |
| this->DirectoryState->Properties.AppendProperty(prop, value, asString); | |
| } | |
| cmValue cmStateDirectory::GetProperty(std::string const& prop) const | |
| { | |
| bool const chain = | |
| this->Snapshot_.State->IsPropertyChained(prop, cmProperty::DIRECTORY); | |
| return this->GetProperty(prop, chain); | |
| } | |
| cmValue cmStateDirectory::GetProperty(std::string const& prop, | |
| bool chain) const | |
| { | |
| static std::string output; | |
| output.clear(); | |
| if (prop == "PARENT_DIRECTORY") { | |
| cmStateSnapshot parent = this->Snapshot_.GetBuildsystemDirectoryParent(); | |
| if (parent.IsValid()) { | |
| return cmValue(parent.GetDirectory().GetCurrentSource()); | |
| } | |
| return cmValue(output); | |
| } | |
| if (prop == kBINARY_DIR) { | |
| output = this->GetCurrentBinary(); | |
| return cmValue(output); | |
| } | |
| if (prop == kSOURCE_DIR) { | |
| output = this->GetCurrentSource(); | |
| return cmValue(output); | |
| } | |
| if (prop == kSUBDIRECTORIES) { | |
| std::vector<std::string> child_dirs; | |
| std::vector<cmStateSnapshot> const& children = | |
| this->DirectoryState->Children; | |
| child_dirs.reserve(children.size()); | |
| for (cmStateSnapshot const& ci : children) { | |
| child_dirs.push_back(ci.GetDirectory().GetCurrentSource()); | |
| } | |
| output = cmList::to_string(child_dirs); | |
| return cmValue(output); | |
| } | |
| if (prop == kBUILDSYSTEM_TARGETS) { | |
| output = cmList::to_string(this->DirectoryState->NormalTargetNames); | |
| return cmValue(output); | |
| } | |
| if (prop == "IMPORTED_TARGETS"_s) { | |
| output = cmList::to_string(this->DirectoryState->ImportedTargetNames); | |
| return cmValue(output); | |
| } | |
| if (prop == "RULES"_s) { | |
| output = cmList::to_string(this->DirectoryState->RuleNames); | |
| return cmValue(output); | |
| } | |
| if (prop == "LISTFILE_STACK") { | |
| std::vector<std::string> listFiles; | |
| cmStateSnapshot snp = this->Snapshot_; | |
| while (snp.IsValid()) { | |
| listFiles.push_back(snp.GetExecutionListFile()); | |
| snp = snp.GetCallStackParent(); | |
| } | |
| std::reverse(listFiles.begin(), listFiles.end()); | |
| output = cmList::to_string(listFiles); | |
| return cmValue(output); | |
| } | |
| if (prop == "CACHE_VARIABLES") { | |
| output = cmList::to_string(this->Snapshot_.State->GetCacheEntryKeys()); | |
| return cmValue(output); | |
| } | |
| if (prop == "VARIABLES") { | |
| std::vector<std::string> res = this->Snapshot_.ClosureKeys(); | |
| cm::append(res, this->Snapshot_.State->GetCacheEntryKeys()); | |
| std::sort(res.begin(), res.end()); | |
| output = cmList::to_string(res); | |
| return cmValue(output); | |
| } | |
| if (prop == "INCLUDE_DIRECTORIES") { | |
| output = cmList::to_string(this->GetIncludeDirectoriesEntries()); | |
| return cmValue(output); | |
| } | |
| if (prop == "COMPILE_OPTIONS") { | |
| output = cmList::to_string(this->GetCompileOptionsEntries()); | |
| return cmValue(output); | |
| } | |
| if (prop == "COMPILE_DEFINITIONS") { | |
| output = cmList::to_string(this->GetCompileDefinitionsEntries()); | |
| return cmValue(output); | |
| } | |
| if (prop == "LINK_OPTIONS") { | |
| output = cmList::to_string(this->GetLinkOptionsEntries()); | |
| return cmValue(output); | |
| } | |
| if (prop == "LINK_DIRECTORIES") { | |
| output = cmList::to_string(this->GetLinkDirectoriesEntries()); | |
| return cmValue(output); | |
| } | |
| cmValue retVal = this->DirectoryState->Properties.GetPropertyValue(prop); | |
| if (!retVal && chain) { | |
| cmStateSnapshot parentSnapshot = | |
| this->Snapshot_.GetBuildsystemDirectoryParent(); | |
| if (parentSnapshot.IsValid()) { | |
| return parentSnapshot.GetDirectory().GetProperty(prop, chain); | |
| } | |
| return this->Snapshot_.State->GetGlobalProperty(prop); | |
| } | |
| return retVal; | |
| } | |
| bool cmStateDirectory::GetPropertyAsBool(std::string const& prop) const | |
| { | |
| return this->GetProperty(prop).IsOn(); | |
| } | |
| std::vector<std::string> cmStateDirectory::GetPropertyKeys() const | |
| { | |
| return this->DirectoryState->Properties.GetKeys(); | |
| } | |
| void cmStateDirectory::AddNormalTargetName(std::string const& name) | |
| { | |
| this->DirectoryState->NormalTargetNames.push_back(name); | |
| } | |
| void cmStateDirectory::AddImportedTargetName(std::string const& name) | |
| { | |
| this->DirectoryState->ImportedTargetNames.emplace_back(name); | |
| } | |
| void cmStateDirectory::AddRuleName(std::string const& name) | |
| { | |
| this->DirectoryState->RuleNames.push_back(name); | |
| } |