From 6b1852874325520a418eb05ec3c2149c2eb194a2 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 1 Dec 2015 10:44:48 -0500 Subject: [PATCH 1/2] cmOrderDirectories: Factor out directory comparison Create an `IsSameDirectory` helper method. --- Source/cmOrderDirectories.cxx | 13 +++++++++---- Source/cmOrderDirectories.h | 3 +++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Source/cmOrderDirectories.cxx b/Source/cmOrderDirectories.cxx index 35ee12709..94912049b 100644 --- a/Source/cmOrderDirectories.cxx +++ b/Source/cmOrderDirectories.cxx @@ -73,10 +73,8 @@ public: { // Check if this directory conflicts with the entry. std::string const& dir = this->OD->OriginalDirectories[i]; - if(dir != this->Directory && - cmSystemTools::GetRealPath(dir) != - cmSystemTools::GetRealPath(this->Directory) && - this->FindConflict(dir)) + if (!this->OD->IsSameDirectory(dir, this->Directory) && + this->FindConflict(dir)) { // The library will be found in this directory but this is not // the directory named for it. Add an entry to make sure the @@ -639,3 +637,10 @@ void cmOrderDirectories::DiagnoseCycle() ->IssueMessage(cmake::WARNING, e.str(), this->Target->Target->GetBacktrace()); } + +bool cmOrderDirectories::IsSameDirectory(std::string const& l, + std::string const& r) +{ + return (l == r || + cmSystemTools::GetRealPath(l) == cmSystemTools::GetRealPath(r)); +} diff --git a/Source/cmOrderDirectories.h b/Source/cmOrderDirectories.h index 211c786d5..0657e92dc 100644 --- a/Source/cmOrderDirectories.h +++ b/Source/cmOrderDirectories.h @@ -80,6 +80,9 @@ private: struct ConflictList: public std::vector {}; std::vector ConflictGraph; + // Compare directories after resolving symlinks. + bool IsSameDirectory(std::string const& l, std::string const& r); + friend class cmOrderDirectoriesConstraint; friend class cmOrderDirectoriesConstraintLibrary; }; From 4e3cf8b012404e4d9602c16d473480cc3d0c7928 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 1 Dec 2015 10:57:33 -0500 Subject: [PATCH 2/2] cmOrderDirectories: Reduce repeat realpath() calls Since commit v3.1.0-rc1~110^2 (Tolerate symlinks during RPATH ordering, 2014-09-09) we call realpath() for every directory ordering constraint check. On some platforms/filesystems this is slow, so memoize the result of the call for each directory. --- Source/cmOrderDirectories.cxx | 17 +++++++++++++++-- Source/cmOrderDirectories.h | 3 +++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/Source/cmOrderDirectories.cxx b/Source/cmOrderDirectories.cxx index 94912049b..e3406a83e 100644 --- a/Source/cmOrderDirectories.cxx +++ b/Source/cmOrderDirectories.cxx @@ -641,6 +641,19 @@ void cmOrderDirectories::DiagnoseCycle() bool cmOrderDirectories::IsSameDirectory(std::string const& l, std::string const& r) { - return (l == r || - cmSystemTools::GetRealPath(l) == cmSystemTools::GetRealPath(r)); + return this->GetRealPath(l) == this->GetRealPath(r); +} + +std::string const& cmOrderDirectories::GetRealPath(std::string const& dir) +{ + std::map::iterator i = + this->RealPaths.lower_bound(dir); + if (i == this->RealPaths.end() || + this->RealPaths.key_comp()(dir, i->first)) + { + typedef std::map::value_type value_type; + i = this->RealPaths.insert( + i, value_type(dir, cmSystemTools::GetRealPath(dir))); + } + return i->second; } diff --git a/Source/cmOrderDirectories.h b/Source/cmOrderDirectories.h index 0657e92dc..477216bbd 100644 --- a/Source/cmOrderDirectories.h +++ b/Source/cmOrderDirectories.h @@ -83,6 +83,9 @@ private: // Compare directories after resolving symlinks. bool IsSameDirectory(std::string const& l, std::string const& r); + std::string const& GetRealPath(std::string const& dir); + std::map RealPaths; + friend class cmOrderDirectoriesConstraint; friend class cmOrderDirectoriesConstraintLibrary; };