From fc411cd0d1806435a9c89e8a10cdfed012663fd9 Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Thu, 4 Feb 2021 16:22:40 +0100 Subject: CMakeProjectManager: Make backup of CMake configuration before starting CMake CMake's fileapi functionality will save the project structure in json files in the .cmake/api/v1/reply directory. When issuing a cmake command with -D variables CMake will update its CMakeCache.txt file even if cmake will fail. This commit will rename .cmake/api/v1/reply as .cmake/api/v1/reply.prev and make a copy of CMakeCache.txt before starting CMake, and if something fails, replace the existing files with the previous values. Also make sure the changed values are not dissappearing when the old .cmake/api/v1/reply gets parsed. Fixes: QTCREATORBUG-24593 Change-Id: I82141786fea7068699e0f761a8978ba1f3203e47 Reviewed-by: Eike Ziller --- src/plugins/cmakeprojectmanager/fileapireader.cpp | 37 ++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) (limited to 'src/plugins/cmakeprojectmanager/fileapireader.cpp') diff --git a/src/plugins/cmakeprojectmanager/fileapireader.cpp b/src/plugins/cmakeprojectmanager/fileapireader.cpp index 71fa5601a1..152f22b468 100644 --- a/src/plugins/cmakeprojectmanager/fileapireader.cpp +++ b/src/plugins/cmakeprojectmanager/fileapireader.cpp @@ -29,6 +29,8 @@ #include "fileapiparser.h" #include "projecttreehelper.h" +#include + #include #include @@ -185,7 +187,8 @@ QList FileApiReader::takeBuildTargets(QString &errorMessage){ CMakeConfig FileApiReader::takeParsedConfiguration(QString &errorMessage) { - Q_UNUSED(errorMessage) + if (m_lastCMakeExitCode != 0) + errorMessage = tr("CMake returned error code: %1").arg(m_lastCMakeExitCode); CMakeConfig cache = m_cache; m_cache.clear(); @@ -296,6 +299,34 @@ void FileApiReader::endState(const QFileInfo &replyFi) }); } +void FileApiReader::makeBackupConfiguration(bool store) +{ + FilePath reply = m_parameters.buildDirectory.pathAppended(".cmake/api/v1/reply"); + FilePath replyPrev = m_parameters.buildDirectory.pathAppended(".cmake/api/v1/reply.prev"); + if (!store) + std::swap(reply, replyPrev); + + if (reply.exists()) { + if (replyPrev.exists()) + FileUtils::removeRecursively(replyPrev); + QDir dir; + if (!dir.rename(reply.toString(), replyPrev.toString())) + Core::MessageManager::writeFlashing(tr("Failed to rename %1 to %2.") + .arg(reply.toString(), replyPrev.toString())); + + } + + FilePath cmakeCacheTxt = m_parameters.buildDirectory.pathAppended("CMakeCache.txt"); + FilePath cmakeCacheTxtPrev = m_parameters.buildDirectory.pathAppended("CMakeCache.txt.prev"); + if (!store) + std::swap(cmakeCacheTxt, cmakeCacheTxtPrev); + + if (!FileUtils::copyIfDifferent(cmakeCacheTxt, cmakeCacheTxtPrev)) + Core::MessageManager::writeFlashing(tr("Failed to copy %1 to %2.") + .arg(cmakeCacheTxt.toString(), cmakeCacheTxtPrev.toString())); + +} + void FileApiReader::startCMakeState(const QStringList &configurationArguments) { qCDebug(cmakeFileApiMode) << "FileApiReader: START CMAKE STATE."; @@ -306,6 +337,7 @@ void FileApiReader::startCMakeState(const QStringList &configurationArguments) connect(m_cmakeProcess.get(), &CMakeProcess::finished, this, &FileApiReader::cmakeFinishedState); qCDebug(cmakeFileApiMode) << ">>>>>> Running cmake with arguments:" << configurationArguments; + makeBackupConfiguration(true); m_cmakeProcess->run(m_parameters, configurationArguments); } @@ -319,6 +351,9 @@ void FileApiReader::cmakeFinishedState(int code, QProcess::ExitStatus status) m_lastCMakeExitCode = m_cmakeProcess->lastExitCode(); m_cmakeProcess.release()->deleteLater(); + if (m_lastCMakeExitCode != 0) + makeBackupConfiguration(false); + endState(FileApiParser::scanForCMakeReplyFile(m_parameters.workDirectory)); } -- cgit v1.2.1