diff --git a/src/plugins/cmakeprojectmanager/builddirreader.cpp b/src/plugins/cmakeprojectmanager/builddirreader.cpp index 6c71218ec7a..ca808d36fd0 100644 --- a/src/plugins/cmakeprojectmanager/builddirreader.cpp +++ b/src/plugins/cmakeprojectmanager/builddirreader.cpp @@ -44,11 +44,15 @@ std::unique_ptr BuildDirReader::createReader(const BuildDirParam { CMakeTool *cmake = p.cmakeTool(); QTC_ASSERT(p.isValid() && cmake, return {}); - if (cmake->hasFileApi()) + + switch (cmake->readerType()) { + case CMakeTool::FileApi: return std::make_unique(); - if (cmake->hasServerMode()) + case CMakeTool::ServerMode: return std::make_unique(); - return std::make_unique(); + default: + return std::make_unique(); + } } } // namespace Internal diff --git a/src/plugins/cmakeprojectmanager/cmaketool.cpp b/src/plugins/cmakeprojectmanager/cmaketool.cpp index 47da660ab2b..d42bf9abf25 100644 --- a/src/plugins/cmakeprojectmanager/cmaketool.cpp +++ b/src/plugins/cmakeprojectmanager/cmaketool.cpp @@ -48,7 +48,7 @@ const char CMAKE_INFORMATION_DISPLAYNAME[] = "DisplayName"; const char CMAKE_INFORMATION_AUTORUN[] = "AutoRun"; const char CMAKE_INFORMATION_AUTO_CREATE_BUILD_DIRECTORY[] = "AutoCreateBuildDirectory"; const char CMAKE_INFORMATION_AUTODETECTED[] = "AutoDetected"; - +const char CMAKE_INFORMATION_READERTYPE[] = "ReaderType"; bool CMakeTool::Generator::matches(const QString &n, const QString &ex) const { @@ -57,6 +57,40 @@ 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 readerTypeFromString(const QString &input) +{ + if (input == READER_TYPE_TEALEAF) + return CMakeTool::TeaLeaf; + if (input == READER_TYPE_SERVERMODE) + return CMakeTool::ServerMode; + if (input == READER_TYPE_FILEAPI) + return ignoreFileApi() ? CMakeTool::ServerMode : CMakeTool::FileApi; + return {}; +} + +static QString readerTypeToString(const CMakeTool::ReaderType &type) +{ + switch (type) { + case CMakeTool::TeaLeaf: + return READER_TYPE_TEALEAF; + case CMakeTool::ServerMode: + return READER_TYPE_SERVERMODE; + case CMakeTool::FileApi: + return READER_TYPE_FILEAPI; + } + return QString(); +} + // -------------------------------------------------------------------- // CMakeIntrospectionData: // -------------------------------------------------------------------- @@ -104,6 +138,8 @@ CMakeTool::CMakeTool(const QVariantMap &map, bool fromSdk) : m_displayName = map.value(CMAKE_INFORMATION_DISPLAYNAME).toString(); m_isAutoRun = map.value(CMAKE_INFORMATION_AUTORUN, true).toBool(); m_autoCreateBuildDirectory = map.value(CMAKE_INFORMATION_AUTO_CREATE_BUILD_DIRECTORY, false).toBool(); + m_readerType = Internal::readerTypeFromString( + map.value(CMAKE_INFORMATION_READERTYPE).toString()); //loading a CMakeTool from SDK is always autodetection if (!fromSdk) @@ -190,6 +226,9 @@ QVariantMap CMakeTool::toMap() const data.insert(CMAKE_INFORMATION_COMMAND, m_executable.toString()); data.insert(CMAKE_INFORMATION_AUTORUN, m_isAutoRun); data.insert(CMAKE_INFORMATION_AUTO_CREATE_BUILD_DIRECTORY, m_autoCreateBuildDirectory); + if (m_readerType.has_value()) + data.insert(CMAKE_INFORMATION_READERTYPE, + Internal::readerTypeToString(m_readerType.value())); data.insert(CMAKE_INFORMATION_AUTODETECTED, m_isAutoDetected); return data; } @@ -301,6 +340,22 @@ CMakeTool::PathMapper CMakeTool::pathMapper() const return [](const Utils::FilePath &fn) { return fn; }; } +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(); +} + void CMakeTool::readInformation(CMakeTool::QueryType type) const { if ((type == QueryType::GENERATORS && !m_introspection->m_generators.isEmpty()) @@ -343,10 +398,10 @@ static QStringList parseDefinition(const QString &definition) ignoreWord = true; } - if (c == ' ' || c == '[' || c == '<' || c == '(' - || c == ']' || c == '>' || c == ')') { + if (c == ' ' || c == '[' || c == '<' || c == '(' || c == ']' || c == '>' || c == ')') { if (!ignoreWord && !word.isEmpty()) { - if (result.isEmpty() || Utils::allOf(word, [](const QChar &c) { return c.isUpper() || c == '_'; })) + if (result.isEmpty() + || Utils::allOf(word, [](const QChar &c) { return c.isUpper() || c == '_'; })) result.append(word); } word.clear(); @@ -403,11 +458,12 @@ QStringList CMakeTool::parseVariableOutput(const QString &output) QStringList result; foreach (const QString &v, variableList) { if (v.startsWith("CMAKE_COMPILER_IS_GNU")) { // This key takes a compiler name :-/ - result << "CMAKE_COMPILER_IS_GNUCC" << "CMAKE_COMPILER_IS_GNUCXX"; + result << "CMAKE_COMPILER_IS_GNUCC" + << "CMAKE_COMPILER_IS_GNUCXX"; } else if (v.contains("")) { const QString tmp = QString(v).replace("", "%1"); - result << tmp.arg("DEBUG") << tmp.arg("RELEASE") - << tmp.arg("MINSIZEREL") << tmp.arg("RELWITHDEBINFO"); + result << tmp.arg("DEBUG") << tmp.arg("RELEASE") << tmp.arg("MINSIZEREL") + << tmp.arg("RELWITHDEBINFO"); } else if (v.contains("")) { const QString tmp = QString(v).replace("", "%1"); result << tmp.arg("C") << tmp.arg("CXX"); diff --git a/src/plugins/cmakeprojectmanager/cmaketool.h b/src/plugins/cmakeprojectmanager/cmaketool.h index 73044d8ba40..c8c29665c2f 100644 --- a/src/plugins/cmakeprojectmanager/cmaketool.h +++ b/src/plugins/cmakeprojectmanager/cmaketool.h @@ -31,6 +31,7 @@ #include #include +#include #include #include @@ -48,10 +49,9 @@ namespace Internal { class IntrospectionData; } class CMAKE_EXPORT CMakeTool { public: - enum Detection { - ManualDetection, - AutoDetection - }; + enum Detection { ManualDetection, AutoDetection }; + + enum ReaderType { TeaLeaf, ServerMode, FileApi }; struct Version { @@ -110,6 +110,8 @@ public: void setPathMapper(const PathMapper &includePathMapper); PathMapper pathMapper() const; + ReaderType readerType() const; + private: enum class QueryType { GENERATORS, @@ -137,6 +139,8 @@ private: bool m_isAutoDetected = false; bool m_autoCreateBuildDirectory = false; + Utils::optional m_readerType; + std::unique_ptr m_introspection; PathMapper m_pathMapper; diff --git a/src/plugins/cmakeprojectmanager/fileapireader.cpp b/src/plugins/cmakeprojectmanager/fileapireader.cpp index 957ebaaea0a..e98f2c9c118 100644 --- a/src/plugins/cmakeprojectmanager/fileapireader.cpp +++ b/src/plugins/cmakeprojectmanager/fileapireader.cpp @@ -107,7 +107,7 @@ void FileApiReader::setParameters(const BuildDirParameters &p) bool FileApiReader::isCompatible(const BuildDirParameters &p) { const CMakeTool *cmakeTool = p.cmakeTool(); - return cmakeTool && cmakeTool->hasFileApi(); + return cmakeTool && cmakeTool->readerType() == CMakeTool::FileApi; } void FileApiReader::resetData() diff --git a/src/plugins/cmakeprojectmanager/servermodereader.cpp b/src/plugins/cmakeprojectmanager/servermodereader.cpp index d4104dbe1df..77f2cd8cb4c 100644 --- a/src/plugins/cmakeprojectmanager/servermodereader.cpp +++ b/src/plugins/cmakeprojectmanager/servermodereader.cpp @@ -109,6 +109,9 @@ void ServerModeReader::setParameters(const BuildDirParameters &p) bool ServerModeReader::isCompatible(const BuildDirParameters &p) { CMakeTool *newCmake = p.cmakeTool(); + if (newCmake->readerType() != CMakeTool::FileApi) + return false; + CMakeTool *oldCmake = m_parameters.cmakeTool(); if (!newCmake || !oldCmake) return false; diff --git a/src/plugins/cmakeprojectmanager/tealeafreader.cpp b/src/plugins/cmakeprojectmanager/tealeafreader.cpp index 4e355a003c9..264f97daceb 100644 --- a/src/plugins/cmakeprojectmanager/tealeafreader.cpp +++ b/src/plugins/cmakeprojectmanager/tealeafreader.cpp @@ -135,9 +135,7 @@ void TeaLeafReader::setParameters(const BuildDirParameters &p) bool TeaLeafReader::isCompatible(const BuildDirParameters &p) { - if (!p.cmakeTool()) - return false; - return !p.cmakeTool()->hasServerMode(); + return p.cmakeTool() && p.cmakeTool()->readerType() == CMakeTool::TeaLeaf; } void TeaLeafReader::resetData()