forked from qt-creator/qt-creator
CMake: Check CMakeCache.txt for changes
Check CMakeCache.txt for changes and ask whether to apply these to the project going forward. This will only consider settings that were previously changed by Qt Creator and will not pick up on newly changed settings. Change-Id: Ia20c67bc2a5e9965243f08003c10ec684875387f Reviewed-by: Tim Jenssen <tim.jenssen@theqtcompany.com>
This commit is contained in:
@@ -30,6 +30,7 @@
|
|||||||
#include "cmakeprojectmanager.h"
|
#include "cmakeprojectmanager.h"
|
||||||
#include "cmaketool.h"
|
#include "cmaketool.h"
|
||||||
|
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/messagemanager.h>
|
#include <coreplugin/messagemanager.h>
|
||||||
#include <coreplugin/progressmanager/progressmanager.h>
|
#include <coreplugin/progressmanager/progressmanager.h>
|
||||||
#include <projectexplorer/kit.h>
|
#include <projectexplorer/kit.h>
|
||||||
@@ -49,6 +50,7 @@
|
|||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QFileSystemWatcher>
|
#include <QFileSystemWatcher>
|
||||||
|
#include <QMessageBox>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
#include <QTemporaryDir>
|
#include <QTemporaryDir>
|
||||||
@@ -91,7 +93,7 @@ static QStringList toArguments(const CMakeConfig &config, const ProjectExplorer:
|
|||||||
// BuildDirManager:
|
// BuildDirManager:
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
|
|
||||||
BuildDirManager::BuildDirManager(const CMakeBuildConfiguration *bc) :
|
BuildDirManager::BuildDirManager(CMakeBuildConfiguration *bc) :
|
||||||
m_buildConfiguration(bc),
|
m_buildConfiguration(bc),
|
||||||
m_watcher(new QFileSystemWatcher(this))
|
m_watcher(new QFileSystemWatcher(this))
|
||||||
{
|
{
|
||||||
@@ -201,6 +203,8 @@ bool BuildDirManager::persistCMakeState()
|
|||||||
|
|
||||||
void BuildDirManager::parse()
|
void BuildDirManager::parse()
|
||||||
{
|
{
|
||||||
|
checkConfiguration();
|
||||||
|
|
||||||
CMakeTool *tool = CMakeKitInformation::cmakeTool(kit());
|
CMakeTool *tool = CMakeKitInformation::cmakeTool(kit());
|
||||||
const QString generator = CMakeGeneratorKitInformation::generator(kit());
|
const QString generator = CMakeGeneratorKitInformation::generator(kit());
|
||||||
|
|
||||||
@@ -275,6 +279,8 @@ CMakeConfig BuildDirManager::parsedConfiguration() const
|
|||||||
if (m_cmakeCache.isEmpty()) {
|
if (m_cmakeCache.isEmpty()) {
|
||||||
Utils::FileName cacheFile = workDirectory();
|
Utils::FileName cacheFile = workDirectory();
|
||||||
cacheFile.appendPath(QLatin1String("CMakeCache.txt"));
|
cacheFile.appendPath(QLatin1String("CMakeCache.txt"));
|
||||||
|
if (!cacheFile.exists())
|
||||||
|
return m_cmakeCache;
|
||||||
QString errorMessage;
|
QString errorMessage;
|
||||||
m_cmakeCache = parseConfiguration(cacheFile, &errorMessage);
|
m_cmakeCache = parseConfiguration(cacheFile, &errorMessage);
|
||||||
if (!errorMessage.isEmpty())
|
if (!errorMessage.isEmpty())
|
||||||
@@ -350,6 +356,7 @@ void BuildDirManager::extractData()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
m_watcher->addPath(cbpFile);
|
m_watcher->addPath(cbpFile);
|
||||||
|
m_watcher->addPath(workDirectory().toString() + QLatin1String("/CMakeCache.txt"));
|
||||||
|
|
||||||
// setFolderName
|
// setFolderName
|
||||||
CMakeCbpParser cbpparser;
|
CMakeCbpParser cbpparser;
|
||||||
@@ -512,6 +519,61 @@ void BuildDirManager::processCMakeError()
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BuildDirManager::checkConfiguration()
|
||||||
|
{
|
||||||
|
if (m_tempDir) // always throw away changes in the tmpdir!
|
||||||
|
return;
|
||||||
|
|
||||||
|
ProjectExplorer::Kit *k = m_buildConfiguration->target()->kit();
|
||||||
|
const CMakeConfig cache = parsedConfiguration();
|
||||||
|
if (cache.isEmpty())
|
||||||
|
return; // No cache file yet.
|
||||||
|
|
||||||
|
CMakeConfig newConfig;
|
||||||
|
QSet<QString> changedKeys;
|
||||||
|
QSet<QString> removedKeys;
|
||||||
|
foreach (const CMakeConfigItem &iBc, intendedConfiguration()) {
|
||||||
|
const CMakeConfigItem &iCache
|
||||||
|
= Utils::findOrDefault(cache, [&iBc](const CMakeConfigItem &i) { return i.key == iBc.key; });
|
||||||
|
if (iCache.isNull()) {
|
||||||
|
removedKeys << QString::fromUtf8(iBc.key);
|
||||||
|
} else if (QString::fromUtf8(iCache.value) != iBc.expandedValue(k)) {
|
||||||
|
changedKeys << QString::fromUtf8(iBc.key);
|
||||||
|
newConfig.append(iCache);
|
||||||
|
} else {
|
||||||
|
newConfig.append(iBc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!changedKeys.isEmpty() || !removedKeys.isEmpty()) {
|
||||||
|
QSet<QString> total = removedKeys + changedKeys;
|
||||||
|
QStringList keyList = total.toList();
|
||||||
|
Utils::sort(keyList);
|
||||||
|
QString table = QLatin1String("<table>");
|
||||||
|
foreach (const QString &k, keyList) {
|
||||||
|
QString change;
|
||||||
|
if (removedKeys.contains(k))
|
||||||
|
change = tr("<removed>");
|
||||||
|
else
|
||||||
|
change = QString::fromUtf8(CMakeConfigItem::valueOf(k.toUtf8(), cache)).trimmed();
|
||||||
|
if (change.isEmpty())
|
||||||
|
change = tr("<empty>");
|
||||||
|
table += QString::fromLatin1("\n<tr><td>%1</td><td>%2</td></tr>").arg(k).arg(change.toHtmlEscaped());
|
||||||
|
}
|
||||||
|
table += QLatin1String("\n</table>");
|
||||||
|
|
||||||
|
QPointer<QMessageBox> box = new QMessageBox(Core::ICore::mainWindow());
|
||||||
|
box->setText(tr("CMake configuration has changed on disk."));
|
||||||
|
box->setInformativeText(tr("The CMakeCache.txt file has changed: %1").arg(table));
|
||||||
|
box->setStandardButtons(QMessageBox::Discard | QMessageBox::Apply);
|
||||||
|
box->setDefaultButton(QMessageBox::Discard);
|
||||||
|
|
||||||
|
int ret = box->exec();
|
||||||
|
if (ret == QMessageBox::Apply)
|
||||||
|
m_buildConfiguration->setCMakeConfiguration(newConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static QByteArray trimCMakeCacheLine(const QByteArray &in) {
|
static QByteArray trimCMakeCacheLine(const QByteArray &in) {
|
||||||
int start = 0;
|
int start = 0;
|
||||||
while (start < in.count() && (in.at(start) == ' ' || in.at(start) == '\t'))
|
while (start < in.count() && (in.at(start) == ' ' || in.at(start) == '\t'))
|
||||||
@@ -602,6 +664,8 @@ CMakeConfig BuildDirManager::parseConfiguration(const Utils::FileName &cacheFile
|
|||||||
|
|
||||||
void BuildDirManager::maybeForceReparse()
|
void BuildDirManager::maybeForceReparse()
|
||||||
{
|
{
|
||||||
|
checkConfiguration();
|
||||||
|
|
||||||
const QByteArray GENERATOR_KEY = "CMAKE_GENERATOR";
|
const QByteArray GENERATOR_KEY = "CMAKE_GENERATOR";
|
||||||
const QByteArray EXTRA_GENERATOR_KEY = "CMAKE_EXTRA_GENERATOR";
|
const QByteArray EXTRA_GENERATOR_KEY = "CMAKE_EXTRA_GENERATOR";
|
||||||
const QByteArray CMAKE_COMMAND_KEY = "CMAKE_COMMAND";
|
const QByteArray CMAKE_COMMAND_KEY = "CMAKE_COMMAND";
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ class BuildDirManager : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BuildDirManager(const CMakeBuildConfiguration *bc);
|
BuildDirManager(CMakeBuildConfiguration *bc);
|
||||||
~BuildDirManager() override;
|
~BuildDirManager() override;
|
||||||
|
|
||||||
const ProjectExplorer::Kit *kit() const;
|
const ProjectExplorer::Kit *kit() const;
|
||||||
@@ -87,6 +87,8 @@ public:
|
|||||||
void clearFiles();
|
void clearFiles();
|
||||||
CMakeConfig parsedConfiguration() const;
|
CMakeConfig parsedConfiguration() const;
|
||||||
|
|
||||||
|
void checkConfiguration();
|
||||||
|
|
||||||
static CMakeConfig parseConfiguration(const Utils::FileName &cacheFile,
|
static CMakeConfig parseConfiguration(const Utils::FileName &cacheFile,
|
||||||
QString *errorMessage);
|
QString *errorMessage);
|
||||||
|
|
||||||
@@ -106,10 +108,9 @@ private:
|
|||||||
void processCMakeOutput();
|
void processCMakeOutput();
|
||||||
void processCMakeError();
|
void processCMakeError();
|
||||||
|
|
||||||
|
|
||||||
bool m_hasData = false;
|
bool m_hasData = false;
|
||||||
|
|
||||||
const CMakeBuildConfiguration *m_buildConfiguration = nullptr;
|
CMakeBuildConfiguration *m_buildConfiguration = nullptr;
|
||||||
Utils::QtcProcess *m_cmakeProcess = nullptr;
|
Utils::QtcProcess *m_cmakeProcess = nullptr;
|
||||||
QTemporaryDir *m_tempDir = nullptr;
|
QTemporaryDir *m_tempDir = nullptr;
|
||||||
mutable CMakeConfig m_cmakeCache;
|
mutable CMakeConfig m_cmakeCache;
|
||||||
|
|||||||
@@ -305,9 +305,11 @@ void CMakeProject::runCMake()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
BuildDirManager *bdm = bc->buildDirManager();
|
BuildDirManager *bdm = bc->buildDirManager();
|
||||||
if (bdm && !bdm->isParsing())
|
if (bdm && !bdm->isParsing()) {
|
||||||
|
bdm->checkConfiguration();
|
||||||
bdm->forceReparse();
|
bdm->forceReparse();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QList<CMakeBuildTarget> CMakeProject::buildTargets() const
|
QList<CMakeBuildTarget> CMakeProject::buildTargets() const
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user