Commit 36cfa32a authored by Tobias Hunger's avatar Tobias Hunger

CMake: Use ServerModeReader to retrieve data

Change-Id: I415dbf7ca79c909eea23ef3dc3a1d87438e9f261
Reviewed-by: Tim Jenssen's avatarTim Jenssen <tim.jenssen@qt.io>
parent c7521003
......@@ -80,17 +80,23 @@ BuildDirManager::BuildDirManager(CMakeBuildConfiguration *bc) :
connect(&m_reparseTimer, &QTimer::timeout, this, &BuildDirManager::parse);
}
BuildDirManager::~BuildDirManager() = default;
const Utils::FileName BuildDirManager::workDirectory() const
{
const Utils::FileName bdir = m_buildConfiguration->buildDirectory();
if (bdir.exists())
return bdir;
if (!m_tempDir)
m_tempDir.reset(new QTemporaryDir(QDir::tempPath() + QLatin1String("/qtc-cmake-XXXXXX")));
if (!m_tempDir) {
const QString path = QDir::tempPath() + QLatin1String("/qtc-cmake-XXXXXX");
m_tempDir.reset(new QTemporaryDir(path));
if (!m_tempDir->isValid())
emit errorOccured(tr("Failed to create temporary directory using template \"%1\".").arg(path));
}
return Utils::FileName::fromString(m_tempDir->path());
}
void BuildDirManager::updateReader()
void BuildDirManager::updateReaderType(std::function<void()> todo)
{
BuildDirReader::Parameters p(m_buildConfiguration);
p.buildDirectory = workDirectory();
......@@ -106,6 +112,92 @@ void BuildDirManager::updateReader()
connect(m_reader.get(), &BuildDirReader::dirty, this, &BuildDirManager::becameDirty);
}
m_reader->setParameters(p);
if (m_reader->isReady())
todo();
else
connect(m_reader.get(), &BuildDirReader::isReadyNow, this, todo);
}
void BuildDirManager::updateReaderData()
{
BuildDirReader::Parameters p(m_buildConfiguration);
p.buildDirectory = workDirectory();
m_reader->setParameters(p);
}
void BuildDirManager::parseOnceReaderReady(bool force)
{
checkConfiguration();
m_reader->stop();
m_reader->parse(force);
}
void BuildDirManager::maybeForceReparseOnceReaderReady()
{
checkConfiguration();
const QByteArray GENERATOR_KEY = "CMAKE_GENERATOR";
const QByteArray EXTRA_GENERATOR_KEY = "CMAKE_EXTRA_GENERATOR";
const QByteArray CMAKE_COMMAND_KEY = "CMAKE_COMMAND";
const QByteArrayList criticalKeys
= QByteArrayList() << GENERATOR_KEY << CMAKE_COMMAND_KEY;
if (!m_reader->hasData()) {
forceReparse();
return;
}
const CMakeConfig currentConfig = parsedConfiguration();
Kit *k = m_buildConfiguration->target()->kit();
const CMakeTool *tool = CMakeKitInformation::cmakeTool(k);
QTC_ASSERT(tool, return); // No cmake... we should not have ended up here in the first place
const QString extraKitGenerator = CMakeGeneratorKitInformation::extraGenerator(k);
const QString mainKitGenerator = CMakeGeneratorKitInformation::generator(k);
CMakeConfig targetConfig = m_buildConfiguration->cmakeConfiguration();
targetConfig.append(CMakeConfigItem(GENERATOR_KEY, CMakeConfigItem::INTERNAL,
QByteArray(), mainKitGenerator.toUtf8()));
if (!extraKitGenerator.isEmpty())
targetConfig.append(CMakeConfigItem(EXTRA_GENERATOR_KEY, CMakeConfigItem::INTERNAL,
QByteArray(), extraKitGenerator.toUtf8()));
targetConfig.append(CMakeConfigItem(CMAKE_COMMAND_KEY, CMakeConfigItem::INTERNAL,
QByteArray(), tool->cmakeExecutable().toUserOutput().toUtf8()));
Utils::sort(targetConfig, CMakeConfigItem::sortOperator());
bool mustReparse = false;
auto ccit = currentConfig.constBegin();
auto kcit = targetConfig.constBegin();
while (ccit != currentConfig.constEnd() && kcit != targetConfig.constEnd()) {
if (ccit->key == kcit->key) {
if (ccit->value != kcit->value) {
if (criticalKeys.contains(kcit->key)) {
clearCache();
return;
}
mustReparse = true;
}
++ccit;
++kcit;
} else {
if (ccit->key < kcit->key) {
++ccit;
} else {
++kcit;
mustReparse = true;
}
}
}
// If we have keys that do not exist yet, then reparse.
//
// The critical keys *must* be set in cmake configuration, so those were already
// handled above.
if (mustReparse || kcit != targetConfig.constEnd())
parseOnceReaderReady(true);
}
bool BuildDirManager::isParsing() const
......@@ -136,12 +228,10 @@ void BuildDirManager::forceReparse()
if (m_buildConfiguration->target()->activeBuildConfiguration() != m_buildConfiguration)
return;
CMakeTool *tool = CMakeKitInformation::cmakeTool(m_buildConfiguration->target()->kit());
QTC_ASSERT(tool, return);
m_reader->stop();
m_reader->parse(true);
updateReaderType([this]() { parseOnceReaderReady(true); });
}
void BuildDirManager::resetData()
......@@ -188,10 +278,7 @@ QSet<Core::Id> BuildDirManager::updateCodeModel(CppTools::ProjectPartBuilder &pp
void BuildDirManager::parse()
{
updateReader();
checkConfiguration();
QTC_ASSERT(m_reader, return);
m_reader->parse(false);
updateReaderType([this]() { parseOnceReaderReady(false); });
}
void BuildDirManager::clearCache()
......@@ -228,8 +315,6 @@ void BuildDirManager::checkConfiguration()
if (m_tempDir) // always throw away changes in the tmpdir!
return;
updateReader();
Kit *k = m_buildConfiguration->target()->kit();
const CMakeConfig cache = m_reader->parsedConfiguration();
if (cache.isEmpty())
......@@ -278,75 +363,14 @@ void BuildDirManager::checkConfiguration()
int ret = box->exec();
if (ret == QMessageBox::Apply) {
m_buildConfiguration->setCMakeConfiguration(newConfig);
updateReader(); // Apply changes to reader
updateReaderData(); // Apply changes to reader
}
}
}
void BuildDirManager::maybeForceReparse()
{
checkConfiguration();
const QByteArray GENERATOR_KEY = "CMAKE_GENERATOR";
const QByteArray EXTRA_GENERATOR_KEY = "CMAKE_EXTRA_GENERATOR";
const QByteArray CMAKE_COMMAND_KEY = "CMAKE_COMMAND";
const QByteArrayList criticalKeys
= QByteArrayList() << GENERATOR_KEY << CMAKE_COMMAND_KEY;
if (!m_reader->hasData()) {
forceReparse();
return;
}
const CMakeConfig currentConfig = parsedConfiguration();
Kit *k = m_buildConfiguration->target()->kit();
const CMakeTool *tool = CMakeKitInformation::cmakeTool(k);
QTC_ASSERT(tool, return); // No cmake... we should not have ended up here in the first place
const QString extraKitGenerator = CMakeGeneratorKitInformation::extraGenerator(k);
const QString mainKitGenerator = CMakeGeneratorKitInformation::generator(k);
CMakeConfig targetConfig = m_buildConfiguration->cmakeConfiguration();
targetConfig.append(CMakeConfigItem(GENERATOR_KEY, CMakeConfigItem::INTERNAL,
QByteArray(), mainKitGenerator.toUtf8()));
if (!extraKitGenerator.isEmpty())
targetConfig.append(CMakeConfigItem(EXTRA_GENERATOR_KEY, CMakeConfigItem::INTERNAL,
QByteArray(), extraKitGenerator.toUtf8()));
targetConfig.append(CMakeConfigItem(CMAKE_COMMAND_KEY, CMakeConfigItem::INTERNAL,
QByteArray(), tool->cmakeExecutable().toUserOutput().toUtf8()));
Utils::sort(targetConfig, CMakeConfigItem::sortOperator());
bool mustReparse = false;
auto ccit = currentConfig.constBegin();
auto kcit = targetConfig.constBegin();
while (ccit != currentConfig.constEnd() && kcit != targetConfig.constEnd()) {
if (ccit->key == kcit->key) {
if (ccit->value != kcit->value) {
if (criticalKeys.contains(kcit->key)) {
clearCache();
return;
}
mustReparse = true;
}
++ccit;
++kcit;
} else {
if (ccit->key < kcit->key) {
++ccit;
} else {
++kcit;
mustReparse = true;
}
}
}
// If we have keys that do not exist yet, then reparse.
//
// The critical keys *must* be set in cmake configuration, so those were already
// handled above.
if (mustReparse || kcit != targetConfig.constEnd())
forceReparse();
updateReaderType([this]() { maybeForceReparseOnceReaderReady(); });
}
} // namespace Internal
......
......@@ -34,6 +34,7 @@
#include <QTemporaryDir>
#include <QTimer>
#include <functional>
#include <memory>
namespace CppTools { class ProjectPartBuilder; }
......@@ -59,6 +60,7 @@ class BuildDirManager : public QObject
public:
BuildDirManager(CMakeBuildConfiguration *bc);
~BuildDirManager() final;
bool isParsing() const;
......@@ -75,8 +77,6 @@ public:
QList<CMakeBuildTarget> buildTargets() const;
CMakeConfig parsedConfiguration() const;
void checkConfiguration();
signals:
void configurationStarted() const;
void dataAvailable() const;
......@@ -89,7 +89,13 @@ protected:
const Utils::FileName workDirectory() const;
private:
void updateReader();
void checkConfiguration();
void updateReaderType(std::function<void()> todo);
void updateReaderData();
void parseOnceReaderReady(bool force);
void maybeForceReparseOnceReaderReady();
void parse();
......
......@@ -27,6 +27,7 @@
#include "cmakebuildconfiguration.h"
#include "cmakekitinformation.h"
#include "servermodereader.h"
#include "tealeafreader.h"
#include <projectexplorer/kitinformation.h>
......@@ -82,7 +83,8 @@ BuildDirReader::Parameters::Parameters(const BuildDirReader::Parameters &other)
BuildDirReader *BuildDirReader::createReader(const BuildDirReader::Parameters &p)
{
Q_UNUSED(p); // FIXME
if (p.cmakeHasServerMode)
return new ServerModeReader;
return new TeaLeafReader;
}
......
......@@ -185,7 +185,6 @@ void CMakeBuildConfiguration::runCMake()
if (!m_buildDirManager || m_buildDirManager->isParsing())
return;
m_buildDirManager->checkConfiguration();
m_buildDirManager->forceReparse();
}
......
......@@ -432,20 +432,7 @@ void ServerModeReader::extractCacheData(const QVariantMap &data)
CMakeConfigItem item;
item.key = eData.value("key").toByteArray();
item.value = eData.value("value").toByteArray();
item.type = CMakeConfigItem::STRING;
const QByteArray typeId = eData.value("type").toByteArray();
if (typeId == "FILEPATH")
item.type = CMakeConfigItem::STRING;
else if (typeId == "PATH")
item.type = CMakeConfigItem::PATH;
else if (typeId == "BOOL")
item.type = CMakeConfigItem::BOOL;
else if (typeId == "INTERNAL")
item.type = CMakeConfigItem::INTERNAL;
else if (typeId == "STRING")
item.type = CMakeConfigItem::STRING;
else if (typeId == "STATIC")
item.type = CMakeConfigItem::STATIC;
item.type = CMakeConfigItem::typeStringToType(eData.value("type").toByteArray());
const QVariantMap properties = eData.value("properties").toMap();
item.isAdvanced = properties.value("ADVANCED", false).toBool();
item.documentation = properties.value("HELPSTRING").toByteArray();
......
......@@ -164,8 +164,7 @@ TeaLeafReader::~TeaLeafReader()
bool TeaLeafReader::isCompatible(const BuildDirReader::Parameters &p)
{
Q_UNUSED(p);
return true; // FIXME: Needs to take server mode into account!
return !p.cmakeHasServerMode;
}
void TeaLeafReader::resetData()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment