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 <tobias.hunger@qt.io>
This commit is contained in:
David Faure
2016-06-18 15:11:12 +02:00
parent ff2ba0cef5
commit 52ed384549
3 changed files with 24 additions and 5 deletions

View File

@@ -207,9 +207,8 @@ bool FileUtils::isFileNewerThan(const FileName &filePath, const QDateTime &timeS
} }
/*! /*!
Recursively resolves possibly present symlinks in \a filePath. Recursively resolves symlinks if \a filePath is a symlink.
Unlike QFileInfo::canonicalFilePath(), this function will still return the expected target file To resolve symlinks anywhere in the path, see canonicalPath
even if the symlink is dangling.
\note Maximum recursion depth == 16. \note Maximum recursion depth == 16.
@@ -226,6 +225,21 @@ FileName FileUtils::resolveSymlinks(const FileName &path)
return FileName::fromString(f.filePath()); 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 Like QDir::toNativeSeparators(), but use prefix '~' instead of $HOME on unix systems when an
absolute path is given. absolute path is given.

View File

@@ -109,6 +109,7 @@ public:
QString *error = 0, const std::function<bool (QFileInfo, QFileInfo, QString *)> &copyHelper = std::function<bool (QFileInfo, QFileInfo, QString *)>()); QString *error = 0, const std::function<bool (QFileInfo, QFileInfo, QString *)> &copyHelper = std::function<bool (QFileInfo, QFileInfo, QString *)>());
static bool isFileNewerThan(const FileName &filePath, const QDateTime &timeStamp); static bool isFileNewerThan(const FileName &filePath, const QDateTime &timeStamp);
static FileName resolveSymlinks(const FileName &path); static FileName resolveSymlinks(const FileName &path);
static FileName canonicalPath(const FileName &path);
static QString shortNativePath(const FileName &path); static QString shortNativePath(const FileName &path);
static QString fileSystemFriendlyName(const QString &name); static QString fileSystemFriendlyName(const QString &name);
static int indexOfQmakeUnfriendly(const QString &name, int startpos = 0); static int indexOfQmakeUnfriendly(const QString &name, int startpos = 0);

View File

@@ -286,8 +286,12 @@ CMakeConfig BuildDirManager::parsedConfiguration() const
emit errorOccured(errorMessage); emit errorOccured(errorMessage);
const Utils::FileName sourceOfBuildDir const Utils::FileName sourceOfBuildDir
= Utils::FileName::fromUtf8(CMakeConfigItem::valueOf("CMAKE_HOME_DIRECTORY", m_cmakeCache)); = Utils::FileName::fromUtf8(CMakeConfigItem::valueOf("CMAKE_HOME_DIRECTORY", m_cmakeCache));
if (sourceOfBuildDir != sourceDirectory()) // Use case-insensitive compare where appropriate const Utils::FileName canonicalSourceOfBuildDir = Utils::FileUtils::canonicalPath(sourceOfBuildDir);
emit errorOccured(tr("The build directory is not for %1").arg(sourceDirectory().toUserOutput())); 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; return m_cmakeCache;
} }