forked from qt-creator/qt-creator
CMakePM: Presets: Add ability to register a Debugger via "vendor" field
This adds "Debugger" as a dependency for the CMake Project Manager. The "vendor" field of a configurePreset can look like: ``` "vendor": { "qt.io/QtCreator/1.0": { "debugger": "C:/Qt/Tools/mingw1120_64/bin/gdb.exe" } } } ``` or with all the DebugItem details as: ``` "vendor": { "qt.io/QtCreator/1.0": { "debugger": { "DisplayName": "GNU gdb 11.2.0 for MinGW 11.2.0 64-bit", "Abis": ["x86-windows-msys-pe-64bit"], "Binary": "C:/Qt/Tools/mingw1120_64/bin/gdb.exe", "EngineType": 1, "Version": "11.2.0" } } } ``` Fixes: QTCREATORBUG-30836 Change-Id: Ia89ff29ce5fad713ee8617477ec798bd86f2f811 Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
@@ -48,7 +48,6 @@ add_subdirectory(autotoolsprojectmanager)
|
|||||||
add_subdirectory(bazaar)
|
add_subdirectory(bazaar)
|
||||||
add_subdirectory(beautifier)
|
add_subdirectory(beautifier)
|
||||||
add_subdirectory(clearcase)
|
add_subdirectory(clearcase)
|
||||||
add_subdirectory(cmakeprojectmanager)
|
|
||||||
add_subdirectory(cvs)
|
add_subdirectory(cvs)
|
||||||
add_subdirectory(designer)
|
add_subdirectory(designer)
|
||||||
add_subdirectory(docker)
|
add_subdirectory(docker)
|
||||||
@@ -80,6 +79,7 @@ if (WITH_QMLDESIGNER)
|
|||||||
endif()
|
endif()
|
||||||
add_subdirectory(python)
|
add_subdirectory(python)
|
||||||
add_subdirectory(clangformat)
|
add_subdirectory(clangformat)
|
||||||
|
add_subdirectory(cmakeprojectmanager)
|
||||||
|
|
||||||
# Level 7:
|
# Level 7:
|
||||||
add_subdirectory(android)
|
add_subdirectory(android)
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
add_qtc_plugin(CMakeProjectManager
|
add_qtc_plugin(CMakeProjectManager
|
||||||
PLUGIN_CLASS CMakeProjectPlugin
|
PLUGIN_CLASS CMakeProjectPlugin
|
||||||
DEPENDS QmlJS
|
DEPENDS QmlJS
|
||||||
PLUGIN_DEPENDS Core CppEditor ProjectExplorer TextEditor QtSupport
|
PLUGIN_DEPENDS Core CppEditor Debugger ProjectExplorer TextEditor QtSupport
|
||||||
SYSTEM_INCLUDES 3dparty/cmake
|
SYSTEM_INCLUDES 3dparty/cmake
|
||||||
SOURCES
|
SOURCES
|
||||||
builddirparameters.cpp builddirparameters.h
|
builddirparameters.cpp builddirparameters.h
|
||||||
|
@@ -12,6 +12,9 @@
|
|||||||
#include "presetsmacros.h"
|
#include "presetsmacros.h"
|
||||||
|
|
||||||
#include <coreplugin/messagemanager.h>
|
#include <coreplugin/messagemanager.h>
|
||||||
|
#include <debugger/debuggeritem.h>
|
||||||
|
#include <debugger/debuggeritemmanager.h>
|
||||||
|
#include <debugger/debuggerkitaspect.h>
|
||||||
|
|
||||||
#include <projectexplorer/buildinfo.h>
|
#include <projectexplorer/buildinfo.h>
|
||||||
#include <projectexplorer/kitaspects.h>
|
#include <projectexplorer/kitaspects.h>
|
||||||
@@ -30,7 +33,9 @@
|
|||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
|
#include <QUuid>
|
||||||
|
|
||||||
|
using namespace Debugger;
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
using namespace QtSupport;
|
using namespace QtSupport;
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
@@ -60,6 +65,7 @@ struct DirectoryData
|
|||||||
FilePath sysroot;
|
FilePath sysroot;
|
||||||
QtProjectImporter::QtVersionData qt;
|
QtProjectImporter::QtVersionData qt;
|
||||||
QVector<ToolchainDescription> toolchains;
|
QVector<ToolchainDescription> toolchains;
|
||||||
|
QVariant debugger;
|
||||||
};
|
};
|
||||||
|
|
||||||
static FilePaths scanDirectory(const FilePath &path, const QString &prefix)
|
static FilePaths scanDirectory(const FilePath &path, const QString &prefix)
|
||||||
@@ -205,6 +211,48 @@ FilePaths CMakeProjectImporter::presetCandidates()
|
|||||||
return candidates;
|
return candidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static QVariant findOrRegisterDebugger(
|
||||||
|
Environment &env, const std::optional<QVariantMap> &vendor, const QString &presetName)
|
||||||
|
{
|
||||||
|
const QString debuggerKey("debugger");
|
||||||
|
if (!vendor || !vendor.value().contains(debuggerKey))
|
||||||
|
return {};
|
||||||
|
|
||||||
|
const QVariant debuggerVariant = vendor.value().value(debuggerKey);
|
||||||
|
FilePath debuggerPath = FilePath::fromUserInput(debuggerVariant.toString());
|
||||||
|
if (!debuggerPath.isEmpty()) {
|
||||||
|
if (debuggerPath.isRelativePath())
|
||||||
|
debuggerPath = env.searchInPath(debuggerPath.fileName());
|
||||||
|
|
||||||
|
const QString mainName = Tr::tr("CMake Preset (%1) %2 Debugger");
|
||||||
|
DebuggerItem debugger;
|
||||||
|
debugger.setCommand(debuggerPath);
|
||||||
|
debugger.setUnexpandedDisplayName(
|
||||||
|
mainName.arg(presetName).arg(debuggerPath.completeBaseName()));
|
||||||
|
debugger.setAutoDetected(false);
|
||||||
|
QString errorMessage;
|
||||||
|
debugger.reinitializeFromFile(&errorMessage, &env);
|
||||||
|
if (!errorMessage.isEmpty())
|
||||||
|
qCWarning(cmInputLog()) << "Error reinitializing debugger" << debuggerPath.toString()
|
||||||
|
<< "Error:" << errorMessage;
|
||||||
|
|
||||||
|
return DebuggerItemManager::registerDebugger(debugger);
|
||||||
|
} else {
|
||||||
|
auto debuggerMap = debuggerVariant.toMap();
|
||||||
|
if (debuggerMap.isEmpty())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
// Manually create an Id, otrhewise the Kit will not have a debugger set
|
||||||
|
if (!debuggerMap.contains("Id"))
|
||||||
|
debuggerMap.insert("Id", QUuid::createUuid().toString());
|
||||||
|
|
||||||
|
auto store = storeFromMap(debuggerMap);
|
||||||
|
DebuggerItem debugger(store);
|
||||||
|
|
||||||
|
return DebuggerItemManager::registerDebugger(debugger);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Target *CMakeProjectImporter::preferredTarget(const QList<Target *> &possibleTargets)
|
Target *CMakeProjectImporter::preferredTarget(const QList<Target *> &possibleTargets)
|
||||||
{
|
{
|
||||||
for (Kit *kit : m_project->oldPresetKits()) {
|
for (Kit *kit : m_project->oldPresetKits()) {
|
||||||
@@ -835,6 +883,8 @@ QList<void *> CMakeProjectImporter::examineDirectory(const FilePath &importPath,
|
|||||||
|
|
||||||
data->hasQmlDebugging = CMakeBuildConfiguration::hasQmlDebugging(config);
|
data->hasQmlDebugging = CMakeBuildConfiguration::hasQmlDebugging(config);
|
||||||
|
|
||||||
|
data->debugger = findOrRegisterDebugger(env, configurePreset.vendor, configurePreset.name);
|
||||||
|
|
||||||
QByteArrayList buildConfigurationTypes = {cache.valueOf("CMAKE_BUILD_TYPE")};
|
QByteArrayList buildConfigurationTypes = {cache.valueOf("CMAKE_BUILD_TYPE")};
|
||||||
if (buildConfigurationTypes.front().isEmpty()) {
|
if (buildConfigurationTypes.front().isEmpty()) {
|
||||||
buildConfigurationTypes.clear();
|
buildConfigurationTypes.clear();
|
||||||
@@ -1055,6 +1105,9 @@ Kit *CMakeProjectImporter::createKit(void *directoryData) const
|
|||||||
if (!data->cmakePreset.isEmpty())
|
if (!data->cmakePreset.isEmpty())
|
||||||
ensureBuildDirectory(*data, k);
|
ensureBuildDirectory(*data, k);
|
||||||
|
|
||||||
|
if (data->debugger.isValid())
|
||||||
|
DebuggerKitAspect::setDebugger(k, data->debugger);
|
||||||
|
|
||||||
qCInfo(cmInputLog) << "Temporary Kit created.";
|
qCInfo(cmInputLog) << "Temporary Kit created.";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -8,6 +8,7 @@ QtcPlugin {
|
|||||||
|
|
||||||
Depends { name: "Core" }
|
Depends { name: "Core" }
|
||||||
Depends { name: "CppEditor" }
|
Depends { name: "CppEditor" }
|
||||||
|
Depends { name: "Debugger" }
|
||||||
Depends { name: "QmlJS" }
|
Depends { name: "QmlJS" }
|
||||||
Depends { name: "ProjectExplorer" }
|
Depends { name: "ProjectExplorer" }
|
||||||
Depends { name: "TextEditor" }
|
Depends { name: "TextEditor" }
|
||||||
|
@@ -148,6 +148,30 @@ std::optional<PresetsDetails::Condition> parseCondition(const QJsonValue &jsonVa
|
|||||||
return condition;
|
return condition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool parseVendor(const QJsonValue &jsonValue, std::optional<QVariantMap> &vendorSettings)
|
||||||
|
{
|
||||||
|
// The whole section is optional
|
||||||
|
if (jsonValue.isUndefined())
|
||||||
|
return true;
|
||||||
|
if (!jsonValue.isObject())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const QJsonObject object = jsonValue.toObject();
|
||||||
|
const QJsonValue qtIo = object.value("qt.io/QtCreator/1.0");
|
||||||
|
if (qtIo.isUndefined())
|
||||||
|
return true;
|
||||||
|
if (!qtIo.isObject())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const QJsonObject qtIoObject = qtIo.toObject();
|
||||||
|
vendorSettings = QVariantMap();
|
||||||
|
for (const QString &settingKey : qtIoObject.keys()) {
|
||||||
|
const QJsonValue settingValue = qtIoObject.value(settingKey);
|
||||||
|
vendorSettings->insert(settingKey, settingValue.toVariant());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool parseConfigurePresets(const QJsonValue &jsonValue,
|
bool parseConfigurePresets(const QJsonValue &jsonValue,
|
||||||
QList<PresetsDetails::ConfigurePreset> &configurePresets,
|
QList<PresetsDetails::ConfigurePreset> &configurePresets,
|
||||||
const Utils::FilePath &fileDir)
|
const Utils::FilePath &fileDir)
|
||||||
@@ -188,6 +212,9 @@ bool parseConfigurePresets(const QJsonValue &jsonValue,
|
|||||||
if (object.contains("condition"))
|
if (object.contains("condition"))
|
||||||
preset.condition = parseCondition(object.value("condition"));
|
preset.condition = parseCondition(object.value("condition"));
|
||||||
|
|
||||||
|
if (object.contains("vendor"))
|
||||||
|
parseVendor(object.value("vendor"), preset.vendor);
|
||||||
|
|
||||||
if (object.contains("displayName"))
|
if (object.contains("displayName"))
|
||||||
preset.displayName = object.value("displayName").toString();
|
preset.displayName = object.value("displayName").toString();
|
||||||
if (object.contains("description"))
|
if (object.contains("description"))
|
||||||
@@ -378,6 +405,9 @@ bool parseBuildPresets(const QJsonValue &jsonValue,
|
|||||||
if (object.contains("condition"))
|
if (object.contains("condition"))
|
||||||
preset.condition = parseCondition(object.value("condition"));
|
preset.condition = parseCondition(object.value("condition"));
|
||||||
|
|
||||||
|
if (object.contains("vendor"))
|
||||||
|
parseVendor(object.value("vendor"), preset.vendor);
|
||||||
|
|
||||||
if (object.contains("displayName"))
|
if (object.contains("displayName"))
|
||||||
preset.displayName = object.value("displayName").toString();
|
preset.displayName = object.value("displayName").toString();
|
||||||
if (object.contains("description"))
|
if (object.contains("description"))
|
||||||
@@ -435,30 +465,6 @@ bool parseBuildPresets(const QJsonValue &jsonValue,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parseVendor(const QJsonValue &jsonValue, std::optional<QVariantMap> &vendorSettings)
|
|
||||||
{
|
|
||||||
// The whole section is optional
|
|
||||||
if (jsonValue.isUndefined())
|
|
||||||
return true;
|
|
||||||
if (!jsonValue.isObject())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const QJsonObject object = jsonValue.toObject();
|
|
||||||
const QJsonValue qtIo = object.value("qt.io/QtCreator/1.0");
|
|
||||||
if (qtIo.isUndefined())
|
|
||||||
return true;
|
|
||||||
if (!qtIo.isObject())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const QJsonObject qtIoObject = qtIo.toObject();
|
|
||||||
vendorSettings = QVariantMap();
|
|
||||||
for (const QString &settingKey : qtIoObject.keys()) {
|
|
||||||
const QJsonValue settingValue = qtIoObject.value(settingKey);
|
|
||||||
vendorSettings->insert(settingKey, settingValue.toVariant());
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const PresetsData &PresetsParser::presetsData() const
|
const PresetsData &PresetsParser::presetsData() const
|
||||||
{
|
{
|
||||||
return m_presetsData;
|
return m_presetsData;
|
||||||
@@ -535,10 +541,9 @@ bool PresetsParser::parse(const Utils::FilePath &jsonFile, QString &errorMessage
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QHash<QString, QString> merge(const QHash<QString, QString> &first,
|
static QVariantMap merge(const QVariantMap &first, const QVariantMap &second)
|
||||||
const QHash<QString, QString> &second)
|
|
||||||
{
|
{
|
||||||
QHash<QString, QString> result = first;
|
QVariantMap result = first;
|
||||||
for (auto it = second.constKeyValueBegin(); it != second.constKeyValueEnd(); ++it) {
|
for (auto it = second.constKeyValueBegin(); it != second.constKeyValueEnd(); ++it) {
|
||||||
result[it->first] = it->second;
|
result[it->first] = it->second;
|
||||||
}
|
}
|
||||||
|
@@ -94,7 +94,7 @@ public:
|
|||||||
std::optional<bool> hidden = false;
|
std::optional<bool> hidden = false;
|
||||||
std::optional<QStringList> inherits;
|
std::optional<QStringList> inherits;
|
||||||
std::optional<Condition> condition;
|
std::optional<Condition> condition;
|
||||||
std::optional<QHash<QString, QString>> vendor;
|
std::optional<QVariantMap> vendor;
|
||||||
std::optional<QString> displayName;
|
std::optional<QString> displayName;
|
||||||
std::optional<QString> description;
|
std::optional<QString> description;
|
||||||
std::optional<QString> generator;
|
std::optional<QString> generator;
|
||||||
@@ -120,7 +120,7 @@ public:
|
|||||||
std::optional<bool> hidden = false;
|
std::optional<bool> hidden = false;
|
||||||
std::optional<QStringList> inherits;
|
std::optional<QStringList> inherits;
|
||||||
std::optional<Condition> condition;
|
std::optional<Condition> condition;
|
||||||
std::optional<QHash<QString, QString>> vendor;
|
std::optional<QVariantMap> vendor;
|
||||||
std::optional<QString> displayName;
|
std::optional<QString> displayName;
|
||||||
std::optional<QString> description;
|
std::optional<QString> description;
|
||||||
std::optional<Utils::Environment> environment;
|
std::optional<Utils::Environment> environment;
|
||||||
|
Reference in New Issue
Block a user