diff options
author | Brad King <brad.king@kitware.com> | 2017-02-28 13:51:35 -0500 |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2017-02-28 14:56:54 -0500 |
commit | 6f5aede71642b05a351d5cf92e0c884ed9b4fd3c (patch) | |
tree | f1f5686398ea5829717832deb516b749bc685a7c /Source/cmFindLibraryCommand.cxx | |
parent | e67963ed7316768bf0ebfbe42137d028c0d1d2a4 (diff) | |
download | cmake-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.cxx | 22 |
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); |