forked from qt-creator/qt-creator
CMake: Add an option to override cmake reader type
Add an option to override the cmake reader type that is going to be used. By default the reader type is "auto" for autodetection, but that can get changed in the cmaketools.xml settings file. Other supported options are "tealeaf", "servermode" or "fileapi" and that will force that reader. You can also set QTC_CMAKE_IGNORE_FILEAPI=1 in your environment to force creator to ignore the existence of fileapi support in all cmake tools. Change-Id: I2006616312090ce2909154dc1966f7a8eaa2949a Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
@@ -44,11 +44,15 @@ std::unique_ptr<BuildDirReader> 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<FileApiReader>();
|
||||
if (cmake->hasServerMode())
|
||||
case CMakeTool::ServerMode:
|
||||
return std::make_unique<ServerModeReader>();
|
||||
return std::make_unique<TeaLeafReader>();
|
||||
default:
|
||||
return std::make_unique<TeaLeafReader>();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
@@ -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<CMakeTool::ReaderType> 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<LANG>")) { // 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("<CONFIG>")) {
|
||||
const QString tmp = QString(v).replace("<CONFIG>", "%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("<LANG>")) {
|
||||
const QString tmp = QString(v).replace("<LANG>", "%1");
|
||||
result << tmp.arg("C") << tmp.arg("CXX");
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#include <texteditor/codeassist/keywordscompletionassist.h>
|
||||
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/optional.h>
|
||||
#include <utils/synchronousprocess.h>
|
||||
|
||||
#include <QObject>
|
||||
@@ -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<ReaderType> m_readerType;
|
||||
|
||||
std::unique_ptr<Internal::IntrospectionData> m_introspection;
|
||||
|
||||
PathMapper m_pathMapper;
|
||||
|
@@ -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()
|
||||
|
@@ -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;
|
||||
|
@@ -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()
|
||||
|
Reference in New Issue
Block a user