|
|
@@ -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);
|
|
|
}
|
|
|
}
|