summaryrefslogtreecommitdiff
path: root/Source/cmFindLibraryCommand.cxx
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2017-02-28 13:51:35 -0500
committerBrad King <brad.king@kitware.com>2017-02-28 14:56:54 -0500
commit6f5aede71642b05a351d5cf92e0c884ed9b4fd3c (patch)
treef1f5686398ea5829717832deb516b749bc685a7c /Source/cmFindLibraryCommand.cxx
parente67963ed7316768bf0ebfbe42137d028c0d1d2a4 (diff)
downloadcmake-6f5aede71642b05a351d5cf92e0c884ed9b4fd3c.tar.gz
find_library: Skip 'lib => lib<arch>' searches if one symlinks the other
The `FIND_LIBRARY_USE_LIB<arch>_PATHS` global properties ask `find_library` to look in `lib<arch>` directories automatically before corresponding `lib` directories. However, if `lib<arch>` is just a symlink to `lib` (or vice-versa) then we should skip adding the `lib<arch>` path. Such symlinks typically only exist to satisfy software that expects the `lib<arch>` path to be available. Fixes: #16687
Diffstat (limited to 'Source/cmFindLibraryCommand.cxx')
-rw-r--r--Source/cmFindLibraryCommand.cxx22
1 files changed, 22 insertions, 0 deletions
diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx
index 58d92aa405..412d573b4e 100644
--- a/Source/cmFindLibraryCommand.cxx
+++ b/Source/cmFindLibraryCommand.cxx
@@ -72,6 +72,18 @@ void cmFindLibraryCommand::AddArchitecturePaths(const char* suffix)
}
}
+static bool cmLibDirsLinked(std::string const& l, std::string const& r)
+{
+ // Compare the real paths of the two directories.
+ // Since our caller only changed the trailing component of each
+ // directory, the real paths can be the same only if at least one of
+ // the trailing components is a symlink. Use this as an optimization
+ // to avoid excessive realpath calls.
+ return (cmSystemTools::FileIsSymlink(l) ||
+ cmSystemTools::FileIsSymlink(r)) &&
+ cmSystemTools::GetRealPath(l) == cmSystemTools::GetRealPath(r);
+}
+
void cmFindLibraryCommand::AddArchitecturePath(
std::string const& dir, std::string::size_type start_pos, const char* suffix,
bool fresh)
@@ -87,6 +99,11 @@ void cmFindLibraryCommand::AddArchitecturePath(
std::string libX = lib + suffix;
bool use_libX = cmSystemTools::FileIsDirectory(libX);
+ // Avoid copies of the same directory due to symlinks.
+ if (use_libX && use_lib && cmLibDirsLinked(libX, lib)) {
+ use_libX = false;
+ }
+
if (use_libX) {
libX += dir.substr(pos + 3);
std::string::size_type libX_pos = pos + 3 + strlen(suffix) + 1;
@@ -106,6 +123,11 @@ void cmFindLibraryCommand::AddArchitecturePath(
std::string dirX = dir + suffix;
bool use_dirX = cmSystemTools::FileIsDirectory(dirX);
+ // Avoid copies of the same directory due to symlinks.
+ if (use_dirX && use_dir && cmLibDirsLinked(dirX, dir)) {
+ use_dirX = false;
+ }
+
if (use_dirX) {
dirX += "/";
this->SearchPaths.push_back(dirX);