CMake: Delay initialization of CMakeTools

Do not run cmake 5 times during startup. Delay that as far as possible.

Also add a supportedGenerators() method while visiting the code anyway.

Fix up and simplify the other cmake help output parsers.

Change-Id: I6622d552ffe559bf099b4b278618676a045e350e
Reviewed-by: Tobias Hunger <tobias.hunger@theqtcompany.com>
This commit is contained in:
Tobias Hunger
2016-01-22 13:50:58 +01:00
parent acdfb09687
commit fa17e27b7f
5 changed files with 210 additions and 266 deletions

View File

@@ -46,8 +46,6 @@ using namespace ProjectExplorer;
// ------------------------------- // -------------------------------
// CMakeFileCompletionAssistProvider // CMakeFileCompletionAssistProvider
// ------------------------------- // -------------------------------
CMakeFileCompletionAssistProvider::CMakeFileCompletionAssistProvider()
{}
bool CMakeFileCompletionAssistProvider::supportsEditor(Core::Id editorId) const bool CMakeFileCompletionAssistProvider::supportsEditor(Core::Id editorId) const
{ {
@@ -56,31 +54,26 @@ bool CMakeFileCompletionAssistProvider::supportsEditor(Core::Id editorId) const
IAssistProcessor *CMakeFileCompletionAssistProvider::createProcessor() const IAssistProcessor *CMakeFileCompletionAssistProvider::createProcessor() const
{ {
return new CMakeFileCompletionAssist(); return new CMakeFileCompletionAssist;
} }
CMakeFileCompletionAssist::CMakeFileCompletionAssist() : CMakeFileCompletionAssist::CMakeFileCompletionAssist() :
KeywordsCompletionAssistProcessor(Keywords()) KeywordsCompletionAssistProcessor(Keywords())
{} {}
IAssistProposal *CMakeFileCompletionAssist::perform(const AssistInterface *interface) IAssistProposal *CMakeFileCompletionAssist::perform(const AssistInterface *interface)
{ {
TextEditor::Keywords keywords; Keywords kw;
QString fileName = interface->fileName(); QString fileName = interface->fileName();
if (!fileName.isEmpty() && QFileInfo(fileName).isFile()) { if (!fileName.isEmpty() && QFileInfo(fileName).isFile()) {
Utils::FileName file = Utils::FileName::fromString(fileName); Project *p = SessionManager::projectForFile(Utils::FileName::fromString(fileName));
if (Project *p = SessionManager::projectForFile(file)) { if (p && p->activeTarget()) {
if (Target *t = p->activeTarget()) { CMakeTool *cmake = CMakeKitInformation::cmakeTool(p->activeTarget()->kit());
if (CMakeTool *cmake = CMakeKitInformation::cmakeTool(t->kit())) { if (cmake && cmake->isValid())
if (cmake->isValid()) kw = cmake->keywords();
keywords = cmake->keywords();
}
}
} }
} }
setKeywords(keywords); setKeywords(kw);
return KeywordsCompletionAssistProcessor::perform(interface); return KeywordsCompletionAssistProcessor::perform(interface);
} }

View File

@@ -47,8 +47,6 @@ class CMakeFileCompletionAssistProvider : public TextEditor::CompletionAssistPro
Q_OBJECT Q_OBJECT
public: public:
CMakeFileCompletionAssistProvider();
bool supportsEditor(Core::Id editorId) const override; bool supportsEditor(Core::Id editorId) const override;
TextEditor::IAssistProcessor *createProcessor() const override; TextEditor::IAssistProcessor *createProcessor() const override;
}; };

View File

@@ -26,12 +26,16 @@
#include "cmaketool.h" #include "cmaketool.h"
#include "cmaketoolmanager.h" #include "cmaketoolmanager.h"
#include <utils/algorithm.h>
#include <utils/environment.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <QProcess>
#include <QFileInfo> #include <QFileInfo>
#include <QProcess>
#include <QSet>
#include <QTextDocument> #include <QTextDocument>
#include <QUuid> #include <QUuid>
#include <QVariantMap>
using namespace CMakeProjectManager; using namespace CMakeProjectManager;
@@ -44,16 +48,12 @@ const char CMAKE_INFORMATION_AUTODETECTED[] = "AutoDetected";
// CMakeTool // CMakeTool
/////////////////////////// ///////////////////////////
CMakeTool::CMakeTool(Detection d, const Core::Id &id) : CMakeTool::CMakeTool(Detection d, const Core::Id &id) :
m_isAutoDetected(d == AutoDetection), m_id(id), m_isAutoDetected(d == AutoDetection)
m_id(id)
{ {
//make sure every CMakeTool has a valid ID QTC_ASSERT(m_id.isValid(), m_id = Core::Id::fromString(QUuid::createUuid().toString()));
if (!m_id.isValid())
createId();
} }
CMakeTool::CMakeTool(const QVariantMap &map, bool fromSdk) : CMakeTool::CMakeTool(const QVariantMap &map, bool fromSdk) : m_isAutoDetected(fromSdk)
m_isAutoDetected(fromSdk)
{ {
m_id = Core::Id::fromSetting(map.value(QLatin1String(CMAKE_INFORMATION_ID))); m_id = Core::Id::fromSetting(map.value(QLatin1String(CMAKE_INFORMATION_ID)));
m_displayName = map.value(QLatin1String(CMAKE_INFORMATION_DISPLAYNAME)).toString(); m_displayName = map.value(QLatin1String(CMAKE_INFORMATION_DISPLAYNAME)).toString();
@@ -62,106 +62,57 @@ CMakeTool::CMakeTool(const QVariantMap &map, bool fromSdk) :
if (!fromSdk) if (!fromSdk)
m_isAutoDetected = map.value(QLatin1String(CMAKE_INFORMATION_AUTODETECTED), false).toBool(); m_isAutoDetected = map.value(QLatin1String(CMAKE_INFORMATION_AUTODETECTED), false).toBool();
setCMakeExecutable(Utils::FileName::fromUserInput(map.value(QLatin1String(CMAKE_INFORMATION_COMMAND)).toString())); setCMakeExecutable(Utils::FileName::fromString(map.value(QLatin1String(CMAKE_INFORMATION_COMMAND)).toString()));
} }
CMakeTool::~CMakeTool() Core::Id CMakeTool::createId()
{ {
cancel(); return Core::Id::fromString(QUuid::createUuid().toString());
}
void CMakeTool::cancel()
{
if (m_process) {
disconnect(m_process, static_cast<void (QProcess::*)(int)>(&QProcess::finished),
this, &CMakeTool::finished);
if (m_process->state() != QProcess::NotRunning)
m_process->kill();
m_process->waitForFinished();
delete m_process;
m_process = 0;
}
} }
void CMakeTool::setCMakeExecutable(const Utils::FileName &executable) void CMakeTool::setCMakeExecutable(const Utils::FileName &executable)
{ {
cancel(); if (m_executable == executable)
m_process = new QProcess(); return;
connect(m_process, static_cast<void (QProcess::*)(int)>(&QProcess::finished), this, &CMakeTool::finished);
m_didRun = false;
m_didAttemptToRun = false;
m_executable = executable; m_executable = executable;
QFileInfo fi = m_executable.toFileInfo();
if (fi.exists() && fi.isExecutable()) {
// Run it to find out more
m_state = CMakeTool::RunningBasic;
if (!startProcess(QStringList(QLatin1String("--help"))))
m_state = CMakeTool::Invalid;
} else {
m_state = CMakeTool::Invalid;
}
CMakeToolManager::notifyAboutUpdate(this); CMakeToolManager::notifyAboutUpdate(this);
} }
void CMakeTool::finished(int exitCode)
{
if (exitCode) {
m_state = CMakeTool::Invalid;
return;
}
if (m_state == CMakeTool::RunningBasic) {
QByteArray response = m_process->readAll();
m_hasCodeBlocksMsvcGenerator = response.contains("CodeBlocks - NMake Makefiles");
m_hasCodeBlocksNinjaGenerator = response.contains("CodeBlocks - Ninja");
if (response.isEmpty()) {
m_state = CMakeTool::Invalid;
} else {
m_state = CMakeTool::RunningFunctionList;
if (!startProcess(QStringList(QLatin1String("--help-command-list"))))
finished(0); // should never happen, just continue
}
} else if (m_state == CMakeTool::RunningFunctionList) {
parseFunctionOutput(m_process->readAll());
m_state = CMakeTool::RunningFunctionDetails;
if (!startProcess(QStringList(QLatin1String("--help-commands"))))
finished(0); // should never happen, just continue
} else if (m_state == CMakeTool::RunningFunctionDetails) {
parseFunctionDetailsOutput(m_process->readAll());
m_state = CMakeTool::RunningPropertyList;
if (!startProcess(QStringList(QLatin1String("--help-property-list"))))
finished(0); // should never happen, just continue
} else if (m_state == CMakeTool::RunningPropertyList) {
parseVariableOutput(m_process->readAll());
m_state = CMakeTool::RunningVariableList;
if (!startProcess(QStringList(QLatin1String("--help-variable-list"))))
finished(0); // should never happen, just continue
} else if (m_state == CMakeTool::RunningVariableList) {
parseVariableOutput(m_process->readAll());
parseDone();
m_state = CMakeTool::RunningDone;
}
}
bool CMakeTool::isValid() const bool CMakeTool::isValid() const
{ {
if (m_state == CMakeTool::Invalid || !m_id.isValid()) if (!m_id.isValid())
return false; return false;
if (m_state == CMakeTool::RunningBasic) {
if (!m_process->waitForFinished(10000)) { if (!m_didAttemptToRun)
return false; supportedGenerators();
}
} return m_didRun;
return (m_state != CMakeTool::Invalid);
} }
void CMakeTool::createId() Utils::SynchronousProcessResponse CMakeTool::run(const QString &arg) const
{ {
QTC_ASSERT(!m_id.isValid(), return); if (m_didAttemptToRun && !m_didRun) {
m_id = Core::Id::fromString(QUuid::createUuid().toString()); Utils::SynchronousProcessResponse response;
response.result = Utils::SynchronousProcessResponse::StartFailed;
return response;
}
Utils::SynchronousProcess cmake;
cmake.setTimeoutS(1);
cmake.setFlags(Utils::SynchronousProcess::UnixTerminalDisabled);
Utils::Environment env = Utils::Environment::systemEnvironment();
env.set(QLatin1String("LC_ALL"), QLatin1String("C"));
cmake.setProcessEnvironment(env.toProcessEnvironment());
cmake.setTimeOutMessageBoxEnabled(false);
Utils::SynchronousProcessResponse response = cmake.run(m_executable.toString(), QStringList() << arg);
m_didAttemptToRun = true;
m_didRun = (response.result == Utils::SynchronousProcessResponse::Finished);
return response;
} }
QVariantMap CMakeTool::toMap() const QVariantMap CMakeTool::toMap() const
@@ -174,12 +125,6 @@ QVariantMap CMakeTool::toMap() const
return data; return data;
} }
bool CMakeTool::startProcess(const QStringList &args)
{
m_process->start(m_executable.toString(), args);
return m_process->waitForStarted(2000);
}
Utils::FileName CMakeTool::cmakeExecutable() const Utils::FileName CMakeTool::cmakeExecutable() const
{ {
return m_executable; return m_executable;
@@ -189,24 +134,70 @@ bool CMakeTool::hasCodeBlocksMsvcGenerator() const
{ {
if (!isValid()) if (!isValid())
return false; return false;
return m_hasCodeBlocksMsvcGenerator; return supportedGenerators().contains(QLatin1String("CodeBlocks - NMake Makefiles"));
} }
bool CMakeTool::hasCodeBlocksNinjaGenerator() const bool CMakeTool::hasCodeBlocksNinjaGenerator() const
{ {
if (!isValid()) return supportedGenerators().contains(QLatin1String("CodeBlocks - Ninja"));
return false; }
return m_hasCodeBlocksNinjaGenerator;
QStringList CMakeTool::supportedGenerators() const
{
if (m_generators.isEmpty()) {
Utils::SynchronousProcessResponse response = run(QLatin1String("--help"));
if (response.result == Utils::SynchronousProcessResponse::Finished) {
bool inGeneratorSection = false;
const QStringList lines = response.stdOut.split(QLatin1Char('\n'));
foreach (const QString &line, lines) {
if (line.isEmpty())
continue;
if (line == QLatin1String("Generators"))
inGeneratorSection = true;
if (!inGeneratorSection)
continue;
if (line.startsWith(QLatin1String(" "))) {
int pos = line.indexOf(QLatin1Char('='));
if (pos < 0)
pos = line.length();
if (pos >= 0) {
--pos;
while (pos > 2 && line.at(pos).isSpace())
--pos;
}
if (pos > 2)
m_generators.append(line.mid(2, pos - 1));
}
}
}
}
return m_generators;
} }
TextEditor::Keywords CMakeTool::keywords() TextEditor::Keywords CMakeTool::keywords()
{ {
while (m_state != RunningDone && m_state != CMakeTool::Invalid) { if (m_functions.isEmpty()) {
m_process->waitForFinished(); Utils::SynchronousProcessResponse response;
} response = run(QLatin1String("--help-command-list"));
if (response.result == Utils::SynchronousProcessResponse::Finished)
m_functions = response.stdOut.split(QLatin1Char('\n'));
if (m_state == CMakeTool::Invalid) response = run(QLatin1String("--help-commands"));
return TextEditor::Keywords(QStringList(), QStringList(), QMap<QString, QStringList>()); if (response.result == Utils::SynchronousProcessResponse::Finished)
parseFunctionDetailsOutput(response.stdOut);
response = run(QLatin1String("--help-property-list"));
if (response.result == Utils::SynchronousProcessResponse::Finished)
m_variables = parseVariableOutput(response.stdOut);
response = run(QLatin1String("--help-variable-list"));
if (response.result == Utils::SynchronousProcessResponse::Finished) {
m_variables.append(parseVariableOutput(response.stdOut));
m_variables = Utils::filteredUnique(m_variables);
Utils::sort(m_variables);
}
}
return TextEditor::Keywords(m_variables, m_functions, m_functionArgs); return TextEditor::Keywords(m_variables, m_functions, m_functionArgs);
} }
@@ -216,53 +207,6 @@ bool CMakeTool::isAutoDetected() const
return m_isAutoDetected; return m_isAutoDetected;
} }
static void extractKeywords(const QByteArray &input, QStringList *destination)
{
if (!destination)
return;
QString keyword;
int ignoreZone = 0;
for (int i = 0; i < input.count(); ++i) {
const QChar chr = QLatin1Char(input.at(i));
if (chr == QLatin1Char('{'))
++ignoreZone;
if (chr == QLatin1Char('}'))
--ignoreZone;
if (ignoreZone == 0) {
if ((chr.isLetterOrNumber() && chr.isUpper())
|| chr == QLatin1Char('_')) {
keyword += chr;
} else {
if (!keyword.isEmpty()) {
if (keyword.size() > 1)
*destination << keyword;
keyword.clear();
}
}
}
}
if (keyword.size() > 1)
*destination << keyword;
}
void CMakeTool::parseFunctionOutput(const QByteArray &output)
{
QList<QByteArray> cmakeFunctionsList = output.split('\n');
m_functions.clear();
if (!cmakeFunctionsList.isEmpty()) {
cmakeFunctionsList.removeFirst(); //remove version string
foreach (const QByteArray &function, cmakeFunctionsList)
m_functions << QString::fromLocal8Bit(function.trimmed());
}
}
QString CMakeTool::formatFunctionDetails(const QString &command, const QString &args)
{
return QString::fromLatin1("<table><tr><td><b>%1</b></td><td>%2</td></tr>")
.arg(command.toHtmlEscaped(), args.toHtmlEscaped());
}
QString CMakeTool::displayName() const QString CMakeTool::displayName() const
{ {
return m_displayName; return m_displayName;
@@ -286,78 +230,91 @@ QString CMakeTool::mapAllPaths(ProjectExplorer::Kit *kit, const QString &in) con
return in; return in;
} }
void CMakeTool::parseFunctionDetailsOutput(const QByteArray &output) static QStringList parseDefinition(const QString &definition)
{ {
QStringList cmakeFunctionsList = m_functions; QStringList result;
QList<QByteArray> cmakeCommandsHelp = output.split('\n'); QString word;
for (int i = 0; i < cmakeCommandsHelp.count(); ++i) { bool ignoreWord = false;
QByteArray lineTrimmed = cmakeCommandsHelp.at(i).trimmed(); QVector<QChar> braceStack;
if (cmakeFunctionsList.isEmpty())
break;
if (cmakeFunctionsList.first().toLatin1() == lineTrimmed) {
QStringList commandSyntaxes;
QString currentCommandSyntax;
QString currentCommand = cmakeFunctionsList.takeFirst();
++i;
for (; i < cmakeCommandsHelp.count(); ++i) {
lineTrimmed = cmakeCommandsHelp.at(i).trimmed();
if (!cmakeFunctionsList.isEmpty() && cmakeFunctionsList.first().toLatin1() == lineTrimmed) { foreach (const QChar &c, definition) {
//start of next function in output if (c == QLatin1Char('[') || c == QLatin1Char('<') || c == QLatin1Char('(')) {
if (!currentCommandSyntax.isEmpty()) braceStack.append(c);
commandSyntaxes << currentCommandSyntax.append(QLatin1String("</table>")); ignoreWord = false;
--i; } else if (c == QLatin1Char(']') || c == QLatin1Char('>') || c == QLatin1Char(')')) {
break; if (braceStack.isEmpty() || braceStack.takeLast() == QLatin1Char('<'))
ignoreWord = true;
} }
if (lineTrimmed.startsWith(currentCommand.toLatin1() + "(")) {
if (!currentCommandSyntax.isEmpty())
commandSyntaxes << currentCommandSyntax.append(QLatin1String("</table>"));
QByteArray argLine = lineTrimmed.mid(currentCommand.length()); if (c == QLatin1Char(' ') || c == QLatin1Char('[') || c == QLatin1Char('<') || c == QLatin1Char('(')
extractKeywords(argLine, &m_variables); || c == QLatin1Char(']') || c == QLatin1Char('>') || c == QLatin1Char(')')) {
currentCommandSyntax = formatFunctionDetails(currentCommand, QString::fromUtf8(argLine)); if (!ignoreWord && !word.isEmpty()) {
if (result.isEmpty() || Utils::allOf(word, [](const QChar &c) { return c.isUpper() || c == QLatin1Char('_'); }))
result.append(word);
}
word.clear();
ignoreWord = false;
} else { } else {
if (!currentCommandSyntax.isEmpty()) { word.append(c);
if (lineTrimmed.isEmpty()) { }
commandSyntaxes << currentCommandSyntax.append(QLatin1String("</table>")); }
currentCommandSyntax.clear(); return result;
}
void CMakeTool::parseFunctionDetailsOutput(const QString &output)
{
QSet<QString> functionSet;
functionSet.fromList(m_functions);
bool expectDefinition = false;
QString currentDefinition;
const QStringList lines = output.split(QLatin1Char('\n'));
for (int i = 0; i < lines.count(); ++i) {
const QString line = lines.at(i);
if (line == QLatin1String("::")) {
expectDefinition = true;
continue;
}
if (expectDefinition) {
if (!line.startsWith(QLatin1Char(' ')) && !line.isEmpty()) {
expectDefinition = false;
QStringList words = parseDefinition(currentDefinition);
if (!words.isEmpty()) {
const QString command = words.takeFirst();
if (functionSet.contains(command)) {
QStringList tmp = words + m_functionArgs[command];
Utils::sort(tmp);
m_functionArgs[command] = Utils::filteredUnique(tmp);
}
}
if (!words.isEmpty() && functionSet.contains(words.at(0)))
m_functionArgs[words.at(0)];
currentDefinition.clear();
} else { } else {
extractKeywords(lineTrimmed, &m_variables); currentDefinition.append(line.trimmed() + QLatin1Char(' '));
currentCommandSyntax += QString::fromLatin1("<tr><td>&nbsp;</td><td>%1</td></tr>")
.arg(QString::fromLocal8Bit(lineTrimmed).toHtmlEscaped());
}
}
}
}
m_functionArgs[currentCommand] = commandSyntaxes;
}
}
m_functions = m_functionArgs.keys();
}
void CMakeTool::parseVariableOutput(const QByteArray &output)
{
QList<QByteArray> variableList = output.split('\n');
if (!variableList.isEmpty()) {
variableList.removeFirst(); //remove version string
foreach (const QByteArray &variable, variableList) {
if (variable.contains("_<CONFIG>")) {
m_variables << QString::fromLocal8Bit(variable).replace(QLatin1String("_<CONFIG>"), QLatin1String("_DEBUG"));
m_variables << QString::fromLocal8Bit(variable).replace(QLatin1String("_<CONFIG>"), QLatin1String("_RELEASE"));
m_variables << QString::fromLocal8Bit(variable).replace(QLatin1String("_<CONFIG>"), QLatin1String("_MINSIZEREL"));
m_variables << QString::fromLocal8Bit(variable).replace(QLatin1String("_<CONFIG>"), QLatin1String("_RELWITHDEBINFO"));
} else if (variable.contains("_<LANG>")) {
m_variables << QString::fromLocal8Bit(variable).replace(QLatin1String("_<LANG>"), QLatin1String("_C"));
m_variables << QString::fromLocal8Bit(variable).replace(QLatin1String("_<LANG>"), QLatin1String("_CXX"));
} else if (!variable.contains("_<") && !variable.contains('[')) {
m_variables << QString::fromLocal8Bit(variable);
} }
} }
} }
} }
void CMakeTool::parseDone() QStringList CMakeTool::parseVariableOutput(const QString &output)
{ {
m_variables.sort(); const QStringList variableList = output.split(QLatin1Char('\n'));
m_variables.removeDuplicates(); QStringList result;
foreach (const QString &v, variableList) {
if (v.contains(QLatin1String("<CONFIG>"))) {
const QString tmp = QString(v).replace(QLatin1String("<CONFIG>"), QLatin1String("%1"));
result << tmp.arg(QLatin1String("DEBUG")) << tmp.arg(QLatin1String("RELEASE"))
<< tmp.arg(QLatin1String("MINSIZEREL")) << tmp.arg(QLatin1String("RELWITHDEBINFO"));
} else if (v.contains(QLatin1String("<LANG>"))) {
const QString tmp = QString(v).replace(QLatin1String("<LANG>"), QLatin1String("%1"));
result << tmp.arg(QLatin1String("C")) << tmp.arg(QLatin1String("CXX"));
} else if (!v.contains(QLatin1Char('<')) && !v.contains(QLatin1Char('['))) {
result << v;
}
}
return result;
} }

View File

@@ -27,12 +27,14 @@
#include "cmake_global.h" #include "cmake_global.h"
#include <texteditor/codeassist/keywordscompletionassist.h>
#include <utils/fileutils.h>
#include <coreplugin/id.h> #include <coreplugin/id.h>
#include <texteditor/codeassist/keywordscompletionassist.h>
#include <utils/fileutils.h>
#include <utils/synchronousprocess.h>
#include <QObject> #include <QObject>
#include <QString> #include <QMap>
#include <QStringList> #include <QStringList>
QT_FORWARD_DECLARE_CLASS(QProcess) QT_FORWARD_DECLARE_CLASS(QProcess)
@@ -52,23 +54,25 @@ public:
typedef std::function<QString (ProjectExplorer::Kit *, const QString &)> PathMapper; typedef std::function<QString (ProjectExplorer::Kit *, const QString &)> PathMapper;
explicit CMakeTool(Detection d, const Core::Id &id = Core::Id()); explicit CMakeTool(Detection d, const Core::Id &id);
explicit CMakeTool(const QVariantMap &map, bool fromSdk); explicit CMakeTool(const QVariantMap &map, bool fromSdk);
~CMakeTool() override; ~CMakeTool() override = default;
static Core::Id createId();
enum State { Invalid, RunningBasic, RunningFunctionList, RunningFunctionDetails,
RunningPropertyList, RunningVariableList, RunningDone };
void cancel();
bool isValid() const; bool isValid() const;
Core::Id id() const { return m_id; } Core::Id id() const { return m_id; }
QVariantMap toMap () const; QVariantMap toMap () const;
void setCMakeExecutable(const Utils::FileName &executable); void setCMakeExecutable(const Utils::FileName &executable);
Utils::FileName cmakeExecutable() const; Utils::FileName cmakeExecutable() const;
bool hasCodeBlocksMsvcGenerator() const; bool hasCodeBlocksMsvcGenerator() const;
bool hasCodeBlocksNinjaGenerator() const; bool hasCodeBlocksNinjaGenerator() const;
QStringList supportedGenerators() const;
TextEditor::Keywords keywords(); TextEditor::Keywords keywords();
bool isAutoDetected() const; bool isAutoDetected() const;
QString displayName() const; QString displayName() const;
void setDisplayName(const QString &displayName); void setDisplayName(const QString &displayName);
@@ -77,32 +81,24 @@ public:
QString mapAllPaths(ProjectExplorer::Kit *kit, const QString &in) const; QString mapAllPaths(ProjectExplorer::Kit *kit, const QString &in) const;
private: private:
void finished(int exitCode); Utils::SynchronousProcessResponse run(const QString &arg) const;
void parseFunctionDetailsOutput(const QString &output);
void createId(); QStringList parseVariableOutput(const QString &output);
void finishStep();
void startNextStep();
bool startProcess(const QStringList &args);
void parseFunctionOutput(const QByteArray &output);
void parseFunctionDetailsOutput(const QByteArray &output);
void parseVariableOutput(const QByteArray &output);
void parseDone();
QString formatFunctionDetails(const QString &command, const QString &args);
State m_state = Invalid;
QProcess *m_process = 0;
Utils::FileName m_executable;
bool m_isAutoDetected;
bool m_hasCodeBlocksMsvcGenerator = false;
bool m_hasCodeBlocksNinjaGenerator = false;
QMap<QString, QStringList> m_functionArgs;
QStringList m_variables;
QStringList m_functions;
Core::Id m_id; Core::Id m_id;
QString m_displayName; QString m_displayName;
Utils::FileName m_executable;
bool m_isAutoDetected;
mutable bool m_didAttemptToRun;
mutable bool m_didRun;
mutable QStringList m_generators;
mutable QMap<QString, QStringList> m_functionArgs;
mutable QStringList m_variables;
mutable QStringList m_functions;
PathMapper m_pathMapper; PathMapper m_pathMapper;
}; };

View File

@@ -131,7 +131,7 @@ static void readAndDeleteLegacyCMakeSettings ()
if (exec.toFileInfo().isExecutable()) { if (exec.toFileInfo().isExecutable()) {
CMakeTool *item = CMakeToolManager::findByCommand(exec); CMakeTool *item = CMakeToolManager::findByCommand(exec);
if (!item) { if (!item) {
item = new CMakeTool(CMakeTool::ManualDetection); item = new CMakeTool(CMakeTool::ManualDetection, CMakeTool::createId());
item->setCMakeExecutable(exec); item->setCMakeExecutable(exec);
item->setDisplayName(CMakeToolManager::tr("CMake at %1").arg(item->cmakeExecutable().toUserOutput())); item->setDisplayName(CMakeToolManager::tr("CMake at %1").arg(item->cmakeExecutable().toUserOutput()));
@@ -182,7 +182,7 @@ static QList<CMakeTool *> autoDetectCMakeTools()
QList<CMakeTool *> found; QList<CMakeTool *> found;
foreach (const FileName &command, suspects) { foreach (const FileName &command, suspects) {
auto item = new CMakeTool(CMakeTool::AutoDetection); auto item = new CMakeTool(CMakeTool::AutoDetection, CMakeTool::createId());
item->setCMakeExecutable(command); item->setCMakeExecutable(command);
item->setDisplayName(CMakeToolManager::tr("System CMake at %1").arg(command.toUserOutput())); item->setDisplayName(CMakeToolManager::tr("System CMake at %1").arg(command.toUserOutput()));
@@ -247,7 +247,7 @@ Id CMakeToolManager::registerOrFindCMakeTool(const FileName &command)
if (cmake) if (cmake)
return cmake->id(); return cmake->id();
cmake = new CMakeTool(CMakeTool::ManualDetection); cmake = new CMakeTool(CMakeTool::ManualDetection, CMakeTool::createId());
cmake->setCMakeExecutable(command); cmake->setCMakeExecutable(command);
cmake->setDisplayName(tr("CMake at %1").arg(command.toUserOutput())); cmake->setDisplayName(tr("CMake at %1").arg(command.toUserOutput()));