diff options
author | Brad King <brad.king@kitware.com> | 2017-03-01 14:00:40 (GMT) |
---|---|---|
committer | CMake Topic Stage <kwrobot@kitware.com> | 2017-03-01 14:00:40 (GMT) |
commit | 4fc64ce76d9981674ababaa3279952544ba8ac01 (patch) | |
tree | 60feed5b9dc61bc6e817b420efcecee4c8fcc450 /Source | |
parent | a9113ae37bae72ee2f7a765da732f2b21d1491ce (diff) | |
parent | 6f5aede71642b05a351d5cf92e0c884ed9b4fd3c (diff) | |
download | CMake-4fc64ce76d9981674ababaa3279952544ba8ac01.zip CMake-4fc64ce76d9981674ababaa3279952544ba8ac01.tar.gz CMake-4fc64ce76d9981674ababaa3279952544ba8ac01.tar.bz2 |
Merge topic 'find-libarch-not-symlink'
6f5aede7 find_library: Skip 'lib => lib<arch>' searches if one symlinks the other
e67963ed cmFindLibraryCommand: Refactor AddArchitecturePath logic
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmFindLibraryCommand.cxx | 64 |
1 files changed, 48 insertions, 16 deletions
diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx index 2feedf3..c86f9c1 100644 --- a/Source/cmFindLibraryCommand.cxx +++ b/Source/cmFindLibraryCommand.cxx @@ -84,36 +84,68 @@ 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) { std::string::size_type pos = dir.find("lib/", start_pos); + if (pos != std::string::npos) { - std::string cur_dir = dir.substr(0, pos + 3); - - // Follow "lib<suffix>". - std::string next_dir = cur_dir + suffix; - if (cmSystemTools::FileIsDirectory(next_dir)) { - next_dir += dir.substr(pos + 3); - std::string::size_type next_pos = pos + 3 + strlen(suffix) + 1; - this->AddArchitecturePath(next_dir, next_pos, suffix); + // Check for "lib". + std::string lib = dir.substr(0, pos + 3); + bool use_lib = cmSystemTools::FileIsDirectory(lib); + + // Check for "lib<suffix>" and use it first. + 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; } - // Follow "lib". - if (cmSystemTools::FileIsDirectory(cur_dir)) { + if (use_libX) { + libX += dir.substr(pos + 3); + std::string::size_type libX_pos = pos + 3 + strlen(suffix) + 1; + this->AddArchitecturePath(libX, libX_pos, suffix); + } + + if (use_lib) { this->AddArchitecturePath(dir, pos + 3 + 1, suffix, false); } } + if (fresh) { - // Check for <dir><suffix>/. - std::string cur_dir = dir + suffix + "/"; - if (cmSystemTools::FileIsDirectory(cur_dir)) { - this->SearchPaths.push_back(cur_dir); + // Check for the original unchanged path. + bool use_dir = cmSystemTools::FileIsDirectory(dir); + + // Check for <dir><suffix>/ and use it first. + 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); } - // Now add the original unchanged path - if (cmSystemTools::FileIsDirectory(dir)) { + if (use_dir) { this->SearchPaths.push_back(dir); } } |