diff options
Diffstat (limited to 'src/plugins/cmakeprojectmanager/cmaketool.cpp')
-rw-r--r-- | src/plugins/cmakeprojectmanager/cmaketool.cpp | 207 |
1 files changed, 40 insertions, 167 deletions
diff --git a/src/plugins/cmakeprojectmanager/cmaketool.cpp b/src/plugins/cmakeprojectmanager/cmaketool.cpp index 52f6f67893..90bc67fc26 100644 --- a/src/plugins/cmakeprojectmanager/cmaketool.cpp +++ b/src/plugins/cmakeprojectmanager/cmaketool.cpp @@ -24,23 +24,21 @@ ****************************************************************************/ #include "cmaketool.h" + #include "cmaketoolmanager.h" #include <utils/algorithm.h> #include <utils/environment.h> -#include <utils/hostosinfo.h> #include <utils/qtcassert.h> #include <QDir> -#include <QFileInfo> #include <QJsonDocument> #include <QJsonObject> -#include <QProcess> #include <QRegularExpression> #include <QSet> -#include <QTextDocument> #include <QUuid> -#include <QVariantMap> + +#include <memory> namespace CMakeProjectManager { @@ -60,38 +58,24 @@ bool CMakeTool::Generator::matches(const QString &n, const QString &ex) const namespace Internal { -const char READER_TYPE_TEALEAF[] = "tealeaf"; -const char READER_TYPE_SERVERMODE[] = "servermode"; const char READER_TYPE_FILEAPI[] = "fileapi"; -static bool ignoreFileApi() -{ - static bool s_ignoreFileApi = qEnvironmentVariableIsSet("QTC_CMAKE_IGNORE_FILEAPI"); - return s_ignoreFileApi; -} - static Utils::optional<CMakeTool::ReaderType> readerTypeFromString(const QString &input) { - if (input == READER_TYPE_TEALEAF) - return CMakeTool::TeaLeaf; - if (input == READER_TYPE_SERVERMODE) - return CMakeTool::ServerMode; + // Do not try to be clever here, just use whatever is in the string! if (input == READER_TYPE_FILEAPI) - return ignoreFileApi() ? CMakeTool::ServerMode : CMakeTool::FileApi; + return CMakeTool::FileApi; return {}; } static QString readerTypeToString(const CMakeTool::ReaderType &type) { switch (type) { - case CMakeTool::TeaLeaf: - return QString(READER_TYPE_TEALEAF); - case CMakeTool::ServerMode: - return QString(READER_TYPE_SERVERMODE); case CMakeTool::FileApi: return QString(READER_TYPE_FILEAPI); + default: + return QString(); } - return QString(); } // -------------------------------------------------------------------- @@ -109,9 +93,7 @@ class IntrospectionData public: bool m_didAttemptToRun = false; bool m_didRun = true; - bool m_hasServerMode = false; - bool m_queriedServerMode = false; bool m_triedCapabilities = false; QList<CMakeTool::Generator> m_generators; @@ -127,9 +109,10 @@ public: /////////////////////////// // CMakeTool /////////////////////////// -CMakeTool::CMakeTool(Detection d, const Core::Id &id) : - m_id(id), m_isAutoDetected(d == AutoDetection), - m_introspection(std::make_unique<Internal::IntrospectionData>()) +CMakeTool::CMakeTool(Detection d, const Core::Id &id) + : m_id(id) + , m_isAutoDetected(d == AutoDetection) + , m_introspection(std::make_unique<Internal::IntrospectionData>()) { QTC_ASSERT(m_id.isValid(), m_id = Core::Id::fromString(QUuid::createUuid().toString())); } @@ -199,13 +182,13 @@ void CMakeTool::setAutoCreateBuildDirectory(bool autoBuildDir) bool CMakeTool::isValid() const { - if (!m_id.isValid()) + if (!m_id.isValid() || !m_introspection) return false; if (!m_introspection->m_didAttemptToRun) - supportedGenerators(); + readInformation(); - return m_introspection->m_didRun; + return m_introspection->m_didRun && !m_introspection->m_fileApis.isEmpty(); } Utils::SynchronousProcessResponse CMakeTool::run(const QStringList &args, int timeoutS) const @@ -230,7 +213,7 @@ QVariantMap CMakeTool::toMap() const data.insert(CMAKE_INFORMATION_QCH_FILE_PATH, m_qchFilePath.toString()); data.insert(CMAKE_INFORMATION_AUTORUN, m_isAutoRun); data.insert(CMAKE_INFORMATION_AUTO_CREATE_BUILD_DIRECTORY, m_autoCreateBuildDirectory); - if (m_readerType.has_value()) + if (m_readerType) data.insert(CMAKE_INFORMATION_READERTYPE, Internal::readerTypeToString(m_readerType.value())); data.insert(CMAKE_INFORMATION_AUTODETECTED, m_isAutoDetected); @@ -290,12 +273,14 @@ bool CMakeTool::autoCreateBuildDirectory() const QList<CMakeTool::Generator> CMakeTool::supportedGenerators() const { - readInformation(QueryType::GENERATORS); - return m_introspection->m_generators; + return isValid() ? m_introspection->m_generators : QList<CMakeTool::Generator>(); } TextEditor::Keywords CMakeTool::keywords() { + if (!isValid()) + return {}; + if (m_introspection->m_functions.isEmpty() && m_introspection->m_didRun) { Utils::SynchronousProcessResponse response; response = run({"--help-command-list"}, 5); @@ -323,28 +308,19 @@ TextEditor::Keywords CMakeTool::keywords() m_introspection->m_functionArgs); } -bool CMakeTool::hasServerMode() const -{ - readInformation(QueryType::SERVER_MODE); - return m_introspection->m_hasServerMode; -} - bool CMakeTool::hasFileApi() const { - readInformation(QueryType::SERVER_MODE); - return !m_introspection->m_fileApis.isEmpty(); + return isValid() ? !m_introspection->m_fileApis.isEmpty() : false; } -QVector<std::pair<QString, int> > CMakeTool::supportedFileApiObjects() const +QVector<std::pair<QString, int>> CMakeTool::supportedFileApiObjects() const { - readInformation(QueryType::SERVER_MODE); - return Utils::transform(m_introspection->m_fileApis, [](const Internal::FileApi &api) { return std::make_pair(api.kind, api.version.first); }); + return isValid() ? Utils::transform(m_introspection->m_fileApis, [](const Internal::FileApi &api) { return std::make_pair(api.kind, api.version.first); }) : QVector<std::pair<QString, int>>(); } CMakeTool::Version CMakeTool::version() const { - readInformation(QueryType::VERSION); - return m_introspection->m_version; + return isValid() ? m_introspection->m_version : CMakeTool::Version(); } bool CMakeTool::isAutoDetected() const @@ -375,20 +351,15 @@ CMakeTool::PathMapper CMakeTool::pathMapper() const return [](const Utils::FilePath &fn) { return fn; }; } -CMakeTool::ReaderType CMakeTool::readerType() const +Utils::optional<CMakeTool::ReaderType> CMakeTool::readerType() const { - if (!m_readerType.has_value()) { - // Find best possible reader type: - if (hasFileApi()) { - if (hasServerMode() && Internal::ignoreFileApi()) - return ServerMode; // We were asked to fall back to server mode - return FileApi; - } - if (hasServerMode()) - return ServerMode; - return TeaLeaf; - } - return m_readerType.value(); + if (m_readerType) + return m_readerType; // Allow overriding the auto-detected value via .user files + + // Find best possible reader type: + if (hasFileApi()) + return FileApi; + return {}; } Utils::FilePath CMakeTool::searchQchFile(const Utils::FilePath &executable) @@ -413,33 +384,16 @@ Utils::FilePath CMakeTool::searchQchFile(const Utils::FilePath &executable) return {}; } -void CMakeTool::readInformation(CMakeTool::QueryType type) const +void CMakeTool::readInformation() const { + QTC_ASSERT(m_introspection, return ); if (!m_introspection->m_didRun && m_introspection->m_didAttemptToRun) return; m_introspection->m_didAttemptToRun = true; - if (!m_introspection->m_triedCapabilities) { - fetchFromCapabilities(); - m_introspection->m_triedCapabilities = true; - m_introspection->m_queriedServerMode = true; // Got added after "-E capabilities" support! - } else { - if ((type == QueryType::GENERATORS && !m_introspection->m_generators.isEmpty()) - || (type == QueryType::SERVER_MODE && m_introspection->m_queriedServerMode) - || (type == QueryType::VERSION && !m_introspection->m_version.fullVersion.isEmpty())) - return; - - if (type == QueryType::GENERATORS) { - fetchGeneratorsFromHelp(); - } else if (type == QueryType::SERVER_MODE) { - // Nothing to do... - } else if (type == QueryType::VERSION) { - fetchVersionFromVersionOutput(); - } else { - QTC_ASSERT(false, return ); - } - } + fetchFromCapabilities(); + m_introspection->m_triedCapabilities = true; } static QStringList parseDefinition(const QString &definition) @@ -533,96 +487,16 @@ QStringList CMakeTool::parseVariableOutput(const QString &output) return result; } -void CMakeTool::fetchGeneratorsFromHelp() const -{ - Utils::SynchronousProcessResponse response = run({"--help"}); - m_introspection->m_didRun = m_introspection->m_didRun - && response.result == Utils::SynchronousProcessResponse::Finished; - - if (response.result == Utils::SynchronousProcessResponse::Finished) - parseGeneratorsFromHelp(response.stdOut().split('\n')); -} - -void CMakeTool::parseGeneratorsFromHelp(const QStringList &lines) const -{ - bool inGeneratorSection = false; - QHash<QString, QStringList> generatorInfo; - foreach (const QString &line, lines) { - if (line.isEmpty()) - continue; - if (line == "Generators") { - inGeneratorSection = true; - continue; - } - if (!inGeneratorSection) - continue; - - if (line.startsWith(" ") && line.at(3) != ' ') { - int pos = line.indexOf('='); - if (pos < 0) - pos = line.length(); - if (pos >= 0) { - --pos; - while (pos > 2 && line.at(pos).isSpace()) - --pos; - } - if (pos > 2) { - const QString fullName = line.mid(2, pos - 1); - const int dashPos = fullName.indexOf(" - "); - QString generator; - QString extra; - if (dashPos < 0) { - generator = fullName; - } else { - extra = fullName.mid(0, dashPos); - generator = fullName.mid(dashPos + 3); - } - QStringList value = generatorInfo.value(generator); - if (!extra.isEmpty()) - value.append(extra); - generatorInfo.insert(generator, value); - } - } - } - - // Populate genertor list: - for (auto it = generatorInfo.constBegin(); it != generatorInfo.constEnd(); ++it) - m_introspection->m_generators.append(Generator(it.key(), it.value())); -} - -void CMakeTool::fetchVersionFromVersionOutput() const -{ - Utils::SynchronousProcessResponse response = run({"--version"}); - - m_introspection->m_didRun = m_introspection->m_didRun - && response.result == Utils::SynchronousProcessResponse::Finished; - - if (response.result == Utils::SynchronousProcessResponse::Finished) - parseVersionFormVersionOutput(response.stdOut().split('\n')); -} - -void CMakeTool::parseVersionFormVersionOutput(const QStringList &lines) const -{ - QRegularExpression versionLine("^cmake.* version ((\\d+).(\\d+).(\\d+).*)$"); - for (const QString &line : lines) { - QRegularExpressionMatch match = versionLine.match(line); - if (!match.hasMatch()) - continue; - - m_introspection->m_version.major = match.captured(2).toInt(); - m_introspection->m_version.minor = match.captured(3).toInt(); - m_introspection->m_version.patch = match.captured(4).toInt(); - m_introspection->m_version.fullVersion = match.captured(1).toUtf8(); - break; - } -} - void CMakeTool::fetchFromCapabilities() const { Utils::SynchronousProcessResponse response = run({"-E", "capabilities"}); - if (response.result == Utils::SynchronousProcessResponse::Finished) + if (response.result == Utils::SynchronousProcessResponse::Finished) { + m_introspection->m_didRun = true; parseFromCapabilities(response.stdOut()); + } else { + m_introspection->m_didRun = false; + } } static int getVersion(const QVariantMap &obj, const QString value) @@ -641,7 +515,6 @@ void CMakeTool::parseFromCapabilities(const QString &input) const return; const QVariantMap data = doc.object().toVariantMap(); - m_introspection->m_hasServerMode = data.value("serverMode").toBool(); const QVariantList generatorList = data.value("generators").toList(); for (const QVariant &v : generatorList) { const QVariantMap gen = v.toMap(); |