From 52ed3845492dd774d85c953606b62ae0068f419d Mon Sep 17 00:00:00 2001 From: David Faure Date: Sat, 18 Jun 2016 15:11:12 +0200 Subject: cmake: resolve symlinks when comparing source directories. Testcase: trying to use an existing build dir which was made for /d/foo where /d is a symlink to $HOME/d. To help understanding the problem, the error message now prints both source dirs, the one found in the builddir and the one we expected. Change-Id: I9a24fbd6ef3cf8108c5edba0d2a5b99ecdea0e89 Reviewed-by: Tobias Hunger --- src/libs/utils/fileutils.cpp | 20 +++++++++++++++++--- src/libs/utils/fileutils.h | 1 + src/plugins/cmakeprojectmanager/builddirmanager.cpp | 8 ++++++-- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/libs/utils/fileutils.cpp b/src/libs/utils/fileutils.cpp index 4c406a363c9..9500035c5f0 100644 --- a/src/libs/utils/fileutils.cpp +++ b/src/libs/utils/fileutils.cpp @@ -207,9 +207,8 @@ bool FileUtils::isFileNewerThan(const FileName &filePath, const QDateTime &timeS } /*! - Recursively resolves possibly present symlinks in \a filePath. - Unlike QFileInfo::canonicalFilePath(), this function will still return the expected target file - even if the symlink is dangling. + Recursively resolves symlinks if \a filePath is a symlink. + To resolve symlinks anywhere in the path, see canonicalPath \note Maximum recursion depth == 16. @@ -226,6 +225,21 @@ FileName FileUtils::resolveSymlinks(const FileName &path) return FileName::fromString(f.filePath()); } +/*! + Recursively resolves possibly present symlinks in \a filePath. + Unlike QFileInfo::canonicalFilePath(), this function will not return an empty + string if path doesn't exist. + + Returns the canonical path. +*/ +FileName FileUtils::canonicalPath(const FileName &path) +{ + const QString result = QFileInfo(path.toString()).canonicalFilePath(); + if (result.isEmpty()) + return path; + return FileName::fromString(result); +} + /*! Like QDir::toNativeSeparators(), but use prefix '~' instead of $HOME on unix systems when an absolute path is given. diff --git a/src/libs/utils/fileutils.h b/src/libs/utils/fileutils.h index 286ffd02f79..5bd844a004d 100644 --- a/src/libs/utils/fileutils.h +++ b/src/libs/utils/fileutils.h @@ -109,6 +109,7 @@ public: QString *error = 0, const std::function ©Helper = std::function()); static bool isFileNewerThan(const FileName &filePath, const QDateTime &timeStamp); static FileName resolveSymlinks(const FileName &path); + static FileName canonicalPath(const FileName &path); static QString shortNativePath(const FileName &path); static QString fileSystemFriendlyName(const QString &name); static int indexOfQmakeUnfriendly(const QString &name, int startpos = 0); diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.cpp b/src/plugins/cmakeprojectmanager/builddirmanager.cpp index 432e28cfba0..79156c784bf 100644 --- a/src/plugins/cmakeprojectmanager/builddirmanager.cpp +++ b/src/plugins/cmakeprojectmanager/builddirmanager.cpp @@ -286,8 +286,12 @@ CMakeConfig BuildDirManager::parsedConfiguration() const emit errorOccured(errorMessage); const Utils::FileName sourceOfBuildDir = Utils::FileName::fromUtf8(CMakeConfigItem::valueOf("CMAKE_HOME_DIRECTORY", m_cmakeCache)); - if (sourceOfBuildDir != sourceDirectory()) // Use case-insensitive compare where appropriate - emit errorOccured(tr("The build directory is not for %1").arg(sourceDirectory().toUserOutput())); + const Utils::FileName canonicalSourceOfBuildDir = Utils::FileUtils::canonicalPath(sourceOfBuildDir); + const Utils::FileName canonicalSourceDirectory = Utils::FileUtils::canonicalPath(sourceDirectory()); + if (canonicalSourceOfBuildDir != canonicalSourceDirectory) // Uses case-insensitive compare where appropriate + emit errorOccured(tr("The build directory is not for %1 but for %2") + .arg(canonicalSourceOfBuildDir.toUserOutput(), + canonicalSourceDirectory.toUserOutput())); } return m_cmakeCache; } -- cgit v1.2.3