From 3ef11019e217048e4b28d17ad89c69706ef3887f Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Wed, 28 Sep 2016 15:18:29 +0200 Subject: [PATCH] CMake: Parse Generators out of new cmake -E capabilities output Makes for way more robust (and featureful) generator discovery. Change-Id: I7df837500e1c3a200960e9d157b5c105dacd4068 Reviewed-by: Tobias Hunger --- src/plugins/cmakeprojectmanager/cmaketool.cpp | 49 ++++++++++++++----- src/plugins/cmakeprojectmanager/cmaketool.h | 8 ++- 2 files changed, 43 insertions(+), 14 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/cmaketool.cpp b/src/plugins/cmakeprojectmanager/cmaketool.cpp index 642a368cfb4..f12f40824d7 100644 --- a/src/plugins/cmakeprojectmanager/cmaketool.cpp +++ b/src/plugins/cmakeprojectmanager/cmaketool.cpp @@ -31,6 +31,8 @@ #include #include +#include +#include #include #include #include @@ -110,7 +112,7 @@ bool CMakeTool::isValid() const return m_didRun; } -Utils::SynchronousProcessResponse CMakeTool::run(const QString &arg) const +Utils::SynchronousProcessResponse CMakeTool::run(const QStringList &args, bool mayFail) const { if (m_didAttemptToRun && !m_didRun) { Utils::SynchronousProcessResponse response; @@ -126,9 +128,9 @@ Utils::SynchronousProcessResponse CMakeTool::run(const QString &arg) const cmake.setProcessEnvironment(env.toProcessEnvironment()); cmake.setTimeOutMessageBoxEnabled(false); - Utils::SynchronousProcessResponse response = cmake.runBlocking(m_executable.toString(), QStringList() << arg); + Utils::SynchronousProcessResponse response = cmake.runBlocking(m_executable.toString(), args); m_didAttemptToRun = true; - m_didRun = (response.result == Utils::SynchronousProcessResponse::Finished); + m_didRun = mayFail ? true : (response.result == Utils::SynchronousProcessResponse::Finished); return response; } @@ -161,9 +163,12 @@ bool CMakeTool::isAutoRun() const QList CMakeTool::supportedGenerators() const { + if (m_generators.isEmpty()) + fetchGeneratorsFromCapabilities(); if (m_generators.isEmpty()) { fetchGeneratorsFromHelp(); } + return m_generators; } @@ -171,19 +176,19 @@ TextEditor::Keywords CMakeTool::keywords() { if (m_functions.isEmpty()) { Utils::SynchronousProcessResponse response; - response = run("--help-command-list"); + response = run({ "--help-command-list" }); if (response.result == Utils::SynchronousProcessResponse::Finished) m_functions = response.stdOut().split('\n'); - response = run("--help-commands"); + response = run({ "--help-commands" }); if (response.result == Utils::SynchronousProcessResponse::Finished) parseFunctionDetailsOutput(response.stdOut()); - response = run("--help-property-list"); + response = run({ "--help-property-list" }); if (response.result == Utils::SynchronousProcessResponse::Finished) m_variables = parseVariableOutput(response.stdOut()); - response = run("--help-variable-list"); + response = run({ "--help-variable-list" }); if (response.result == Utils::SynchronousProcessResponse::Finished) { m_variables.append(parseVariableOutput(response.stdOut())); m_variables = Utils::filteredUnique(m_variables); @@ -315,7 +320,7 @@ QStringList CMakeTool::parseVariableOutput(const QString &output) void CMakeTool::fetchGeneratorsFromHelp() const { - Utils::SynchronousProcessResponse response = run("--help"); + Utils::SynchronousProcessResponse response = run({ "--help" }); if (response.result != Utils::SynchronousProcessResponse::Finished) return; @@ -361,11 +366,29 @@ void CMakeTool::fetchGeneratorsFromHelp() const } // Populate genertor list: - for (auto it = generatorInfo.constBegin(); it != generatorInfo.constEnd(); ++it) { - Generator info; - info.name = it.key(); - info.extraGenerators = it.value(); - m_generators.append(info); + for (auto it = generatorInfo.constBegin(); it != generatorInfo.constEnd(); ++it) + m_generators.append(Generator(it.key(), it.value())); +} + +void CMakeTool::fetchGeneratorsFromCapabilities() const +{ + Utils::SynchronousProcessResponse response = run({ "-E", "capabilities" }, true); + if (response.result != Utils::SynchronousProcessResponse::Finished) + return; + + auto doc = QJsonDocument::fromJson(response.stdOut().toUtf8()); + if (!doc.isObject()) + return; + + const QVariantMap data = doc.object().toVariantMap(); + m_hasServerMode = data.value("serverMode").toBool(); + const QVariantList generatorList = data.value("generators").toList(); + for (const QVariant &v : generatorList) { + const QVariantMap gen = v.toMap(); + m_generators.append(Generator(gen.value("name").toString(), + gen.value("extraGenerators").toStringList(), + gen.value("platformSupport").toBool(), + gen.value("toolsetSupport").toBool())); } } diff --git a/src/plugins/cmakeprojectmanager/cmaketool.h b/src/plugins/cmakeprojectmanager/cmaketool.h index 8ddc8eafa2e..30193262cbd 100644 --- a/src/plugins/cmakeprojectmanager/cmaketool.h +++ b/src/plugins/cmakeprojectmanager/cmaketool.h @@ -55,6 +55,10 @@ public: class Generator { public: + Generator(const QString &n, const QStringList &eg, bool pl = true, bool ts = true) : + name(n), extraGenerators(eg), supportsPlatform(pl), supportsToolset(ts) + { } + QString name; QStringList extraGenerators; bool supportsPlatform = true; @@ -92,11 +96,12 @@ public: QString mapAllPaths(const ProjectExplorer::Kit *kit, const QString &in) const; private: - Utils::SynchronousProcessResponse run(const QString &arg) const; + Utils::SynchronousProcessResponse run(const QStringList &args, bool mayFail = false) const; void parseFunctionDetailsOutput(const QString &output); QStringList parseVariableOutput(const QString &output); void fetchGeneratorsFromHelp() const; + void fetchGeneratorsFromCapabilities() const; Core::Id m_id; QString m_displayName; @@ -107,6 +112,7 @@ private: mutable bool m_didAttemptToRun = false; mutable bool m_didRun = false; + mutable bool m_hasServerMode = false; mutable QList m_generators; mutable QMap m_functionArgs;