From 9e4b6cc2cebc7af40432f5027d2960c0cc68515f Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 4 May 2015 23:30:29 +0200 Subject: cmState: Store computed relative paths to to current directories. --- Source/cmLocalGenerator.cxx | 107 ++----------------------------- Source/cmLocalGenerator.h | 13 ---- Source/cmLocalUnixMakefileGenerator3.cxx | 11 ++-- Source/cmState.cxx | 106 ++++++++++++++++++++++++++++++ Source/cmState.h | 16 +++++ 5 files changed, 132 insertions(+), 121 deletions(-) diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 4e4970d..ea840c5 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -66,7 +66,6 @@ cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg, this->UseRelativePaths = false; this->Configured = false; this->EmitUniversalBinaryFlags = true; - this->RelativePathsConfigured = false; this->BackwardsCompatibility = 0; this->BackwardsCompatibilityFinal = false; } @@ -2779,97 +2778,6 @@ std::string cmLocalGenerator::Convert(RelativeRoot remote, } //---------------------------------------------------------------------------- -std::string cmLocalGenerator::FindRelativePathTopSource() -{ - cmState::Snapshot snapshot = this->StateSnapshot; - std::vector snapshots; - snapshots.push_back(snapshot); - while (true) - { - snapshot = snapshot.GetParent(); - if (snapshot.IsValid()) - { - snapshots.push_back(snapshot); - } - else - { - break; - } - } - - std::string result = snapshots.front().GetCurrentSourceDirectory(); - - for (std::vector::const_iterator it = - snapshots.begin() + 1; it != snapshots.end(); ++it) - { - std::string currentSource = it->GetCurrentSourceDirectory(); - if(cmSystemTools::IsSubDirectory(result, currentSource)) - { - result = currentSource; - } - } - - return result; -} - -//---------------------------------------------------------------------------- -std::string cmLocalGenerator::FindRelativePathTopBinary() -{ - cmState::Snapshot snapshot = this->StateSnapshot; - std::vector snapshots; - snapshots.push_back(snapshot); - while (true) - { - snapshot = snapshot.GetParent(); - if (snapshot.IsValid()) - { - snapshots.push_back(snapshot); - } - else - { - break; - } - } - - std::string result = snapshots.front().GetCurrentBinaryDirectory(); - - for (std::vector::const_iterator it = - snapshots.begin() + 1; it != snapshots.end(); ++it) - { - std::string currentBinary = it->GetCurrentBinaryDirectory(); - if(cmSystemTools::IsSubDirectory(result, currentBinary)) - { - result = currentBinary; - } - } - - return result; -} - -//---------------------------------------------------------------------------- -void cmLocalGenerator::ConfigureRelativePaths() -{ - // Relative path conversion inside the source tree is not used to - // construct relative paths passed to build tools so it is safe to - // even when the source is a network path. - std::string source = this->FindRelativePathTopSource(); - this->RelativePathTopSource = source; - - // The current working directory on Windows cannot be a network - // path. Therefore relative paths cannot work when the binary tree - // is a network path. - std::string binary = this->FindRelativePathTopBinary(); - if(binary.size() < 2 || binary.substr(0, 2) != "//") - { - this->RelativePathTopBinary = binary; - } - else - { - this->RelativePathTopBinary = ""; - } -} - -//---------------------------------------------------------------------------- static bool cmLocalGeneratorNotAbove(const char* a, const char* b) { return (cmSystemTools::ComparePath(a, b) || @@ -2894,26 +2802,19 @@ cmLocalGenerator::ConvertToRelativePath(const std::vector& local, return in_remote; } - // Make sure relative path conversion is configured. - if(!this->RelativePathsConfigured) - { - this->ConfigureRelativePaths(); - this->RelativePathsConfigured = true; - } - if(!force) { // Skip conversion if the path and local are not both in the source // or both in the binary tree. std::string local_path = cmSystemTools::JoinPath(local); if(!((cmLocalGeneratorNotAbove(local_path.c_str(), - this->RelativePathTopBinary.c_str()) && + this->StateSnapshot.GetRelativePathTopBinary()) && cmLocalGeneratorNotAbove(in_remote.c_str(), - this->RelativePathTopBinary.c_str())) || + this->StateSnapshot.GetRelativePathTopBinary())) || (cmLocalGeneratorNotAbove(local_path.c_str(), - this->RelativePathTopSource.c_str()) && + this->StateSnapshot.GetRelativePathTopSource()) && cmLocalGeneratorNotAbove(in_remote.c_str(), - this->RelativePathTopSource.c_str())))) + this->StateSnapshot.GetRelativePathTopSource())))) { return in_remote; } diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index e4d4444..5e32794 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -440,10 +440,6 @@ protected: std::string const& dir_max); void ComputeObjectMaxPath(); - void ConfigureRelativePaths(); - std::string FindRelativePathTopSource(); - std::string FindRelativePathTopBinary(); - virtual std::string ConvertToLinkReference(std::string const& lib, OutputFormat format = SHELL); @@ -473,15 +469,6 @@ protected: // committed. std::string TargetImplib; - // 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; - bool RelativePathsConfigured; - cmIML_INT_uint64_t BackwardsCompatibility; bool BackwardsCompatibilityFinal; private: diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index f11c79e..54bff7f 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -545,9 +545,11 @@ void cmLocalUnixMakefileGenerator3::WriteDirectoryInformationFile() // Setup relative path conversion tops. infoFileStream << "# Relative path conversion top directories.\n" - << "set(CMAKE_RELATIVE_PATH_TOP_SOURCE \"" << this->RelativePathTopSource + << "set(CMAKE_RELATIVE_PATH_TOP_SOURCE \"" + << this->StateSnapshot.GetRelativePathTopSource() << "\")\n" - << "set(CMAKE_RELATIVE_PATH_TOP_BINARY \"" << this->RelativePathTopBinary + << "set(CMAKE_RELATIVE_PATH_TOP_BINARY \"" + << this->StateSnapshot.GetRelativePathTopBinary() << "\")\n" << "\n"; @@ -1613,16 +1615,15 @@ cmLocalUnixMakefileGenerator3 } // Setup relative path top directories. - this->RelativePathsConfigured = true; if(const char* relativePathTopSource = mf->GetDefinition("CMAKE_RELATIVE_PATH_TOP_SOURCE")) { - this->RelativePathTopSource = relativePathTopSource; + this->StateSnapshot.SetRelativePathTopSource(relativePathTopSource); } if(const char* relativePathTopBinary = mf->GetDefinition("CMAKE_RELATIVE_PATH_TOP_BINARY")) { - this->RelativePathTopBinary = relativePathTopBinary; + this->StateSnapshot.SetRelativePathTopBinary(relativePathTopBinary); } } else diff --git a/Source/cmState.cxx b/Source/cmState.cxx index 27a36bc..4965ae3 100644 --- a/Source/cmState.cxx +++ b/Source/cmState.cxx @@ -199,6 +199,8 @@ void cmState::Initialize() this->ParentPositions.clear(); this->CurrentSourceDirectoryComponents.clear(); this->CurrentBinaryDirectoryComponents.clear(); + this->RelativePathTopSource.clear(); + this->RelativePathTopBinary.clear(); this->CreateSnapshot(Snapshot()); this->DefineProperty @@ -496,6 +498,86 @@ std::vector const& cmState::GetBinaryDirectoryComponents() const return this->BinaryDirectoryComponents; } +void cmState::Snapshot::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. + + cmState::Snapshot snapshot = *this; + std::vector snapshots; + snapshots.push_back(snapshot); + while (true) + { + snapshot = snapshot.GetParent(); + if (snapshot.IsValid()) + { + snapshots.push_back(snapshot); + } + else + { + break; + } + } + + std::string result = snapshots.front().GetCurrentSourceDirectory(); + + for (std::vector::const_iterator it = + snapshots.begin() + 1; it != snapshots.end(); ++it) + { + std::string currentSource = it->GetCurrentSourceDirectory(); + if(cmSystemTools::IsSubDirectory(result, currentSource)) + { + result = currentSource; + } + } + this->State->RelativePathTopSource[this->Position] = result; +} + +void cmState::Snapshot::ComputeRelativePathTopBinary() +{ + cmState::Snapshot snapshot = *this; + std::vector snapshots; + snapshots.push_back(snapshot); + while (true) + { + snapshot = snapshot.GetParent(); + if (snapshot.IsValid()) + { + snapshots.push_back(snapshot); + } + else + { + break; + } + } + + std::string result = + snapshots.front().GetCurrentBinaryDirectory(); + + for (std::vector::const_iterator it = + snapshots.begin() + 1; it != snapshots.end(); ++it) + { + std::string currentBinary = it->GetCurrentBinaryDirectory(); + 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->State->RelativePathTopBinary[this->Position] = result; + } + else + { + this->State->RelativePathTopBinary[this->Position] = ""; + } +} + cmState::Snapshot cmState::CreateSnapshot(Snapshot originSnapshot) { PositionType pos = this->ParentPositions.size(); @@ -506,6 +588,8 @@ cmState::Snapshot cmState::CreateSnapshot(Snapshot originSnapshot) this->CurrentSourceDirectoryComponents.size() + 1); this->CurrentBinaryDirectoryComponents.resize( this->CurrentBinaryDirectoryComponents.size() + 1); + this->RelativePathTopSource.resize(this->RelativePathTopSource.size() + 1); + this->RelativePathTopBinary.resize(this->RelativePathTopBinary.size() + 1); return cmState::Snapshot(this, pos); } @@ -533,6 +617,7 @@ void cmState::Snapshot::SetCurrentSourceDirectory(std::string const& dir) cmSystemTools::SplitPath( this->State->Locations[this->Position], this->State->CurrentSourceDirectoryComponents[this->Position]); + this->ComputeRelativePathTopSource(); } const char* cmState::Snapshot::GetCurrentBinaryDirectory() const @@ -553,6 +638,7 @@ void cmState::Snapshot::SetCurrentBinaryDirectory(std::string const& dir) cmSystemTools::SplitPath( this->State->OutputLocations[this->Position], this->State->CurrentBinaryDirectoryComponents[this->Position]); + this->ComputeRelativePathTopBinary(); } std::vector const& @@ -567,6 +653,26 @@ cmState::Snapshot::GetCurrentBinaryDirectoryComponents() return this->State->CurrentBinaryDirectoryComponents[this->Position]; } +const char* cmState::Snapshot::GetRelativePathTopSource() const +{ + return this->State->RelativePathTopSource[this->Position].c_str(); +} + +const char* cmState::Snapshot::GetRelativePathTopBinary() const +{ + return this->State->RelativePathTopBinary[this->Position].c_str(); +} + +void cmState::Snapshot::SetRelativePathTopSource(const char* dir) +{ + this->State->RelativePathTopSource[this->Position] = dir; +} + +void cmState::Snapshot::SetRelativePathTopBinary(const char* dir) +{ + this->State->RelativePathTopBinary[this->Position] = dir; +} + bool cmState::Snapshot::IsValid() const { return this->State ? true : false; diff --git a/Source/cmState.h b/Source/cmState.h index faf0739..23d3f0d 100644 --- a/Source/cmState.h +++ b/Source/cmState.h @@ -39,10 +39,19 @@ public: std::vector const& GetCurrentSourceDirectoryComponents(); std::vector const& GetCurrentBinaryDirectoryComponents(); + const char* GetRelativePathTopSource() const; + const char* GetRelativePathTopBinary() const; + void SetRelativePathTopSource(const char* dir); + void SetRelativePathTopBinary(const char* dir); + bool IsValid() const; Snapshot GetParent() const; private: + void ComputeRelativePathTopSource(); + void ComputeRelativePathTopBinary(); + + private: friend class cmState; cmState* State; cmState::PositionType Position; @@ -141,6 +150,13 @@ private: std::vector > CurrentSourceDirectoryComponents; std::vector > CurrentBinaryDirectoryComponents; + // 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::vector RelativePathTopSource; + std::vector RelativePathTopBinary; std::vector SourceDirectoryComponents; std::vector BinaryDirectoryComponents; -- cgit v0.12