From e0a84904eb38e145c3a4d4e4ef5d7aceb3c2d196 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Tue, 18 Oct 2016 21:28:49 +0200 Subject: cmState: Split auxiliary classes into separate files Port dependents to the new locations as needed. Leave behind a cmState.h include in cmListFileCache to reduce noise. It is removed in a following commit. --- Source/CMakeLists.txt | 4 + Source/cmCommonTargetGenerator.cxx | 1 + Source/cmDependsFortran.cxx | 1 + Source/cmGlobalGenerator.h | 3 +- Source/cmGlobalUnixMakefileGenerator3.cxx | 2 + Source/cmLinkLineComputer.cxx | 1 + Source/cmLinkLineComputer.h | 2 +- Source/cmListFileCache.h | 1 + Source/cmLocalGenerator.cxx | 2 + Source/cmLocalUnixMakefileGenerator3.cxx | 2 + Source/cmMakefile.cxx | 2 + Source/cmMakefile.h | 2 +- Source/cmOutputConverter.cxx | 2 + Source/cmOutputConverter.h | 2 +- Source/cmQtAutoGenerators.cxx | 2 + Source/cmState.cxx | 994 +----------------------------- Source/cmState.h | 135 ---- Source/cmStateDirectory.cxx | 518 ++++++++++++++++ Source/cmStateDirectory.h | 82 +++ Source/cmStatePrivate.h | 94 +++ Source/cmStateSnapshot.cxx | 415 +++++++++++++ Source/cmStateSnapshot.h | 88 +++ Source/cmake.h | 2 +- Source/cmcmd.cxx | 2 +- bootstrap | 2 + 25 files changed, 1228 insertions(+), 1133 deletions(-) create mode 100644 Source/cmStateDirectory.cxx create mode 100644 Source/cmStateDirectory.h create mode 100644 Source/cmStatePrivate.h create mode 100644 Source/cmStateSnapshot.cxx create mode 100644 Source/cmStateSnapshot.h diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 3124f81..2b8c17c 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -360,6 +360,10 @@ set(SRCS cmSourceGroup.h cmState.cxx cmState.h + cmStateDirectory.cxx + cmStateDirectory.h + cmStateSnapshot.cxx + cmStateSnapshot.h cmStateTypes.h cmSystemTools.cxx cmSystemTools.h diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx index 4d900b6..95b95c1 100644 --- a/Source/cmCommonTargetGenerator.cxx +++ b/Source/cmCommonTargetGenerator.cxx @@ -17,6 +17,7 @@ #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmSourceFile.h" +#include "cmStateDirectory.h" #include "cmStateTypes.h" cmCommonTargetGenerator::cmCommonTargetGenerator(cmGeneratorTarget* gt) diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx index aaa9d3a..c8723d0 100644 --- a/Source/cmDependsFortran.cxx +++ b/Source/cmDependsFortran.cxx @@ -7,6 +7,7 @@ #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmOutputConverter.h" +#include "cmStateDirectory.h" #include "cmSystemTools.h" #include diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 959fe32..9cc6724 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -6,7 +6,8 @@ #include #include "cmExportSetMap.h" -#include "cmState.h" +#include "cmStateDirectory.h" +#include "cmStateSnapshot.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cmTargetDepend.h" diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index 3433d75..17d49e8 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -12,6 +12,8 @@ #include "cmMakefile.h" #include "cmMakefileTargetGenerator.h" #include "cmOutputConverter.h" +#include "cmState.h" +#include "cmStateDirectory.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cmTargetDepend.h" diff --git a/Source/cmLinkLineComputer.cxx b/Source/cmLinkLineComputer.cxx index f6d5e70..c271246 100644 --- a/Source/cmLinkLineComputer.cxx +++ b/Source/cmLinkLineComputer.cxx @@ -5,6 +5,7 @@ #include "cmComputeLinkInformation.h" #include "cmGeneratorTarget.h" #include "cmOutputConverter.h" +#include "cmStateDirectory.h" cmLinkLineComputer::cmLinkLineComputer(cmOutputConverter* outputConverter, cmStateDirectory stateDir) diff --git a/Source/cmLinkLineComputer.h b/Source/cmLinkLineComputer.h index 59e7357..6bbb69e 100644 --- a/Source/cmLinkLineComputer.h +++ b/Source/cmLinkLineComputer.h @@ -4,7 +4,7 @@ #ifndef cmLinkLineComputer_h #define cmLinkLineComputer_h -#include "cmState.h" +#include "cmStateDirectory.h" class cmComputeLinkInformation; class cmOutputConverter; diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h index 83aac51..9af00b2 100644 --- a/Source/cmListFileCache.h +++ b/Source/cmListFileCache.h @@ -10,6 +10,7 @@ #include #include "cmState.h" +#include "cmStateSnapshot.h" /** \class cmListFileCache * \brief A class to cache list file contents. diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index d90094b..4aecb1d 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -16,6 +16,8 @@ #include "cmMakefile.h" #include "cmRulePlaceholderExpander.h" #include "cmSourceFile.h" +#include "cmState.h" +#include "cmStateDirectory.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cmTestGenerator.h" diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index eda604d..4f81ef1 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -16,6 +16,8 @@ #include "cmOutputConverter.h" #include "cmRulePlaceholderExpander.h" #include "cmSourceFile.h" +#include "cmState.h" +#include "cmStateDirectory.h" #include "cmStateTypes.h" #include "cmSystemTools.h" #include "cmVersion.h" diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 28912c3..00c0e82 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -17,6 +17,8 @@ #include "cmListFileCache.h" #include "cmSourceFile.h" #include "cmSourceFileLocation.h" +#include "cmState.h" +#include "cmStateDirectory.h" #include "cmStateTypes.h" #include "cmSystemTools.h" #include "cmTest.h" diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 8ac0e33..b61e81b 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -9,7 +9,7 @@ #include "cmListFileCache.h" #include "cmNewLineStyle.h" #include "cmPolicies.h" -#include "cmState.h" +#include "cmStateSnapshot.h" #include "cmTarget.h" #include "cmTargetLinkLibraryType.h" #include "cmake.h" diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx index c219fdf..445ad0b 100644 --- a/Source/cmOutputConverter.cxx +++ b/Source/cmOutputConverter.cxx @@ -3,6 +3,8 @@ #include "cmOutputConverter.h" #include "cmAlgorithms.h" +#include "cmState.h" +#include "cmStateDirectory.h" #include "cmSystemTools.h" #include diff --git a/Source/cmOutputConverter.h b/Source/cmOutputConverter.h index 2a81dab..dabb091 100644 --- a/Source/cmOutputConverter.h +++ b/Source/cmOutputConverter.h @@ -5,7 +5,7 @@ #include // IWYU pragma: keep -#include "cmState.h" +#include "cmStateSnapshot.h" #include #include diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index dca0f69..f56f575 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -7,6 +7,8 @@ #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmOutputConverter.h" +#include "cmState.h" +#include "cmStateDirectory.h" #include "cmStateTypes.h" #include "cmSystemTools.h" #include "cm_auto_ptr.hxx" diff --git a/Source/cmState.cxx b/Source/cmState.cxx index 32fe66c..0d1eb3e 100644 --- a/Source/cmState.cxx +++ b/Source/cmState.cxx @@ -2,6 +2,8 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmState.h" +#include "cmStatePrivate.h" + #include "cmAlgorithms.h" #include "cmCacheManager.h" #include "cmCommand.h" @@ -9,7 +11,6 @@ #include "cmListFileCache.h" #include "cmSystemTools.h" #include "cmTypeMacro.h" -#include "cmVersion.h" #include "cmake.h" #include @@ -20,85 +21,6 @@ #include #include -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"; - -struct cmStateDetail::SnapshotDataType -{ - cmStateDetail::PositionType ScopeParent; - cmStateDetail::PositionType DirectoryParent; - cmLinkedTree::iterator Policies; - cmLinkedTree::iterator PolicyRoot; - cmLinkedTree::iterator PolicyScope; - cmStateEnums::SnapshotType SnapshotType; - bool Keep; - cmLinkedTree::iterator ExecutionListFile; - cmLinkedTree::iterator - BuildSystemDirectory; - cmLinkedTree::iterator Vars; - cmLinkedTree::iterator Root; - cmLinkedTree::iterator Parent; - std::vector::size_type IncludeDirectoryPosition; - std::vector::size_type CompileDefinitionsPosition; - std::vector::size_type CompileOptionsPosition; -}; - -struct cmStateDetail::PolicyStackEntry : public cmPolicies::PolicyMap -{ - typedef cmPolicies::PolicyMap derived; - PolicyStackEntry(bool w = false) - : derived() - , Weak(w) - { - } - PolicyStackEntry(derived const& d, bool w) - : derived(d) - , Weak(w) - { - } - PolicyStackEntry(PolicyStackEntry const& r) - : derived(r) - , Weak(r.Weak) - { - } - bool Weak; -}; - -struct cmStateDetail::BuildsystemDirectoryStateType -{ - cmStateDetail::PositionType DirectoryEnd; - - std::string Location; - std::string OutputLocation; - - // The top-most directories for relative path conversion. Both the - // source and destination location of a relative path conversion - // must be underneath one of these directories (both under source or - // both under binary) in order for the relative path to be evaluated - // safely by the build tools. - std::string RelativePathTopSource; - std::string RelativePathTopBinary; - - std::vector IncludeDirectories; - std::vector IncludeDirectoryBacktraces; - - std::vector CompileDefinitions; - std::vector CompileDefinitionsBacktraces; - - std::vector CompileOptions; - std::vector CompileOptionsBacktraces; - - std::vector NormalTargetNames; - - std::string ProjectName; - - cmPropertyMap Properties; - - std::vector Children; -}; - cmState::cmState() : IsInTryCompile(false) , WindowsShell(false) @@ -676,70 +598,6 @@ const char* cmState::GetBinaryDirectory() const return this->BinaryDirectory.c_str(); } -void cmStateDirectory::ComputeRelativePathTopSource() -{ - // Relative path conversion inside the source tree is not used to - // construct relative paths passed to build tools so it is safe to use - // even when the source is a network path. - - cmStateSnapshot snapshot = this->Snapshot_; - std::vector snapshots; - snapshots.push_back(snapshot); - while (true) { - snapshot = snapshot.GetBuildsystemDirectoryParent(); - if (snapshot.IsValid()) { - snapshots.push_back(snapshot); - } else { - break; - } - } - - std::string result = snapshots.front().GetDirectory().GetCurrentSource(); - - for (std::vector::const_iterator it = snapshots.begin() + 1; - it != snapshots.end(); ++it) { - std::string currentSource = it->GetDirectory().GetCurrentSource(); - if (cmSystemTools::IsSubDirectory(result, currentSource)) { - result = currentSource; - } - } - this->DirectoryState->RelativePathTopSource = result; -} - -void cmStateDirectory::ComputeRelativePathTopBinary() -{ - cmStateSnapshot snapshot = this->Snapshot_; - std::vector snapshots; - snapshots.push_back(snapshot); - while (true) { - snapshot = snapshot.GetBuildsystemDirectoryParent(); - if (snapshot.IsValid()) { - snapshots.push_back(snapshot); - } else { - break; - } - } - - std::string result = snapshots.front().GetDirectory().GetCurrentBinary(); - - for (std::vector::const_iterator it = snapshots.begin() + 1; - it != snapshots.end(); ++it) { - std::string currentBinary = it->GetDirectory().GetCurrentBinary(); - if (cmSystemTools::IsSubDirectory(result, currentBinary)) { - result = currentBinary; - } - } - - // The current working directory on Windows cannot be a network - // path. Therefore relative paths cannot work when the binary tree - // is a network path. - if (result.size() < 2 || result.substr(0, 2) != "//") { - this->DirectoryState->RelativePathTopBinary = result; - } else { - this->DirectoryState->RelativePathTopBinary = ""; - } -} - cmStateSnapshot cmState::CreateBaseSnapshot() { cmStateDetail::PositionType pos = @@ -923,854 +781,6 @@ cmStateSnapshot cmState::Pop(cmStateSnapshot originSnapshot) return cmStateSnapshot(this, prevPos); } -cmStateSnapshot::cmStateSnapshot(cmState* state) - : State(state) - , Position() -{ -} - -std::vector cmStateSnapshot::GetChildren() -{ - return this->Position->BuildSystemDirectory->Children; -} - -cmStateSnapshot::cmStateSnapshot(cmState* state, - cmStateDetail::PositionType position) - : State(state) - , Position(position) -{ -} - -cmStateEnums::SnapshotType cmStateSnapshot::GetType() const -{ - return this->Position->SnapshotType; -} - -const char* cmStateDirectory::GetCurrentSource() const -{ - return this->DirectoryState->Location.c_str(); -} - -void cmStateDirectory::SetCurrentSource(std::string const& dir) -{ - std::string& loc = this->DirectoryState->Location; - loc = dir; - cmSystemTools::ConvertToUnixSlashes(loc); - loc = cmSystemTools::CollapseFullPath(loc); - - this->ComputeRelativePathTopSource(); - - this->Snapshot_.SetDefinition("CMAKE_CURRENT_SOURCE_DIR", loc); -} - -const char* cmStateDirectory::GetCurrentBinary() const -{ - return this->DirectoryState->OutputLocation.c_str(); -} - -void cmStateDirectory::SetCurrentBinary(std::string const& dir) -{ - std::string& loc = this->DirectoryState->OutputLocation; - loc = dir; - cmSystemTools::ConvertToUnixSlashes(loc); - loc = cmSystemTools::CollapseFullPath(loc); - - this->ComputeRelativePathTopBinary(); - - this->Snapshot_.SetDefinition("CMAKE_CURRENT_BINARY_DIR", loc); -} - -void cmStateSnapshot::SetListFile(const std::string& listfile) -{ - *this->Position->ExecutionListFile = listfile; -} - -const char* cmStateDirectory::GetRelativePathTopSource() const -{ - return this->DirectoryState->RelativePathTopSource.c_str(); -} - -const char* cmStateDirectory::GetRelativePathTopBinary() const -{ - return this->DirectoryState->RelativePathTopBinary.c_str(); -} - -void cmStateDirectory::SetRelativePathTopSource(const char* dir) -{ - this->DirectoryState->RelativePathTopSource = dir; -} - -void cmStateDirectory::SetRelativePathTopBinary(const char* dir) -{ - this->DirectoryState->RelativePathTopBinary = dir; -} - -std::string cmStateSnapshot::GetExecutionListFile() const -{ - return *this->Position->ExecutionListFile; -} - -bool cmStateSnapshot::IsValid() const -{ - return this->State && this->Position.IsValid() - ? this->Position != this->State->SnapshotData.Root() - : false; -} - -cmStateSnapshot cmStateSnapshot::GetBuildsystemDirectoryParent() const -{ - cmStateSnapshot snapshot; - if (!this->State || this->Position == this->State->SnapshotData.Root()) { - return snapshot; - } - cmStateDetail::PositionType parentPos = this->Position->DirectoryParent; - if (parentPos != this->State->SnapshotData.Root()) { - snapshot = cmStateSnapshot(this->State, - parentPos->BuildSystemDirectory->DirectoryEnd); - } - - return snapshot; -} - -cmStateSnapshot cmStateSnapshot::GetCallStackParent() const -{ - assert(this->State); - assert(this->Position != this->State->SnapshotData.Root()); - - cmStateSnapshot snapshot; - cmStateDetail::PositionType parentPos = this->Position; - while (parentPos->SnapshotType == cmStateEnums::PolicyScopeType || - parentPos->SnapshotType == cmStateEnums::VariableScopeType) { - ++parentPos; - } - if (parentPos->SnapshotType == cmStateEnums::BuildsystemDirectoryType || - parentPos->SnapshotType == cmStateEnums::BaseType) { - return snapshot; - } - - ++parentPos; - while (parentPos->SnapshotType == cmStateEnums::PolicyScopeType || - parentPos->SnapshotType == cmStateEnums::VariableScopeType) { - ++parentPos; - } - - if (parentPos == this->State->SnapshotData.Root()) { - return snapshot; - } - - snapshot = cmStateSnapshot(this->State, parentPos); - return snapshot; -} - -cmStateSnapshot cmStateSnapshot::GetCallStackBottom() const -{ - assert(this->State); - assert(this->Position != this->State->SnapshotData.Root()); - - cmStateDetail::PositionType pos = this->Position; - while (pos->SnapshotType != cmStateEnums::BaseType && - pos->SnapshotType != cmStateEnums::BuildsystemDirectoryType && - pos != this->State->SnapshotData.Root()) { - ++pos; - } - return cmStateSnapshot(this->State, pos); -} - -void cmStateSnapshot::PushPolicy(cmPolicies::PolicyMap entry, bool weak) -{ - cmStateDetail::PositionType pos = this->Position; - pos->Policies = this->State->PolicyStack.Push( - pos->Policies, cmStateDetail::PolicyStackEntry(entry, weak)); -} - -bool cmStateSnapshot::PopPolicy() -{ - cmStateDetail::PositionType pos = this->Position; - if (pos->Policies == pos->PolicyScope) { - return false; - } - pos->Policies = this->State->PolicyStack.Pop(pos->Policies); - return true; -} - -bool cmStateSnapshot::CanPopPolicyScope() -{ - return this->Position->Policies == this->Position->PolicyScope; -} - -void cmStateSnapshot::SetPolicy(cmPolicies::PolicyID id, - cmPolicies::PolicyStatus status) -{ - // Update the policy stack from the top to the top-most strong entry. - bool previous_was_weak = true; - for (cmLinkedTree::iterator psi = - this->Position->Policies; - previous_was_weak && psi != this->Position->PolicyRoot; ++psi) { - psi->Set(id, status); - previous_was_weak = psi->Weak; - } -} - -cmPolicies::PolicyStatus cmStateSnapshot::GetPolicy( - cmPolicies::PolicyID id) const -{ - cmPolicies::PolicyStatus status = cmPolicies::GetPolicyStatus(id); - - if (status == cmPolicies::REQUIRED_ALWAYS || - status == cmPolicies::REQUIRED_IF_USED) { - return status; - } - - cmLinkedTree::iterator dir = - this->Position->BuildSystemDirectory; - - while (true) { - assert(dir.IsValid()); - cmLinkedTree::iterator leaf = - dir->DirectoryEnd->Policies; - cmLinkedTree::iterator root = - dir->DirectoryEnd->PolicyRoot; - for (; leaf != root; ++leaf) { - if (leaf->IsDefined(id)) { - status = leaf->Get(id); - return status; - } - } - cmStateDetail::PositionType e = dir->DirectoryEnd; - cmStateDetail::PositionType p = e->DirectoryParent; - if (p == this->State->SnapshotData.Root()) { - break; - } - dir = p->BuildSystemDirectory; - } - return status; -} - -bool cmStateSnapshot::HasDefinedPolicyCMP0011() -{ - return !this->Position->Policies->IsEmpty(); -} - -const char* cmStateSnapshot::GetDefinition(std::string const& name) const -{ - assert(this->Position->Vars.IsValid()); - return cmDefinitions::Get(name, this->Position->Vars, this->Position->Root); -} - -bool cmStateSnapshot::IsInitialized(std::string const& name) const -{ - return cmDefinitions::HasKey(name, this->Position->Vars, - this->Position->Root); -} - -void cmStateSnapshot::SetDefinition(std::string const& name, - std::string const& value) -{ - this->Position->Vars->Set(name, value.c_str()); -} - -void cmStateSnapshot::RemoveDefinition(std::string const& name) -{ - this->Position->Vars->Set(name, CM_NULLPTR); -} - -std::vector cmStateSnapshot::UnusedKeys() const -{ - return this->Position->Vars->UnusedKeys(); -} - -std::vector cmStateSnapshot::ClosureKeys() const -{ - return cmDefinitions::ClosureKeys(this->Position->Vars, - this->Position->Root); -} - -bool cmStateSnapshot::RaiseScope(std::string const& var, const char* varDef) -{ - if (this->Position->ScopeParent == this->Position->DirectoryParent) { - cmStateSnapshot parentDir = this->GetBuildsystemDirectoryParent(); - if (!parentDir.IsValid()) { - return false; - } - // Update the definition in the parent directory top scope. This - // directory's scope was initialized by the closure of the parent - // scope, so we do not need to localize the definition first. - if (varDef) { - parentDir.SetDefinition(var, varDef); - } else { - parentDir.RemoveDefinition(var); - } - return true; - } - // First localize the definition in the current scope. - cmDefinitions::Raise(var, this->Position->Vars, this->Position->Root); - - // Now update the definition in the parent scope. - this->Position->Parent->Set(var, varDef); - return true; -} - -static const std::string cmPropertySentinal = std::string(); - -template -void InitializeContentFromParent(T& parentContent, T& thisContent, - U& parentBacktraces, U& thisBacktraces, - V& contentEndPosition) -{ - std::vector::const_iterator parentBegin = parentContent.begin(); - std::vector::const_iterator parentEnd = parentContent.end(); - - std::vector::const_reverse_iterator parentRbegin = - cmMakeReverseIterator(parentEnd); - std::vector::const_reverse_iterator parentRend = - parentContent.rend(); - parentRbegin = std::find(parentRbegin, parentRend, cmPropertySentinal); - std::vector::const_iterator parentIt = parentRbegin.base(); - - thisContent = std::vector(parentIt, parentEnd); - - std::vector::const_iterator btIt = - parentBacktraces.begin() + std::distance(parentBegin, parentIt); - std::vector::const_iterator btEnd = - parentBacktraces.end(); - - thisBacktraces = std::vector(btIt, btEnd); - - contentEndPosition = thisContent.size(); -} - -void cmStateSnapshot::SetDefaultDefinitions() -{ -/* Up to CMake 2.4 here only WIN32, UNIX and APPLE were set. - With CMake must separate between target and host platform. In most cases - the tests for WIN32, UNIX and APPLE will be for the target system, so an - additional set of variables for the host system is required -> - CMAKE_HOST_WIN32, CMAKE_HOST_UNIX, CMAKE_HOST_APPLE. - WIN32, UNIX and APPLE are now set in the platform files in - Modules/Platforms/. - To keep cmake scripts (-P) and custom language and compiler modules - working, these variables are still also set here in this place, but they - will be reset in CMakeSystemSpecificInformation.cmake before the platform - files are executed. */ -#if defined(_WIN32) - this->SetDefinition("WIN32", "1"); - this->SetDefinition("CMAKE_HOST_WIN32", "1"); -#else - this->SetDefinition("UNIX", "1"); - this->SetDefinition("CMAKE_HOST_UNIX", "1"); -#endif -#if defined(__CYGWIN__) - std::string legacy; - if (cmSystemTools::GetEnv("CMAKE_LEGACY_CYGWIN_WIN32", legacy) && - cmSystemTools::IsOn(legacy.c_str())) { - this->SetDefinition("WIN32", "1"); - this->SetDefinition("CMAKE_HOST_WIN32", "1"); - } -#endif -#if defined(__APPLE__) - this->SetDefinition("APPLE", "1"); - this->SetDefinition("CMAKE_HOST_APPLE", "1"); -#endif -#if defined(__sun__) - this->SetDefinition("CMAKE_HOST_SOLARIS", "1"); -#endif - - char temp[1024]; - sprintf(temp, "%d", cmVersion::GetMinorVersion()); - this->SetDefinition("CMAKE_MINOR_VERSION", temp); - sprintf(temp, "%d", cmVersion::GetMajorVersion()); - this->SetDefinition("CMAKE_MAJOR_VERSION", temp); - sprintf(temp, "%d", cmVersion::GetPatchVersion()); - this->SetDefinition("CMAKE_PATCH_VERSION", temp); - sprintf(temp, "%d", cmVersion::GetTweakVersion()); - this->SetDefinition("CMAKE_TWEAK_VERSION", temp); - this->SetDefinition("CMAKE_VERSION", cmVersion::GetCMakeVersion()); - - this->SetDefinition("CMAKE_FILES_DIRECTORY", - cmake::GetCMakeFilesDirectory()); - - // Setup the default include file regular expression (match everything). - this->Position->BuildSystemDirectory->Properties.SetProperty( - "INCLUDE_REGULAR_EXPRESSION", "^.*$"); -} - -void cmStateSnapshot::SetDirectoryDefinitions() -{ - this->SetDefinition("CMAKE_SOURCE_DIR", this->State->GetSourceDirectory()); - this->SetDefinition("CMAKE_CURRENT_SOURCE_DIR", - this->State->GetSourceDirectory()); - this->SetDefinition("CMAKE_BINARY_DIR", this->State->GetBinaryDirectory()); - this->SetDefinition("CMAKE_CURRENT_BINARY_DIR", - this->State->GetBinaryDirectory()); -} - -void cmStateSnapshot::InitializeFromParent() -{ - cmStateDetail::PositionType parent = this->Position->DirectoryParent; - assert(this->Position->Vars.IsValid()); - assert(parent->Vars.IsValid()); - - *this->Position->Vars = - cmDefinitions::MakeClosure(parent->Vars, parent->Root); - - InitializeContentFromParent( - parent->BuildSystemDirectory->IncludeDirectories, - this->Position->BuildSystemDirectory->IncludeDirectories, - parent->BuildSystemDirectory->IncludeDirectoryBacktraces, - this->Position->BuildSystemDirectory->IncludeDirectoryBacktraces, - this->Position->IncludeDirectoryPosition); - - InitializeContentFromParent( - parent->BuildSystemDirectory->CompileDefinitions, - this->Position->BuildSystemDirectory->CompileDefinitions, - parent->BuildSystemDirectory->CompileDefinitionsBacktraces, - this->Position->BuildSystemDirectory->CompileDefinitionsBacktraces, - this->Position->CompileDefinitionsPosition); - - InitializeContentFromParent( - parent->BuildSystemDirectory->CompileOptions, - this->Position->BuildSystemDirectory->CompileOptions, - parent->BuildSystemDirectory->CompileOptionsBacktraces, - this->Position->BuildSystemDirectory->CompileOptionsBacktraces, - this->Position->CompileOptionsPosition); -} - -cmState* cmStateSnapshot::GetState() const -{ - return this->State; -} - -cmStateDirectory cmStateSnapshot::GetDirectory() const -{ - return cmStateDirectory(this->Position->BuildSystemDirectory, *this); -} - -void cmStateSnapshot::SetProjectName(const std::string& name) -{ - this->Position->BuildSystemDirectory->ProjectName = name; -} - -std::string cmStateSnapshot::GetProjectName() const -{ - return this->Position->BuildSystemDirectory->ProjectName; -} - -void cmStateSnapshot::InitializeFromParent_ForSubdirsCommand() -{ - std::string currentSrcDir = this->GetDefinition("CMAKE_CURRENT_SOURCE_DIR"); - std::string currentBinDir = this->GetDefinition("CMAKE_CURRENT_BINARY_DIR"); - this->InitializeFromParent(); - this->SetDefinition("CMAKE_SOURCE_DIR", this->State->GetSourceDirectory()); - this->SetDefinition("CMAKE_BINARY_DIR", this->State->GetBinaryDirectory()); - - this->SetDefinition("CMAKE_CURRENT_SOURCE_DIR", currentSrcDir); - this->SetDefinition("CMAKE_CURRENT_BINARY_DIR", currentBinDir); -} - -cmStateDirectory::cmStateDirectory( - cmLinkedTree::iterator iter, - const cmStateSnapshot& snapshot) - : DirectoryState(iter) - , Snapshot_(snapshot) -{ -} - -template -cmStringRange GetPropertyContent(T const& content, U contentEndPosition) -{ - std::vector::const_iterator end = - content.begin() + contentEndPosition; - - std::vector::const_reverse_iterator rbegin = - cmMakeReverseIterator(end); - rbegin = std::find(rbegin, content.rend(), cmPropertySentinal); - - return cmMakeRange(rbegin.base(), end); -} - -template -cmBacktraceRange GetPropertyBacktraces(T const& content, U const& backtraces, - V contentEndPosition) -{ - std::vector::const_iterator entryEnd = - content.begin() + contentEndPosition; - - std::vector::const_reverse_iterator rbegin = - cmMakeReverseIterator(entryEnd); - rbegin = std::find(rbegin, content.rend(), cmPropertySentinal); - - std::vector::const_iterator it = - backtraces.begin() + std::distance(content.begin(), rbegin.base()); - - std::vector::const_iterator end = backtraces.end(); - return cmMakeRange(it, end); -} - -template -void AppendEntry(T& content, U& backtraces, V& endContentPosition, - const std::string& value, const cmListFileBacktrace& lfbt) -{ - if (value.empty()) { - return; - } - - assert(endContentPosition == content.size()); - - content.push_back(value); - backtraces.push_back(lfbt); - - endContentPosition = content.size(); -} - -template -void SetContent(T& content, U& backtraces, V& endContentPosition, - const std::string& vec, const cmListFileBacktrace& lfbt) -{ - assert(endContentPosition == content.size()); - - content.resize(content.size() + 2); - backtraces.resize(backtraces.size() + 2); - - content.back() = vec; - backtraces.back() = lfbt; - - endContentPosition = content.size(); -} - -template -void ClearContent(T& content, U& backtraces, V& endContentPosition) -{ - assert(endContentPosition == content.size()); - - content.resize(content.size() + 1); - backtraces.resize(backtraces.size() + 1); - - endContentPosition = content.size(); -} - -cmStringRange cmStateDirectory::GetIncludeDirectoriesEntries() const -{ - return GetPropertyContent( - this->DirectoryState->IncludeDirectories, - this->Snapshot_.Position->IncludeDirectoryPosition); -} - -cmBacktraceRange cmStateDirectory::GetIncludeDirectoriesEntryBacktraces() const -{ - return GetPropertyBacktraces( - this->DirectoryState->IncludeDirectories, - this->DirectoryState->IncludeDirectoryBacktraces, - this->Snapshot_.Position->IncludeDirectoryPosition); -} - -void cmStateDirectory::AppendIncludeDirectoriesEntry( - const std::string& vec, const cmListFileBacktrace& lfbt) -{ - AppendEntry(this->DirectoryState->IncludeDirectories, - this->DirectoryState->IncludeDirectoryBacktraces, - this->Snapshot_.Position->IncludeDirectoryPosition, vec, lfbt); -} - -void cmStateDirectory::PrependIncludeDirectoriesEntry( - const std::string& vec, const cmListFileBacktrace& lfbt) -{ - std::vector::iterator entryEnd = - this->DirectoryState->IncludeDirectories.begin() + - this->Snapshot_.Position->IncludeDirectoryPosition; - - std::vector::reverse_iterator rend = - this->DirectoryState->IncludeDirectories.rend(); - std::vector::reverse_iterator rbegin = - cmMakeReverseIterator(entryEnd); - rbegin = std::find(rbegin, rend, cmPropertySentinal); - - std::vector::iterator entryIt = rbegin.base(); - std::vector::iterator entryBegin = - this->DirectoryState->IncludeDirectories.begin(); - - std::vector::iterator btIt = - this->DirectoryState->IncludeDirectoryBacktraces.begin() + - std::distance(entryBegin, entryIt); - - this->DirectoryState->IncludeDirectories.insert(entryIt, vec); - this->DirectoryState->IncludeDirectoryBacktraces.insert(btIt, lfbt); - - this->Snapshot_.Position->IncludeDirectoryPosition = - this->DirectoryState->IncludeDirectories.size(); -} - -void cmStateDirectory::SetIncludeDirectories(const std::string& vec, - const cmListFileBacktrace& lfbt) -{ - SetContent(this->DirectoryState->IncludeDirectories, - this->DirectoryState->IncludeDirectoryBacktraces, - this->Snapshot_.Position->IncludeDirectoryPosition, vec, lfbt); -} - -void cmStateDirectory::ClearIncludeDirectories() -{ - ClearContent(this->DirectoryState->IncludeDirectories, - this->DirectoryState->IncludeDirectoryBacktraces, - this->Snapshot_.Position->IncludeDirectoryPosition); -} - -cmStringRange cmStateDirectory::GetCompileDefinitionsEntries() const -{ - return GetPropertyContent( - this->DirectoryState->CompileDefinitions, - this->Snapshot_.Position->CompileDefinitionsPosition); -} - -cmBacktraceRange cmStateDirectory::GetCompileDefinitionsEntryBacktraces() const -{ - return GetPropertyBacktraces( - this->DirectoryState->CompileDefinitions, - this->DirectoryState->CompileDefinitionsBacktraces, - this->Snapshot_.Position->CompileDefinitionsPosition); -} - -void cmStateDirectory::AppendCompileDefinitionsEntry( - const std::string& vec, const cmListFileBacktrace& lfbt) -{ - AppendEntry(this->DirectoryState->CompileDefinitions, - this->DirectoryState->CompileDefinitionsBacktraces, - this->Snapshot_.Position->CompileDefinitionsPosition, vec, lfbt); -} - -void cmStateDirectory::SetCompileDefinitions(const std::string& vec, - const cmListFileBacktrace& lfbt) -{ - SetContent(this->DirectoryState->CompileDefinitions, - this->DirectoryState->CompileDefinitionsBacktraces, - this->Snapshot_.Position->CompileDefinitionsPosition, vec, lfbt); -} - -void cmStateDirectory::ClearCompileDefinitions() -{ - ClearContent(this->DirectoryState->CompileDefinitions, - this->DirectoryState->CompileDefinitionsBacktraces, - this->Snapshot_.Position->CompileDefinitionsPosition); -} - -cmStringRange cmStateDirectory::GetCompileOptionsEntries() const -{ - return GetPropertyContent(this->DirectoryState->CompileOptions, - this->Snapshot_.Position->CompileOptionsPosition); -} - -cmBacktraceRange cmStateDirectory::GetCompileOptionsEntryBacktraces() const -{ - return GetPropertyBacktraces( - this->DirectoryState->CompileOptions, - this->DirectoryState->CompileOptionsBacktraces, - this->Snapshot_.Position->CompileOptionsPosition); -} - -void cmStateDirectory::AppendCompileOptionsEntry( - const std::string& vec, const cmListFileBacktrace& lfbt) -{ - AppendEntry(this->DirectoryState->CompileOptions, - this->DirectoryState->CompileOptionsBacktraces, - this->Snapshot_.Position->CompileOptionsPosition, vec, lfbt); -} - -void cmStateDirectory::SetCompileOptions(const std::string& vec, - const cmListFileBacktrace& lfbt) -{ - SetContent(this->DirectoryState->CompileOptions, - this->DirectoryState->CompileOptionsBacktraces, - this->Snapshot_.Position->CompileOptionsPosition, vec, lfbt); -} - -void cmStateDirectory::ClearCompileOptions() -{ - ClearContent(this->DirectoryState->CompileOptions, - this->DirectoryState->CompileOptionsBacktraces, - this->Snapshot_.Position->CompileOptionsPosition); -} - -bool cmStateSnapshot::StrictWeakOrder::operator()( - const cmStateSnapshot& lhs, const cmStateSnapshot& rhs) const -{ - return lhs.Position.StrictWeakOrdered(rhs.Position); -} - -void cmStateDirectory::SetProperty(const std::string& prop, const char* value, - cmListFileBacktrace const& lfbt) -{ - if (prop == "INCLUDE_DIRECTORIES") { - if (!value) { - this->ClearIncludeDirectories(); - return; - } - this->SetIncludeDirectories(value, lfbt); - return; - } - if (prop == "COMPILE_OPTIONS") { - if (!value) { - this->ClearCompileOptions(); - return; - } - this->SetCompileOptions(value, lfbt); - return; - } - if (prop == "COMPILE_DEFINITIONS") { - if (!value) { - this->ClearCompileDefinitions(); - return; - } - this->SetCompileDefinitions(value, lfbt); - return; - } - - this->DirectoryState->Properties.SetProperty(prop, value); -} - -void cmStateDirectory::AppendProperty(const std::string& prop, - const char* value, bool asString, - cmListFileBacktrace const& lfbt) -{ - if (prop == "INCLUDE_DIRECTORIES") { - this->AppendIncludeDirectoriesEntry(value, lfbt); - return; - } - if (prop == "COMPILE_OPTIONS") { - this->AppendCompileOptionsEntry(value, lfbt); - return; - } - if (prop == "COMPILE_DEFINITIONS") { - this->AppendCompileDefinitionsEntry(value, lfbt); - return; - } - - this->DirectoryState->Properties.AppendProperty(prop, value, asString); -} - -const char* cmStateDirectory::GetProperty(const std::string& prop) const -{ - const bool chain = - this->Snapshot_.State->IsPropertyChained(prop, cmProperty::DIRECTORY); - return this->GetProperty(prop, chain); -} - -const char* cmStateDirectory::GetProperty(const std::string& prop, - bool chain) const -{ - static std::string output; - output = ""; - if (prop == "PARENT_DIRECTORY") { - cmStateSnapshot parent = this->Snapshot_.GetBuildsystemDirectoryParent(); - if (parent.IsValid()) { - return parent.GetDirectory().GetCurrentSource(); - } - return ""; - } - if (prop == kBINARY_DIR) { - output = this->GetCurrentBinary(); - return output.c_str(); - } - if (prop == kSOURCE_DIR) { - output = this->GetCurrentSource(); - return output.c_str(); - } - if (prop == kSUBDIRECTORIES) { - std::vector child_dirs; - std::vector const& children = - this->DirectoryState->Children; - for (std::vector::const_iterator ci = children.begin(); - ci != children.end(); ++ci) { - child_dirs.push_back(ci->GetDirectory().GetCurrentSource()); - } - output = cmJoin(child_dirs, ";"); - return output.c_str(); - } - if (prop == kBUILDSYSTEM_TARGETS) { - output = cmJoin(this->DirectoryState->NormalTargetNames, ";"); - return output.c_str(); - } - - if (prop == "LISTFILE_STACK") { - std::vector listFiles; - cmStateSnapshot snp = this->Snapshot_; - while (snp.IsValid()) { - listFiles.push_back(snp.GetExecutionListFile()); - snp = snp.GetCallStackParent(); - } - std::reverse(listFiles.begin(), listFiles.end()); - output = cmJoin(listFiles, ";"); - return output.c_str(); - } - if (prop == "CACHE_VARIABLES") { - output = cmJoin(this->Snapshot_.State->GetCacheEntryKeys(), ";"); - return output.c_str(); - } - if (prop == "VARIABLES") { - std::vector res = this->Snapshot_.ClosureKeys(); - std::vector cacheKeys = - this->Snapshot_.State->GetCacheEntryKeys(); - res.insert(res.end(), cacheKeys.begin(), cacheKeys.end()); - std::sort(res.begin(), res.end()); - output = cmJoin(res, ";"); - return output.c_str(); - } - if (prop == "INCLUDE_DIRECTORIES") { - output = cmJoin(this->GetIncludeDirectoriesEntries(), ";"); - return output.c_str(); - } - if (prop == "COMPILE_OPTIONS") { - output = cmJoin(this->GetCompileOptionsEntries(), ";"); - return output.c_str(); - } - if (prop == "COMPILE_DEFINITIONS") { - output = cmJoin(this->GetCompileDefinitionsEntries(), ";"); - return output.c_str(); - } - - const char* 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(const std::string& prop) const -{ - return cmSystemTools::IsOn(this->GetProperty(prop)); -} - -std::vector cmStateDirectory::GetPropertyKeys() const -{ - std::vector keys; - keys.reserve(this->DirectoryState->Properties.size()); - for (cmPropertyMap::const_iterator it = - this->DirectoryState->Properties.begin(); - it != this->DirectoryState->Properties.end(); ++it) { - keys.push_back(it->first); - } - return keys; -} - -void cmStateDirectory::AddNormalTargetName(std::string const& name) -{ - this->DirectoryState->NormalTargetNames.push_back(name); -} - -bool operator==(const cmStateSnapshot& lhs, const cmStateSnapshot& rhs) -{ - return lhs.Position == rhs.Position; -} - -bool operator!=(const cmStateSnapshot& lhs, const cmStateSnapshot& rhs) -{ - return lhs.Position != rhs.Position; -} - static bool ParseEntryWithoutType(const std::string& entry, std::string& var, std::string& value) { diff --git a/Source/cmState.h b/Source/cmState.h index 938c90b..6d74815 100644 --- a/Source/cmState.h +++ b/Source/cmState.h @@ -8,7 +8,6 @@ #include "cmAlgorithms.h" #include "cmDefinitions.h" #include "cmLinkedTree.h" -#include "cmPolicies.h" #include "cmProperty.h" #include "cmPropertyDefinitionMap.h" #include "cmPropertyMap.h" @@ -186,138 +185,4 @@ private: bool MSYSShell; }; -class cmStateSnapshot -{ -public: - cmStateSnapshot(cmState* state = CM_NULLPTR); - cmStateSnapshot(cmState* state, cmStateDetail::PositionType position); - - const char* GetDefinition(std::string const& name) const; - bool IsInitialized(std::string const& name) const; - void SetDefinition(std::string const& name, std::string const& value); - void RemoveDefinition(std::string const& name); - std::vector UnusedKeys() const; - std::vector ClosureKeys() const; - bool RaiseScope(std::string const& var, const char* varDef); - - void SetListFile(std::string const& listfile); - - std::string GetExecutionListFile() const; - - std::vector GetChildren(); - - bool IsValid() const; - cmStateSnapshot GetBuildsystemDirectoryParent() const; - cmStateSnapshot GetCallStackParent() const; - cmStateSnapshot GetCallStackBottom() const; - cmStateEnums::SnapshotType GetType() const; - - void SetPolicy(cmPolicies::PolicyID id, cmPolicies::PolicyStatus status); - cmPolicies::PolicyStatus GetPolicy(cmPolicies::PolicyID id) const; - bool HasDefinedPolicyCMP0011(); - void PushPolicy(cmPolicies::PolicyMap entry, bool weak); - bool PopPolicy(); - bool CanPopPolicyScope(); - - cmState* GetState() const; - - cmStateDirectory GetDirectory() const; - - void SetProjectName(std::string const& name); - std::string GetProjectName() const; - - void InitializeFromParent_ForSubdirsCommand(); - - struct StrictWeakOrder - { - bool operator()(const cmStateSnapshot& lhs, - const cmStateSnapshot& rhs) const; - }; - - void SetDirectoryDefinitions(); - void SetDefaultDefinitions(); - -private: - friend bool operator==(const cmStateSnapshot& lhs, - const cmStateSnapshot& rhs); - friend bool operator!=(const cmStateSnapshot& lhs, - const cmStateSnapshot& rhs); - friend class cmState; - friend class cmStateDirectory; - friend struct StrictWeakOrder; - - void InitializeFromParent(); - - cmState* State; - cmStateDetail::PositionType Position; -}; - -class cmStateDirectory -{ - cmStateDirectory( - cmLinkedTree::iterator iter, - cmStateSnapshot const& snapshot); - -public: - const char* GetCurrentSource() const; - void SetCurrentSource(std::string const& dir); - const char* GetCurrentBinary() const; - void SetCurrentBinary(std::string const& dir); - - const char* GetRelativePathTopSource() const; - const char* GetRelativePathTopBinary() const; - void SetRelativePathTopSource(const char* dir); - void SetRelativePathTopBinary(const char* dir); - - cmStringRange GetIncludeDirectoriesEntries() const; - cmBacktraceRange GetIncludeDirectoriesEntryBacktraces() const; - void AppendIncludeDirectoriesEntry(std::string const& vec, - cmListFileBacktrace const& lfbt); - void PrependIncludeDirectoriesEntry(std::string const& vec, - cmListFileBacktrace const& lfbt); - void SetIncludeDirectories(std::string const& vec, - cmListFileBacktrace const& lfbt); - void ClearIncludeDirectories(); - - cmStringRange GetCompileDefinitionsEntries() const; - cmBacktraceRange GetCompileDefinitionsEntryBacktraces() const; - void AppendCompileDefinitionsEntry(std::string const& vec, - cmListFileBacktrace const& lfbt); - void SetCompileDefinitions(std::string const& vec, - cmListFileBacktrace const& lfbt); - void ClearCompileDefinitions(); - - cmStringRange GetCompileOptionsEntries() const; - cmBacktraceRange GetCompileOptionsEntryBacktraces() const; - void AppendCompileOptionsEntry(std::string const& vec, - cmListFileBacktrace const& lfbt); - void SetCompileOptions(std::string const& vec, - cmListFileBacktrace const& lfbt); - void ClearCompileOptions(); - - void SetProperty(const std::string& prop, const char* value, - cmListFileBacktrace const& lfbt); - void AppendProperty(const std::string& prop, const char* value, - bool asString, cmListFileBacktrace const& lfbt); - const char* GetProperty(const std::string& prop) const; - const char* GetProperty(const std::string& prop, bool chain) const; - bool GetPropertyAsBool(const std::string& prop) const; - std::vector GetPropertyKeys() const; - - void AddNormalTargetName(std::string const& name); - -private: - void ComputeRelativePathTopSource(); - void ComputeRelativePathTopBinary(); - -private: - cmLinkedTree::iterator - DirectoryState; - cmStateSnapshot Snapshot_; - friend class cmStateSnapshot; -}; - -bool operator==(const cmStateSnapshot& lhs, const cmStateSnapshot& rhs); -bool operator!=(const cmStateSnapshot& lhs, const cmStateSnapshot& rhs); - #endif diff --git a/Source/cmStateDirectory.cxx b/Source/cmStateDirectory.cxx new file mode 100644 index 0000000..01e1e7e --- /dev/null +++ b/Source/cmStateDirectory.cxx @@ -0,0 +1,518 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#include "cmStateDirectory.h" +#include "cmState.h" +#include "cmStatePrivate.h" +#include "cmSystemTools.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"; + +void cmStateDirectory::ComputeRelativePathTopSource() +{ + // Relative path conversion inside the source tree is not used to + // construct relative paths passed to build tools so it is safe to use + // even when the source is a network path. + + cmStateSnapshot snapshot = this->Snapshot_; + std::vector snapshots; + snapshots.push_back(snapshot); + while (true) { + snapshot = snapshot.GetBuildsystemDirectoryParent(); + if (snapshot.IsValid()) { + snapshots.push_back(snapshot); + } else { + break; + } + } + + std::string result = snapshots.front().GetDirectory().GetCurrentSource(); + + for (std::vector::const_iterator it = snapshots.begin() + 1; + it != snapshots.end(); ++it) { + std::string currentSource = it->GetDirectory().GetCurrentSource(); + if (cmSystemTools::IsSubDirectory(result, currentSource)) { + result = currentSource; + } + } + this->DirectoryState->RelativePathTopSource = result; +} + +void cmStateDirectory::ComputeRelativePathTopBinary() +{ + cmStateSnapshot snapshot = this->Snapshot_; + std::vector snapshots; + snapshots.push_back(snapshot); + while (true) { + snapshot = snapshot.GetBuildsystemDirectoryParent(); + if (snapshot.IsValid()) { + snapshots.push_back(snapshot); + } else { + break; + } + } + + std::string result = snapshots.front().GetDirectory().GetCurrentBinary(); + + for (std::vector::const_iterator it = snapshots.begin() + 1; + it != snapshots.end(); ++it) { + std::string currentBinary = it->GetDirectory().GetCurrentBinary(); + if (cmSystemTools::IsSubDirectory(result, currentBinary)) { + result = currentBinary; + } + } + + // The current working directory on Windows cannot be a network + // path. Therefore relative paths cannot work when the binary tree + // is a network path. + if (result.size() < 2 || result.substr(0, 2) != "//") { + this->DirectoryState->RelativePathTopBinary = result; + } else { + this->DirectoryState->RelativePathTopBinary = ""; + } +} + +const char* cmStateDirectory::GetCurrentSource() const +{ + return this->DirectoryState->Location.c_str(); +} + +void cmStateDirectory::SetCurrentSource(std::string const& dir) +{ + std::string& loc = this->DirectoryState->Location; + loc = dir; + cmSystemTools::ConvertToUnixSlashes(loc); + loc = cmSystemTools::CollapseFullPath(loc); + + this->ComputeRelativePathTopSource(); + + this->Snapshot_.SetDefinition("CMAKE_CURRENT_SOURCE_DIR", loc); +} + +const char* cmStateDirectory::GetCurrentBinary() const +{ + return this->DirectoryState->OutputLocation.c_str(); +} + +void cmStateDirectory::SetCurrentBinary(std::string const& dir) +{ + std::string& loc = this->DirectoryState->OutputLocation; + loc = dir; + cmSystemTools::ConvertToUnixSlashes(loc); + loc = cmSystemTools::CollapseFullPath(loc); + + this->ComputeRelativePathTopBinary(); + + this->Snapshot_.SetDefinition("CMAKE_CURRENT_BINARY_DIR", loc); +} + +const char* cmStateDirectory::GetRelativePathTopSource() const +{ + return this->DirectoryState->RelativePathTopSource.c_str(); +} + +const char* cmStateDirectory::GetRelativePathTopBinary() const +{ + return this->DirectoryState->RelativePathTopBinary.c_str(); +} + +void cmStateDirectory::SetRelativePathTopSource(const char* dir) +{ + this->DirectoryState->RelativePathTopSource = dir; +} + +void cmStateDirectory::SetRelativePathTopBinary(const char* dir) +{ + this->DirectoryState->RelativePathTopBinary = dir; +} + +cmStateDirectory::cmStateDirectory( + cmLinkedTree::iterator iter, + const cmStateSnapshot& snapshot) + : DirectoryState(iter) + , Snapshot_(snapshot) +{ +} + +template +cmStringRange GetPropertyContent(T const& content, U contentEndPosition) +{ + std::vector::const_iterator end = + content.begin() + contentEndPosition; + + std::vector::const_reverse_iterator rbegin = + cmMakeReverseIterator(end); + rbegin = std::find(rbegin, content.rend(), cmPropertySentinal); + + return cmMakeRange(rbegin.base(), end); +} + +template +cmBacktraceRange GetPropertyBacktraces(T const& content, U const& backtraces, + V contentEndPosition) +{ + std::vector::const_iterator entryEnd = + content.begin() + contentEndPosition; + + std::vector::const_reverse_iterator rbegin = + cmMakeReverseIterator(entryEnd); + rbegin = std::find(rbegin, content.rend(), cmPropertySentinal); + + std::vector::const_iterator it = + backtraces.begin() + std::distance(content.begin(), rbegin.base()); + + std::vector::const_iterator end = backtraces.end(); + return cmMakeRange(it, end); +} + +template +void AppendEntry(T& content, U& backtraces, V& endContentPosition, + const std::string& value, const cmListFileBacktrace& lfbt) +{ + if (value.empty()) { + return; + } + + assert(endContentPosition == content.size()); + + content.push_back(value); + backtraces.push_back(lfbt); + + endContentPosition = content.size(); +} + +template +void SetContent(T& content, U& backtraces, V& endContentPosition, + const std::string& vec, const cmListFileBacktrace& lfbt) +{ + assert(endContentPosition == content.size()); + + content.resize(content.size() + 2); + backtraces.resize(backtraces.size() + 2); + + content.back() = vec; + backtraces.back() = lfbt; + + endContentPosition = content.size(); +} + +template +void ClearContent(T& content, U& backtraces, V& endContentPosition) +{ + assert(endContentPosition == content.size()); + + content.resize(content.size() + 1); + backtraces.resize(backtraces.size() + 1); + + endContentPosition = content.size(); +} + +cmStringRange cmStateDirectory::GetIncludeDirectoriesEntries() const +{ + return GetPropertyContent( + this->DirectoryState->IncludeDirectories, + this->Snapshot_.Position->IncludeDirectoryPosition); +} + +cmBacktraceRange cmStateDirectory::GetIncludeDirectoriesEntryBacktraces() const +{ + return GetPropertyBacktraces( + this->DirectoryState->IncludeDirectories, + this->DirectoryState->IncludeDirectoryBacktraces, + this->Snapshot_.Position->IncludeDirectoryPosition); +} + +void cmStateDirectory::AppendIncludeDirectoriesEntry( + const std::string& vec, const cmListFileBacktrace& lfbt) +{ + AppendEntry(this->DirectoryState->IncludeDirectories, + this->DirectoryState->IncludeDirectoryBacktraces, + this->Snapshot_.Position->IncludeDirectoryPosition, vec, lfbt); +} + +void cmStateDirectory::PrependIncludeDirectoriesEntry( + const std::string& vec, const cmListFileBacktrace& lfbt) +{ + std::vector::iterator entryEnd = + this->DirectoryState->IncludeDirectories.begin() + + this->Snapshot_.Position->IncludeDirectoryPosition; + + std::vector::reverse_iterator rend = + this->DirectoryState->IncludeDirectories.rend(); + std::vector::reverse_iterator rbegin = + cmMakeReverseIterator(entryEnd); + rbegin = std::find(rbegin, rend, cmPropertySentinal); + + std::vector::iterator entryIt = rbegin.base(); + std::vector::iterator entryBegin = + this->DirectoryState->IncludeDirectories.begin(); + + std::vector::iterator btIt = + this->DirectoryState->IncludeDirectoryBacktraces.begin() + + std::distance(entryBegin, entryIt); + + this->DirectoryState->IncludeDirectories.insert(entryIt, vec); + this->DirectoryState->IncludeDirectoryBacktraces.insert(btIt, lfbt); + + this->Snapshot_.Position->IncludeDirectoryPosition = + this->DirectoryState->IncludeDirectories.size(); +} + +void cmStateDirectory::SetIncludeDirectories(const std::string& vec, + const cmListFileBacktrace& lfbt) +{ + SetContent(this->DirectoryState->IncludeDirectories, + this->DirectoryState->IncludeDirectoryBacktraces, + this->Snapshot_.Position->IncludeDirectoryPosition, vec, lfbt); +} + +void cmStateDirectory::ClearIncludeDirectories() +{ + ClearContent(this->DirectoryState->IncludeDirectories, + this->DirectoryState->IncludeDirectoryBacktraces, + this->Snapshot_.Position->IncludeDirectoryPosition); +} + +cmStringRange cmStateDirectory::GetCompileDefinitionsEntries() const +{ + return GetPropertyContent( + this->DirectoryState->CompileDefinitions, + this->Snapshot_.Position->CompileDefinitionsPosition); +} + +cmBacktraceRange cmStateDirectory::GetCompileDefinitionsEntryBacktraces() const +{ + return GetPropertyBacktraces( + this->DirectoryState->CompileDefinitions, + this->DirectoryState->CompileDefinitionsBacktraces, + this->Snapshot_.Position->CompileDefinitionsPosition); +} + +void cmStateDirectory::AppendCompileDefinitionsEntry( + const std::string& vec, const cmListFileBacktrace& lfbt) +{ + AppendEntry(this->DirectoryState->CompileDefinitions, + this->DirectoryState->CompileDefinitionsBacktraces, + this->Snapshot_.Position->CompileDefinitionsPosition, vec, lfbt); +} + +void cmStateDirectory::SetCompileDefinitions(const std::string& vec, + const cmListFileBacktrace& lfbt) +{ + SetContent(this->DirectoryState->CompileDefinitions, + this->DirectoryState->CompileDefinitionsBacktraces, + this->Snapshot_.Position->CompileDefinitionsPosition, vec, lfbt); +} + +void cmStateDirectory::ClearCompileDefinitions() +{ + ClearContent(this->DirectoryState->CompileDefinitions, + this->DirectoryState->CompileDefinitionsBacktraces, + this->Snapshot_.Position->CompileDefinitionsPosition); +} + +cmStringRange cmStateDirectory::GetCompileOptionsEntries() const +{ + return GetPropertyContent(this->DirectoryState->CompileOptions, + this->Snapshot_.Position->CompileOptionsPosition); +} + +cmBacktraceRange cmStateDirectory::GetCompileOptionsEntryBacktraces() const +{ + return GetPropertyBacktraces( + this->DirectoryState->CompileOptions, + this->DirectoryState->CompileOptionsBacktraces, + this->Snapshot_.Position->CompileOptionsPosition); +} + +void cmStateDirectory::AppendCompileOptionsEntry( + const std::string& vec, const cmListFileBacktrace& lfbt) +{ + AppendEntry(this->DirectoryState->CompileOptions, + this->DirectoryState->CompileOptionsBacktraces, + this->Snapshot_.Position->CompileOptionsPosition, vec, lfbt); +} + +void cmStateDirectory::SetCompileOptions(const std::string& vec, + const cmListFileBacktrace& lfbt) +{ + SetContent(this->DirectoryState->CompileOptions, + this->DirectoryState->CompileOptionsBacktraces, + this->Snapshot_.Position->CompileOptionsPosition, vec, lfbt); +} + +void cmStateDirectory::ClearCompileOptions() +{ + ClearContent(this->DirectoryState->CompileOptions, + this->DirectoryState->CompileOptionsBacktraces, + this->Snapshot_.Position->CompileOptionsPosition); +} + +void cmStateDirectory::SetProperty(const std::string& prop, const char* value, + cmListFileBacktrace const& lfbt) +{ + if (prop == "INCLUDE_DIRECTORIES") { + if (!value) { + this->ClearIncludeDirectories(); + return; + } + this->SetIncludeDirectories(value, lfbt); + return; + } + if (prop == "COMPILE_OPTIONS") { + if (!value) { + this->ClearCompileOptions(); + return; + } + this->SetCompileOptions(value, lfbt); + return; + } + if (prop == "COMPILE_DEFINITIONS") { + if (!value) { + this->ClearCompileDefinitions(); + return; + } + this->SetCompileDefinitions(value, lfbt); + return; + } + + this->DirectoryState->Properties.SetProperty(prop, value); +} + +void cmStateDirectory::AppendProperty(const std::string& prop, + const char* value, bool asString, + cmListFileBacktrace const& lfbt) +{ + if (prop == "INCLUDE_DIRECTORIES") { + this->AppendIncludeDirectoriesEntry(value, lfbt); + return; + } + if (prop == "COMPILE_OPTIONS") { + this->AppendCompileOptionsEntry(value, lfbt); + return; + } + if (prop == "COMPILE_DEFINITIONS") { + this->AppendCompileDefinitionsEntry(value, lfbt); + return; + } + + this->DirectoryState->Properties.AppendProperty(prop, value, asString); +} + +const char* cmStateDirectory::GetProperty(const std::string& prop) const +{ + const bool chain = + this->Snapshot_.State->IsPropertyChained(prop, cmProperty::DIRECTORY); + return this->GetProperty(prop, chain); +} + +const char* cmStateDirectory::GetProperty(const std::string& prop, + bool chain) const +{ + static std::string output; + output = ""; + if (prop == "PARENT_DIRECTORY") { + cmStateSnapshot parent = this->Snapshot_.GetBuildsystemDirectoryParent(); + if (parent.IsValid()) { + return parent.GetDirectory().GetCurrentSource(); + } + return ""; + } + if (prop == kBINARY_DIR) { + output = this->GetCurrentBinary(); + return output.c_str(); + } + if (prop == kSOURCE_DIR) { + output = this->GetCurrentSource(); + return output.c_str(); + } + if (prop == kSUBDIRECTORIES) { + std::vector child_dirs; + std::vector const& children = + this->DirectoryState->Children; + for (std::vector::const_iterator ci = children.begin(); + ci != children.end(); ++ci) { + child_dirs.push_back(ci->GetDirectory().GetCurrentSource()); + } + output = cmJoin(child_dirs, ";"); + return output.c_str(); + } + if (prop == kBUILDSYSTEM_TARGETS) { + output = cmJoin(this->DirectoryState->NormalTargetNames, ";"); + return output.c_str(); + } + + if (prop == "LISTFILE_STACK") { + std::vector listFiles; + cmStateSnapshot snp = this->Snapshot_; + while (snp.IsValid()) { + listFiles.push_back(snp.GetExecutionListFile()); + snp = snp.GetCallStackParent(); + } + std::reverse(listFiles.begin(), listFiles.end()); + output = cmJoin(listFiles, ";"); + return output.c_str(); + } + if (prop == "CACHE_VARIABLES") { + output = cmJoin(this->Snapshot_.State->GetCacheEntryKeys(), ";"); + return output.c_str(); + } + if (prop == "VARIABLES") { + std::vector res = this->Snapshot_.ClosureKeys(); + std::vector cacheKeys = + this->Snapshot_.State->GetCacheEntryKeys(); + res.insert(res.end(), cacheKeys.begin(), cacheKeys.end()); + std::sort(res.begin(), res.end()); + output = cmJoin(res, ";"); + return output.c_str(); + } + if (prop == "INCLUDE_DIRECTORIES") { + output = cmJoin(this->GetIncludeDirectoriesEntries(), ";"); + return output.c_str(); + } + if (prop == "COMPILE_OPTIONS") { + output = cmJoin(this->GetCompileOptionsEntries(), ";"); + return output.c_str(); + } + if (prop == "COMPILE_DEFINITIONS") { + output = cmJoin(this->GetCompileDefinitionsEntries(), ";"); + return output.c_str(); + } + + const char* 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(const std::string& prop) const +{ + return cmSystemTools::IsOn(this->GetProperty(prop)); +} + +std::vector cmStateDirectory::GetPropertyKeys() const +{ + std::vector keys; + keys.reserve(this->DirectoryState->Properties.size()); + for (cmPropertyMap::const_iterator it = + this->DirectoryState->Properties.begin(); + it != this->DirectoryState->Properties.end(); ++it) { + keys.push_back(it->first); + } + return keys; +} + +void cmStateDirectory::AddNormalTargetName(std::string const& name) +{ + this->DirectoryState->NormalTargetNames.push_back(name); +} diff --git a/Source/cmStateDirectory.h b/Source/cmStateDirectory.h new file mode 100644 index 0000000..17a89d8 --- /dev/null +++ b/Source/cmStateDirectory.h @@ -0,0 +1,82 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#ifndef cmStateDirectory_h +#define cmStateDirectory_h + +#include // IWYU pragma: keep + +#include +#include + +#include "cmAlgorithms.h" +#include "cmListFileCache.h" +#include "cmStateSnapshot.h" +#include "cmStateTypes.h" + +class cmStateDirectory +{ + cmStateDirectory( + cmLinkedTree::iterator iter, + cmStateSnapshot const& snapshot); + +public: + const char* GetCurrentSource() const; + void SetCurrentSource(std::string const& dir); + const char* GetCurrentBinary() const; + void SetCurrentBinary(std::string const& dir); + + const char* GetRelativePathTopSource() const; + const char* GetRelativePathTopBinary() const; + void SetRelativePathTopSource(const char* dir); + void SetRelativePathTopBinary(const char* dir); + + cmStringRange GetIncludeDirectoriesEntries() const; + cmBacktraceRange GetIncludeDirectoriesEntryBacktraces() const; + void AppendIncludeDirectoriesEntry(std::string const& vec, + cmListFileBacktrace const& lfbt); + void PrependIncludeDirectoriesEntry(std::string const& vec, + cmListFileBacktrace const& lfbt); + void SetIncludeDirectories(std::string const& vec, + cmListFileBacktrace const& lfbt); + void ClearIncludeDirectories(); + + cmStringRange GetCompileDefinitionsEntries() const; + cmBacktraceRange GetCompileDefinitionsEntryBacktraces() const; + void AppendCompileDefinitionsEntry(std::string const& vec, + cmListFileBacktrace const& lfbt); + void SetCompileDefinitions(std::string const& vec, + cmListFileBacktrace const& lfbt); + void ClearCompileDefinitions(); + + cmStringRange GetCompileOptionsEntries() const; + cmBacktraceRange GetCompileOptionsEntryBacktraces() const; + void AppendCompileOptionsEntry(std::string const& vec, + cmListFileBacktrace const& lfbt); + void SetCompileOptions(std::string const& vec, + cmListFileBacktrace const& lfbt); + void ClearCompileOptions(); + + void SetProperty(const std::string& prop, const char* value, + cmListFileBacktrace const& lfbt); + void AppendProperty(const std::string& prop, const char* value, + bool asString, cmListFileBacktrace const& lfbt); + const char* GetProperty(const std::string& prop) const; + const char* GetProperty(const std::string& prop, bool chain) const; + bool GetPropertyAsBool(const std::string& prop) const; + std::vector GetPropertyKeys() const; + + void AddNormalTargetName(std::string const& name); + +private: + void ComputeRelativePathTopSource(); + void ComputeRelativePathTopBinary(); + +private: + cmLinkedTree::iterator + DirectoryState; + cmStateSnapshot Snapshot_; + friend class cmStateSnapshot; +}; + +#endif diff --git a/Source/cmStatePrivate.h b/Source/cmStatePrivate.h new file mode 100644 index 0000000..8daa3cf --- /dev/null +++ b/Source/cmStatePrivate.h @@ -0,0 +1,94 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#ifndef cmStatePrivate_h +#define cmStatePrivate_h + +#include // IWYU pragma: keep + +#include +#include + +#include "cmDefinitions.h" +#include "cmLinkedTree.h" +#include "cmListFileCache.h" +#include "cmPropertyMap.h" +#include "cmStateTypes.h" + +static const std::string cmPropertySentinal = std::string(); + +struct cmStateDetail::SnapshotDataType +{ + cmStateDetail::PositionType ScopeParent; + cmStateDetail::PositionType DirectoryParent; + cmLinkedTree::iterator Policies; + cmLinkedTree::iterator PolicyRoot; + cmLinkedTree::iterator PolicyScope; + cmStateEnums::SnapshotType SnapshotType; + bool Keep; + cmLinkedTree::iterator ExecutionListFile; + cmLinkedTree::iterator + BuildSystemDirectory; + cmLinkedTree::iterator Vars; + cmLinkedTree::iterator Root; + cmLinkedTree::iterator Parent; + std::vector::size_type IncludeDirectoryPosition; + std::vector::size_type CompileDefinitionsPosition; + std::vector::size_type CompileOptionsPosition; +}; + +struct cmStateDetail::PolicyStackEntry : public cmPolicies::PolicyMap +{ + typedef cmPolicies::PolicyMap derived; + PolicyStackEntry(bool w = false) + : derived() + , Weak(w) + { + } + PolicyStackEntry(derived const& d, bool w) + : derived(d) + , Weak(w) + { + } + PolicyStackEntry(PolicyStackEntry const& r) + : derived(r) + , Weak(r.Weak) + { + } + bool Weak; +}; + +struct cmStateDetail::BuildsystemDirectoryStateType +{ + cmStateDetail::PositionType DirectoryEnd; + + std::string Location; + std::string OutputLocation; + + // The top-most directories for relative path conversion. Both the + // source and destination location of a relative path conversion + // must be underneath one of these directories (both under source or + // both under binary) in order for the relative path to be evaluated + // safely by the build tools. + std::string RelativePathTopSource; + std::string RelativePathTopBinary; + + std::vector IncludeDirectories; + std::vector IncludeDirectoryBacktraces; + + std::vector CompileDefinitions; + std::vector CompileDefinitionsBacktraces; + + std::vector CompileOptions; + std::vector CompileOptionsBacktraces; + + std::vector NormalTargetNames; + + std::string ProjectName; + + cmPropertyMap Properties; + + std::vector Children; +}; + +#endif diff --git a/Source/cmStateSnapshot.cxx b/Source/cmStateSnapshot.cxx new file mode 100644 index 0000000..7f86221 --- /dev/null +++ b/Source/cmStateSnapshot.cxx @@ -0,0 +1,415 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#include "cmStateSnapshot.h" + +#include "cmState.h" +#include "cmStateDirectory.h" +#include "cmStatePrivate.h" +#include "cmSystemTools.h" +#include "cmVersion.h" +#include "cmake.h" + +cmStateSnapshot::cmStateSnapshot(cmState* state) + : State(state) + , Position() +{ +} + +std::vector cmStateSnapshot::GetChildren() +{ + return this->Position->BuildSystemDirectory->Children; +} + +cmStateSnapshot::cmStateSnapshot(cmState* state, + cmStateDetail::PositionType position) + : State(state) + , Position(position) +{ +} + +cmStateEnums::SnapshotType cmStateSnapshot::GetType() const +{ + return this->Position->SnapshotType; +} + +void cmStateSnapshot::SetListFile(const std::string& listfile) +{ + *this->Position->ExecutionListFile = listfile; +} + +std::string cmStateSnapshot::GetExecutionListFile() const +{ + return *this->Position->ExecutionListFile; +} + +bool cmStateSnapshot::IsValid() const +{ + return this->State && this->Position.IsValid() + ? this->Position != this->State->SnapshotData.Root() + : false; +} + +cmStateSnapshot cmStateSnapshot::GetBuildsystemDirectoryParent() const +{ + cmStateSnapshot snapshot; + if (!this->State || this->Position == this->State->SnapshotData.Root()) { + return snapshot; + } + cmStateDetail::PositionType parentPos = this->Position->DirectoryParent; + if (parentPos != this->State->SnapshotData.Root()) { + snapshot = cmStateSnapshot(this->State, + parentPos->BuildSystemDirectory->DirectoryEnd); + } + + return snapshot; +} + +cmStateSnapshot cmStateSnapshot::GetCallStackParent() const +{ + assert(this->State); + assert(this->Position != this->State->SnapshotData.Root()); + + cmStateSnapshot snapshot; + cmStateDetail::PositionType parentPos = this->Position; + while (parentPos->SnapshotType == cmStateEnums::PolicyScopeType || + parentPos->SnapshotType == cmStateEnums::VariableScopeType) { + ++parentPos; + } + if (parentPos->SnapshotType == cmStateEnums::BuildsystemDirectoryType || + parentPos->SnapshotType == cmStateEnums::BaseType) { + return snapshot; + } + + ++parentPos; + while (parentPos->SnapshotType == cmStateEnums::PolicyScopeType || + parentPos->SnapshotType == cmStateEnums::VariableScopeType) { + ++parentPos; + } + + if (parentPos == this->State->SnapshotData.Root()) { + return snapshot; + } + + snapshot = cmStateSnapshot(this->State, parentPos); + return snapshot; +} + +cmStateSnapshot cmStateSnapshot::GetCallStackBottom() const +{ + assert(this->State); + assert(this->Position != this->State->SnapshotData.Root()); + + cmStateDetail::PositionType pos = this->Position; + while (pos->SnapshotType != cmStateEnums::BaseType && + pos->SnapshotType != cmStateEnums::BuildsystemDirectoryType && + pos != this->State->SnapshotData.Root()) { + ++pos; + } + return cmStateSnapshot(this->State, pos); +} + +void cmStateSnapshot::PushPolicy(cmPolicies::PolicyMap entry, bool weak) +{ + cmStateDetail::PositionType pos = this->Position; + pos->Policies = this->State->PolicyStack.Push( + pos->Policies, cmStateDetail::PolicyStackEntry(entry, weak)); +} + +bool cmStateSnapshot::PopPolicy() +{ + cmStateDetail::PositionType pos = this->Position; + if (pos->Policies == pos->PolicyScope) { + return false; + } + pos->Policies = this->State->PolicyStack.Pop(pos->Policies); + return true; +} + +bool cmStateSnapshot::CanPopPolicyScope() +{ + return this->Position->Policies == this->Position->PolicyScope; +} + +void cmStateSnapshot::SetPolicy(cmPolicies::PolicyID id, + cmPolicies::PolicyStatus status) +{ + // Update the policy stack from the top to the top-most strong entry. + bool previous_was_weak = true; + for (cmLinkedTree::iterator psi = + this->Position->Policies; + previous_was_weak && psi != this->Position->PolicyRoot; ++psi) { + psi->Set(id, status); + previous_was_weak = psi->Weak; + } +} + +cmPolicies::PolicyStatus cmStateSnapshot::GetPolicy( + cmPolicies::PolicyID id) const +{ + cmPolicies::PolicyStatus status = cmPolicies::GetPolicyStatus(id); + + if (status == cmPolicies::REQUIRED_ALWAYS || + status == cmPolicies::REQUIRED_IF_USED) { + return status; + } + + cmLinkedTree::iterator dir = + this->Position->BuildSystemDirectory; + + while (true) { + assert(dir.IsValid()); + cmLinkedTree::iterator leaf = + dir->DirectoryEnd->Policies; + cmLinkedTree::iterator root = + dir->DirectoryEnd->PolicyRoot; + for (; leaf != root; ++leaf) { + if (leaf->IsDefined(id)) { + status = leaf->Get(id); + return status; + } + } + cmStateDetail::PositionType e = dir->DirectoryEnd; + cmStateDetail::PositionType p = e->DirectoryParent; + if (p == this->State->SnapshotData.Root()) { + break; + } + dir = p->BuildSystemDirectory; + } + return status; +} + +bool cmStateSnapshot::HasDefinedPolicyCMP0011() +{ + return !this->Position->Policies->IsEmpty(); +} + +const char* cmStateSnapshot::GetDefinition(std::string const& name) const +{ + assert(this->Position->Vars.IsValid()); + return cmDefinitions::Get(name, this->Position->Vars, this->Position->Root); +} + +bool cmStateSnapshot::IsInitialized(std::string const& name) const +{ + return cmDefinitions::HasKey(name, this->Position->Vars, + this->Position->Root); +} + +void cmStateSnapshot::SetDefinition(std::string const& name, + std::string const& value) +{ + this->Position->Vars->Set(name, value.c_str()); +} + +void cmStateSnapshot::RemoveDefinition(std::string const& name) +{ + this->Position->Vars->Set(name, CM_NULLPTR); +} + +std::vector cmStateSnapshot::UnusedKeys() const +{ + return this->Position->Vars->UnusedKeys(); +} + +std::vector cmStateSnapshot::ClosureKeys() const +{ + return cmDefinitions::ClosureKeys(this->Position->Vars, + this->Position->Root); +} + +bool cmStateSnapshot::RaiseScope(std::string const& var, const char* varDef) +{ + if (this->Position->ScopeParent == this->Position->DirectoryParent) { + cmStateSnapshot parentDir = this->GetBuildsystemDirectoryParent(); + if (!parentDir.IsValid()) { + return false; + } + // Update the definition in the parent directory top scope. This + // directory's scope was initialized by the closure of the parent + // scope, so we do not need to localize the definition first. + if (varDef) { + parentDir.SetDefinition(var, varDef); + } else { + parentDir.RemoveDefinition(var); + } + return true; + } + // First localize the definition in the current scope. + cmDefinitions::Raise(var, this->Position->Vars, this->Position->Root); + + // Now update the definition in the parent scope. + this->Position->Parent->Set(var, varDef); + return true; +} + +template +void InitializeContentFromParent(T& parentContent, T& thisContent, + U& parentBacktraces, U& thisBacktraces, + V& contentEndPosition) +{ + std::vector::const_iterator parentBegin = parentContent.begin(); + std::vector::const_iterator parentEnd = parentContent.end(); + + std::vector::const_reverse_iterator parentRbegin = + cmMakeReverseIterator(parentEnd); + std::vector::const_reverse_iterator parentRend = + parentContent.rend(); + parentRbegin = std::find(parentRbegin, parentRend, cmPropertySentinal); + std::vector::const_iterator parentIt = parentRbegin.base(); + + thisContent = std::vector(parentIt, parentEnd); + + std::vector::const_iterator btIt = + parentBacktraces.begin() + std::distance(parentBegin, parentIt); + std::vector::const_iterator btEnd = + parentBacktraces.end(); + + thisBacktraces = std::vector(btIt, btEnd); + + contentEndPosition = thisContent.size(); +} + +void cmStateSnapshot::SetDefaultDefinitions() +{ +/* Up to CMake 2.4 here only WIN32, UNIX and APPLE were set. + With CMake must separate between target and host platform. In most cases + the tests for WIN32, UNIX and APPLE will be for the target system, so an + additional set of variables for the host system is required -> + CMAKE_HOST_WIN32, CMAKE_HOST_UNIX, CMAKE_HOST_APPLE. + WIN32, UNIX and APPLE are now set in the platform files in + Modules/Platforms/. + To keep cmake scripts (-P) and custom language and compiler modules + working, these variables are still also set here in this place, but they + will be reset in CMakeSystemSpecificInformation.cmake before the platform + files are executed. */ +#if defined(_WIN32) + this->SetDefinition("WIN32", "1"); + this->SetDefinition("CMAKE_HOST_WIN32", "1"); +#else + this->SetDefinition("UNIX", "1"); + this->SetDefinition("CMAKE_HOST_UNIX", "1"); +#endif +#if defined(__CYGWIN__) + std::string legacy; + if (cmSystemTools::GetEnv("CMAKE_LEGACY_CYGWIN_WIN32", legacy) && + cmSystemTools::IsOn(legacy.c_str())) { + this->SetDefinition("WIN32", "1"); + this->SetDefinition("CMAKE_HOST_WIN32", "1"); + } +#endif +#if defined(__APPLE__) + this->SetDefinition("APPLE", "1"); + this->SetDefinition("CMAKE_HOST_APPLE", "1"); +#endif +#if defined(__sun__) + this->SetDefinition("CMAKE_HOST_SOLARIS", "1"); +#endif + + char temp[1024]; + sprintf(temp, "%d", cmVersion::GetMinorVersion()); + this->SetDefinition("CMAKE_MINOR_VERSION", temp); + sprintf(temp, "%d", cmVersion::GetMajorVersion()); + this->SetDefinition("CMAKE_MAJOR_VERSION", temp); + sprintf(temp, "%d", cmVersion::GetPatchVersion()); + this->SetDefinition("CMAKE_PATCH_VERSION", temp); + sprintf(temp, "%d", cmVersion::GetTweakVersion()); + this->SetDefinition("CMAKE_TWEAK_VERSION", temp); + this->SetDefinition("CMAKE_VERSION", cmVersion::GetCMakeVersion()); + + this->SetDefinition("CMAKE_FILES_DIRECTORY", + cmake::GetCMakeFilesDirectory()); + + // Setup the default include file regular expression (match everything). + this->Position->BuildSystemDirectory->Properties.SetProperty( + "INCLUDE_REGULAR_EXPRESSION", "^.*$"); +} + +void cmStateSnapshot::SetDirectoryDefinitions() +{ + this->SetDefinition("CMAKE_SOURCE_DIR", this->State->GetSourceDirectory()); + this->SetDefinition("CMAKE_CURRENT_SOURCE_DIR", + this->State->GetSourceDirectory()); + this->SetDefinition("CMAKE_BINARY_DIR", this->State->GetBinaryDirectory()); + this->SetDefinition("CMAKE_CURRENT_BINARY_DIR", + this->State->GetBinaryDirectory()); +} + +void cmStateSnapshot::InitializeFromParent() +{ + cmStateDetail::PositionType parent = this->Position->DirectoryParent; + assert(this->Position->Vars.IsValid()); + assert(parent->Vars.IsValid()); + + *this->Position->Vars = + cmDefinitions::MakeClosure(parent->Vars, parent->Root); + + InitializeContentFromParent( + parent->BuildSystemDirectory->IncludeDirectories, + this->Position->BuildSystemDirectory->IncludeDirectories, + parent->BuildSystemDirectory->IncludeDirectoryBacktraces, + this->Position->BuildSystemDirectory->IncludeDirectoryBacktraces, + this->Position->IncludeDirectoryPosition); + + InitializeContentFromParent( + parent->BuildSystemDirectory->CompileDefinitions, + this->Position->BuildSystemDirectory->CompileDefinitions, + parent->BuildSystemDirectory->CompileDefinitionsBacktraces, + this->Position->BuildSystemDirectory->CompileDefinitionsBacktraces, + this->Position->CompileDefinitionsPosition); + + InitializeContentFromParent( + parent->BuildSystemDirectory->CompileOptions, + this->Position->BuildSystemDirectory->CompileOptions, + parent->BuildSystemDirectory->CompileOptionsBacktraces, + this->Position->BuildSystemDirectory->CompileOptionsBacktraces, + this->Position->CompileOptionsPosition); +} + +cmState* cmStateSnapshot::GetState() const +{ + return this->State; +} + +cmStateDirectory cmStateSnapshot::GetDirectory() const +{ + return cmStateDirectory(this->Position->BuildSystemDirectory, *this); +} + +void cmStateSnapshot::SetProjectName(const std::string& name) +{ + this->Position->BuildSystemDirectory->ProjectName = name; +} + +std::string cmStateSnapshot::GetProjectName() const +{ + return this->Position->BuildSystemDirectory->ProjectName; +} + +void cmStateSnapshot::InitializeFromParent_ForSubdirsCommand() +{ + std::string currentSrcDir = this->GetDefinition("CMAKE_CURRENT_SOURCE_DIR"); + std::string currentBinDir = this->GetDefinition("CMAKE_CURRENT_BINARY_DIR"); + this->InitializeFromParent(); + this->SetDefinition("CMAKE_SOURCE_DIR", this->State->GetSourceDirectory()); + this->SetDefinition("CMAKE_BINARY_DIR", this->State->GetBinaryDirectory()); + + this->SetDefinition("CMAKE_CURRENT_SOURCE_DIR", currentSrcDir); + this->SetDefinition("CMAKE_CURRENT_BINARY_DIR", currentBinDir); +} + +bool cmStateSnapshot::StrictWeakOrder::operator()( + const cmStateSnapshot& lhs, const cmStateSnapshot& rhs) const +{ + return lhs.Position.StrictWeakOrdered(rhs.Position); +} + +bool operator==(const cmStateSnapshot& lhs, const cmStateSnapshot& rhs) +{ + return lhs.Position == rhs.Position; +} + +bool operator!=(const cmStateSnapshot& lhs, const cmStateSnapshot& rhs) +{ + return lhs.Position != rhs.Position; +} diff --git a/Source/cmStateSnapshot.h b/Source/cmStateSnapshot.h new file mode 100644 index 0000000..63b581d --- /dev/null +++ b/Source/cmStateSnapshot.h @@ -0,0 +1,88 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#ifndef cmStateSnapshot_h +#define cmStateSnapshot_h + +#include // IWYU pragma: keep + +#include +#include +#include + +#include "cmPolicies.h" +#include "cmStateTypes.h" + +class cmState; +class cmStateDirectory; + +class cmStateSnapshot +{ +public: + cmStateSnapshot(cmState* state = CM_NULLPTR); + cmStateSnapshot(cmState* state, cmStateDetail::PositionType position); + + const char* GetDefinition(std::string const& name) const; + bool IsInitialized(std::string const& name) const; + void SetDefinition(std::string const& name, std::string const& value); + void RemoveDefinition(std::string const& name); + std::vector UnusedKeys() const; + std::vector ClosureKeys() const; + bool RaiseScope(std::string const& var, const char* varDef); + + void SetListFile(std::string const& listfile); + + std::string GetExecutionListFile() const; + + std::vector GetChildren(); + + bool IsValid() const; + cmStateSnapshot GetBuildsystemDirectoryParent() const; + cmStateSnapshot GetCallStackParent() const; + cmStateSnapshot GetCallStackBottom() const; + cmStateEnums::SnapshotType GetType() const; + + void SetPolicy(cmPolicies::PolicyID id, cmPolicies::PolicyStatus status); + cmPolicies::PolicyStatus GetPolicy(cmPolicies::PolicyID id) const; + bool HasDefinedPolicyCMP0011(); + void PushPolicy(cmPolicies::PolicyMap entry, bool weak); + bool PopPolicy(); + bool CanPopPolicyScope(); + + cmState* GetState() const; + + cmStateDirectory GetDirectory() const; + + void SetProjectName(std::string const& name); + std::string GetProjectName() const; + + void InitializeFromParent_ForSubdirsCommand(); + + struct StrictWeakOrder + { + bool operator()(const cmStateSnapshot& lhs, + const cmStateSnapshot& rhs) const; + }; + + void SetDirectoryDefinitions(); + void SetDefaultDefinitions(); + +private: + friend bool operator==(const cmStateSnapshot& lhs, + const cmStateSnapshot& rhs); + friend bool operator!=(const cmStateSnapshot& lhs, + const cmStateSnapshot& rhs); + friend class cmState; + friend class cmStateDirectory; + friend struct StrictWeakOrder; + + void InitializeFromParent(); + + cmState* State; + cmStateDetail::PositionType Position; +}; + +bool operator==(const cmStateSnapshot& lhs, const cmStateSnapshot& rhs); +bool operator!=(const cmStateSnapshot& lhs, const cmStateSnapshot& rhs); + +#endif diff --git a/Source/cmake.h b/Source/cmake.h index 0a577ad..cd00c61 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -7,7 +7,7 @@ #include "cmInstalledFile.h" #include "cmListFileCache.h" -#include "cmState.h" +#include "cmStateSnapshot.h" #include #include diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 912acdb..6e9ad6c 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -7,7 +7,7 @@ #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmQtAutoGenerators.h" -#include "cmState.h" +#include "cmStateDirectory.h" #include "cmSystemTools.h" #include "cmUtils.hxx" #include "cmVersion.h" diff --git a/bootstrap b/bootstrap index d537211..44afbb2 100755 --- a/bootstrap +++ b/bootstrap @@ -292,6 +292,8 @@ CMAKE_CXX_SOURCES="\ cmSourceFile \ cmSourceFileLocation \ cmState \ + cmStateDirectory \ + cmStateSnapshot \ cmSystemTools \ cmTestGenerator \ cmVersion \ -- cgit v0.12