diff options
7 files changed, 82 insertions, 25 deletions
diff --git a/src/plugins/cmakeprojectmanager/builddirparameters.cpp b/src/plugins/cmakeprojectmanager/builddirparameters.cpp index 023de6b071..0c06c329f5 100644 --- a/src/plugins/cmakeprojectmanager/builddirparameters.cpp +++ b/src/plugins/cmakeprojectmanager/builddirparameters.cpp @@ -59,7 +59,7 @@ BuildDirParameters::BuildDirParameters(CMakeBuildConfiguration *bc) }); initialCMakeArguments = Utils::filtered(expandedArguments, [](const QString &s) { return !s.isEmpty(); }); - extraCMakeArguments = Utils::transform(bc->extraCMakeArguments(), + extraCMakeArguments = Utils::transform(bc->configurationChangesArguments(), [expander](const QString &s) { return expander->expand(s); }); diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp index 42457c6a77..13cf6c8af2 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp @@ -470,8 +470,7 @@ void CMakeBuildSettingsWidget::updateButtonState() m_resetButton->setEnabled(m_configModel->hasChanges() && !isParsing); m_reconfigureButton->setEnabled((!configChanges.isEmpty() || m_configModel->hasCMakeChanges()) && !isParsing); - m_buildConfiguration->setExtraCMakeArguments( - Utils::transform(configChanges, [](const CMakeConfigItem &i) { return i.toArgument(); })); + m_buildConfiguration->setConfigurationChanges(configChanges); } void CMakeBuildSettingsWidget::updateAdvancedCheckBox() @@ -943,24 +942,19 @@ CMakeConfig CMakeBuildConfiguration::configurationFromCMake() const return m_configurationFromCMake; } -QStringList CMakeBuildConfiguration::extraCMakeArguments() const +CMakeConfig CMakeBuildConfiguration::configurationChanges() const { - return m_extraCMakeArguments; + return m_configurationChanges; } -QStringList CMakeBuildConfiguration::initialCMakeArguments() const +QStringList CMakeBuildConfiguration::configurationChangesArguments() const { - return aspect<InitialCMakeArgumentsAspect>()->value().split('\n', Qt::SkipEmptyParts); + return Utils::transform(m_configurationChanges, [](const CMakeConfigItem &i) { return i.toArgument(); }); } -void CMakeBuildConfiguration::setExtraCMakeArguments(const QStringList &args) +QStringList CMakeBuildConfiguration::initialCMakeArguments() const { - if (m_extraCMakeArguments == args) - return; - - qCDebug(cmakeBuildConfigurationLog) - << "Extra Args changed from" << m_extraCMakeArguments << "to" << args << "..."; - m_extraCMakeArguments = args; + return aspect<InitialCMakeArgumentsAspect>()->value().split('\n', Qt::SkipEmptyParts); } void CMakeBuildConfiguration::setConfigurationFromCMake(const CMakeConfig &config) @@ -968,6 +962,17 @@ void CMakeBuildConfiguration::setConfigurationFromCMake(const CMakeConfig &confi m_configurationFromCMake = config; } +void CMakeBuildConfiguration::setConfigurationChanges(const CMakeConfig &config) +{ + qCDebug(cmakeBuildConfigurationLog) + << "Configuration changes before:" << configurationChangesArguments(); + + m_configurationChanges = config; + + qCDebug(cmakeBuildConfigurationLog) + << "Configuration changes after:" << configurationChangesArguments(); +} + // FIXME: Run clean steps when a setting starting with "ANDROID_BUILD_ABI_" is changed. // FIXME: Warn when kit settings are overridden by a project. diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h index b9bf253091..24dbaaca43 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h @@ -52,8 +52,9 @@ public: ~CMakeBuildConfiguration() override; CMakeConfig configurationFromCMake() const; + CMakeConfig configurationChanges() const; - QStringList extraCMakeArguments() const; + QStringList configurationChangesArguments() const; QStringList initialCMakeArguments() const; @@ -96,8 +97,8 @@ private: void clearError(ForceEnabledChanged fec = ForceEnabledChanged::False); void setConfigurationFromCMake(const CMakeConfig &config); + void setConfigurationChanges(const CMakeConfig &config); - void setExtraCMakeArguments(const QStringList &args); void setInitialCMakeArguments(const QStringList &args); void setError(const QString &message); @@ -108,6 +109,7 @@ private: QString m_warning; CMakeConfig m_configurationFromCMake; + CMakeConfig m_configurationChanges; Internal::CMakeBuildSystem *m_buildSystem = nullptr; QStringList m_extraCMakeArguments; diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp index 636f0c47f5..abd515f1a0 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp @@ -676,6 +676,24 @@ void CMakeBuildSystem::updateFallbackProjectData() qCDebug(cmakeBuildSystemLog) << "All fallback CMake project data up to date."; } +void CMakeBuildSystem::updateCMakeConfiguration(QString &errorMessage) +{ + CMakeConfig cmakeConfig = m_reader.takeParsedConfiguration(errorMessage); + for (auto &ci : cmakeConfig) + ci.inCMakeCache = true; + if (!errorMessage.isEmpty()) { + const CMakeConfig changes = cmakeBuildConfiguration()->configurationChanges(); + for (const auto &ci : changes) { + const bool haveConfigItem = Utils::contains(cmakeConfig, [ci](const CMakeConfigItem& i) { + return i.key == ci.key; + }); + if (!haveConfigItem) + cmakeConfig.append(ci); + } + } + cmakeBuildConfiguration()->setConfigurationFromCMake(cmakeConfig); +} + void CMakeBuildSystem::handleParsingSucceeded() { if (!cmakeBuildConfiguration()->isActive()) { @@ -699,10 +717,7 @@ void CMakeBuildSystem::handleParsingSucceeded() } { - CMakeConfig cmakeConfig = m_reader.takeParsedConfiguration(errorMessage); - for (auto &ci : cmakeConfig) - ci.inCMakeCache = true; - cmakeBuildConfiguration()->setConfigurationFromCMake(cmakeConfig); + updateCMakeConfiguration(errorMessage); checkAndReportError(errorMessage); } @@ -722,10 +737,7 @@ void CMakeBuildSystem::handleParsingFailed(const QString &msg) cmakeBuildConfiguration()->setError(msg); QString errorMessage; - CMakeConfig cmakeConfig = m_reader.takeParsedConfiguration(errorMessage); - for (auto &ci : cmakeConfig) - ci.inCMakeCache = true; - cmakeBuildConfiguration()->setConfigurationFromCMake(cmakeConfig); + updateCMakeConfiguration(errorMessage); // ignore errorMessage here, we already got one. m_ctestPath.clear(); diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.h b/src/plugins/cmakeprojectmanager/cmakebuildsystem.h index b69d675be0..283990ed7b 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.h +++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.h @@ -134,6 +134,8 @@ private: const QList<const ProjectExplorer::FileNode *> &allFiles, bool includeHeadersNode); void checkAndReportError(QString &errorMessage); + void updateCMakeConfiguration(QString &errorMessage); + void updateProjectData(); void updateFallbackProjectData(); QList<ProjectExplorer::ExtraCompiler *> findExtraCompilers(); 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 <coreplugin/messagemanager.h> + #include <projectexplorer/projectexplorer.h> #include <utils/algorithm.h> @@ -185,7 +187,8 @@ QList<CMakeBuildTarget> 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)); } diff --git a/src/plugins/cmakeprojectmanager/fileapireader.h b/src/plugins/cmakeprojectmanager/fileapireader.h index ef210ea2a7..25d5e1af1b 100644 --- a/src/plugins/cmakeprojectmanager/fileapireader.h +++ b/src/plugins/cmakeprojectmanager/fileapireader.h @@ -89,6 +89,7 @@ private: void cmakeFinishedState(int code, QProcess::ExitStatus status); void replyDirectoryHasChanged(const QString &directory) const; + void makeBackupConfiguration(bool store); std::unique_ptr<CMakeProcess> m_cmakeProcess; |