forked from qt-creator/qt-creator
Debugger: Rework detection of SDK-specified "auto" debuggers
Change-Id: I173752a41da7b34d64cb7e3e423992be464fc73b Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com> Reviewed-by: Tobias Hunger <tobias.hunger@digia.com>
This commit is contained in:
@@ -86,20 +86,104 @@ DebuggerKitInformation::DebuggerKitInformation()
|
|||||||
|
|
||||||
QVariant DebuggerKitInformation::defaultValue(Kit *k) const
|
QVariant DebuggerKitInformation::defaultValue(Kit *k) const
|
||||||
{
|
{
|
||||||
// This is only called from Kit::Kit()
|
|
||||||
// if (isValidDebugger(k)) {
|
|
||||||
// DebuggerItem *item = DebuggerItemManager::debuggerFromKit(k);
|
|
||||||
// QTC_ASSERT(item, return QVariant());
|
|
||||||
// return item->id;
|
|
||||||
// }
|
|
||||||
|
|
||||||
ToolChain *tc = ToolChainKitInformation::toolChain(k);
|
ToolChain *tc = ToolChainKitInformation::toolChain(k);
|
||||||
return DebuggerItemManager::defaultDebugger(tc);
|
QTC_ASSERT(tc, return QVariant());
|
||||||
|
|
||||||
|
const Abi toolChainAbi = tc->targetAbi();
|
||||||
|
foreach (const DebuggerItem &item, DebuggerItemManager::debuggers())
|
||||||
|
foreach (const Abi targetAbi, item.abis())
|
||||||
|
if (targetAbi.isCompatibleWith(toolChainAbi))
|
||||||
|
return item.id();
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerKitInformation::setup(Kit *k)
|
void DebuggerKitInformation::setup(Kit *k)
|
||||||
{
|
{
|
||||||
k->setValue(DebuggerKitInformation::id(), defaultValue(k));
|
// Get one of the available debugger matching the kit's toolchain.
|
||||||
|
const ToolChain *tc = ToolChainKitInformation::toolChain(k);
|
||||||
|
const Abi toolChainAbi = tc ? tc->targetAbi() : Abi::hostAbi();
|
||||||
|
|
||||||
|
// This can be anything (Id, binary path, "auto")
|
||||||
|
const QVariant rawId = k->value(DebuggerKitInformation::id());
|
||||||
|
|
||||||
|
enum {
|
||||||
|
NotDetected, DetectedAutomatically, DetectedByFile, DetectedById
|
||||||
|
} detection = NotDetected;
|
||||||
|
DebuggerEngineType autoEngine = NoEngineType;
|
||||||
|
FileName fileName;
|
||||||
|
|
||||||
|
// With 3.0 we have:
|
||||||
|
// <value type="QString" key="Debugger.Information">{75ecf347-f221-44c3-b613-ea1d29929cd4}</value>
|
||||||
|
// Before we had:
|
||||||
|
// <valuemap type="QVariantMap" key="Debugger.Information">
|
||||||
|
// <value type="QString" key="Binary">/data/dev/debugger/gdb-git/gdb/gdb</value>
|
||||||
|
// <value type="int" key="EngineType">1</value>
|
||||||
|
// </valuemap>
|
||||||
|
// Or for force auto-detected CDB
|
||||||
|
// <valuemap type="QVariantMap" key="Debugger.Information">
|
||||||
|
// <value type="QString" key="Binary">auto</value>
|
||||||
|
// <value type="int" key="EngineType">4</value>
|
||||||
|
// </valuemap>
|
||||||
|
|
||||||
|
if (rawId.type() == QVariant::String) {
|
||||||
|
detection = DetectedById;
|
||||||
|
} else {
|
||||||
|
QMap<QString, QVariant> map = rawId.toMap();
|
||||||
|
QString binary = map.value(QLatin1String("Binary")).toString();
|
||||||
|
if (binary == QLatin1String("auto")) {
|
||||||
|
detection = DetectedAutomatically;
|
||||||
|
autoEngine = DebuggerEngineType(map.value(QLatin1String("EngineType")).toInt());
|
||||||
|
} else {
|
||||||
|
detection = DetectedByFile;
|
||||||
|
fileName = FileName::fromUserInput(binary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QTC_CHECK(detection != NotDetected);
|
||||||
|
|
||||||
|
const DebuggerItem *bestItem = 0;
|
||||||
|
DebuggerItem::MatchLevel bestLevel = DebuggerItem::DoesNotMatch;
|
||||||
|
foreach (const DebuggerItem &item, DebuggerItemManager::debuggers()) {
|
||||||
|
const DebuggerItem *goodItem = 0;
|
||||||
|
if (detection == DetectedById && item.id() == rawId)
|
||||||
|
goodItem = &item;
|
||||||
|
if (detection == DetectedByFile && item.command() == fileName)
|
||||||
|
goodItem = &item;
|
||||||
|
if (detection == DetectedAutomatically && item.engineType() == autoEngine)
|
||||||
|
goodItem = &item;
|
||||||
|
|
||||||
|
if (goodItem) {
|
||||||
|
DebuggerItem::MatchLevel level = goodItem->matchTarget(toolChainAbi);
|
||||||
|
if (level > bestLevel) {
|
||||||
|
bestLevel = level;
|
||||||
|
bestItem = goodItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have an existing debugger with matching id _and_
|
||||||
|
// matching target ABI we are fine.
|
||||||
|
if (bestItem) {
|
||||||
|
k->setValue(DebuggerKitInformation::id(), bestItem->id());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We didn't find an existing debugger that matched by whatever
|
||||||
|
// data we found in the kit (i.e. no id, filename, "auto")
|
||||||
|
// (or what we found did not match ABI-wise)
|
||||||
|
// Let's try to pick one with matching ABI.
|
||||||
|
QVariant bestId;
|
||||||
|
bestLevel = DebuggerItem::DoesNotMatch;
|
||||||
|
foreach (const DebuggerItem &item, DebuggerItemManager::debuggers()) {
|
||||||
|
DebuggerItem::MatchLevel level = item.matchTarget(toolChainAbi);
|
||||||
|
if (level > bestLevel) {
|
||||||
|
bestLevel = level;
|
||||||
|
bestId = item.id();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
k->setValue(DebuggerKitInformation::id(), bestId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the configuration errors and return a flag mask. Provide a quick check and
|
// Check the configuration errors and return a flag mask. Provide a quick check and
|
||||||
@@ -145,57 +229,9 @@ static unsigned debuggerConfigurationErrors(const Kit *k)
|
|||||||
|
|
||||||
const DebuggerItem *DebuggerKitInformation::debugger(const Kit *kit)
|
const DebuggerItem *DebuggerKitInformation::debugger(const Kit *kit)
|
||||||
{
|
{
|
||||||
if (!kit)
|
QTC_ASSERT(kit, return 0);
|
||||||
return 0;
|
|
||||||
|
|
||||||
const QVariant id = kit->value(DebuggerKitInformation::id());
|
const QVariant id = kit->value(DebuggerKitInformation::id());
|
||||||
|
return DebuggerItemManager::findById(id);
|
||||||
enum Detection { NotDetected, DetectedAutomatically, DetectedByFile, DetectedById };
|
|
||||||
Detection detection = NotDetected;
|
|
||||||
|
|
||||||
DebuggerEngineType autoEngine = NoEngineType;
|
|
||||||
|
|
||||||
FileName fileName;
|
|
||||||
|
|
||||||
// With 3.0 we have:
|
|
||||||
// <value type="QString" key="Debugger.Information">{75ecf347-f221-44c3-b613-ea1d29929cd4}</value>
|
|
||||||
// Before we had:
|
|
||||||
// <valuemap type="QVariantMap" key="Debugger.Information">
|
|
||||||
// <value type="QString" key="Binary">/data/dev/debugger/gdb-git/gdb/gdb</value>
|
|
||||||
// <value type="int" key="EngineType">1</value>
|
|
||||||
// </valuemap>
|
|
||||||
// Or for force auto-detected CDB
|
|
||||||
// <valuemap type="QVariantMap" key="Debugger.Information">
|
|
||||||
// <value type="QString" key="Binary">auto</value>
|
|
||||||
// <value type="int" key="EngineType">4</value>
|
|
||||||
// </valuemap>
|
|
||||||
|
|
||||||
if (id.type() == QVariant::String) {
|
|
||||||
detection = DetectedById;
|
|
||||||
} else {
|
|
||||||
QMap<QString, QVariant> map = id.toMap();
|
|
||||||
QString binary = map.value(QLatin1String("Binary")).toString();
|
|
||||||
if (binary == QLatin1String("auto")) {
|
|
||||||
detection = DetectedAutomatically;
|
|
||||||
autoEngine = DebuggerEngineType(map.value(QLatin1String("EngineType")).toInt());
|
|
||||||
} else {
|
|
||||||
detection = DetectedByFile;
|
|
||||||
fileName = FileName::fromUserInput(binary);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QTC_CHECK(detection != NotDetected);
|
|
||||||
|
|
||||||
foreach (const DebuggerItem &item, DebuggerItemManager::debuggers()) {
|
|
||||||
if (detection == DetectedById && item.id() == id)
|
|
||||||
return &item;
|
|
||||||
if (detection == DetectedByFile && item.command() == fileName)
|
|
||||||
return &item;
|
|
||||||
if (detection == DetectedAutomatically && item.engineType() == autoEngine)
|
|
||||||
return &item;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DebuggerKitInformation::isValidDebugger(const Kit *k)
|
bool DebuggerKitInformation::isValidDebugger(const Kit *k)
|
||||||
@@ -297,32 +333,39 @@ static FileName userSettingsFileName()
|
|||||||
return FileName::fromString(settingsLocation.absolutePath() + QLatin1String(DEBUGGER_FILENAME));
|
return FileName::fromString(settingsLocation.absolutePath() + QLatin1String(DEBUGGER_FILENAME));
|
||||||
}
|
}
|
||||||
|
|
||||||
static QList<DebuggerItem> readDebuggers(const FileName &fileName)
|
static void readDebuggers(const FileName &fileName, bool isSystem)
|
||||||
{
|
{
|
||||||
QList<DebuggerItem> result;
|
|
||||||
|
|
||||||
PersistentSettingsReader reader;
|
PersistentSettingsReader reader;
|
||||||
if (!reader.load(fileName))
|
if (!reader.load(fileName))
|
||||||
return result;
|
return;
|
||||||
QVariantMap data = reader.restoreValues();
|
QVariantMap data = reader.restoreValues();
|
||||||
|
|
||||||
// Check version
|
// Check version
|
||||||
int version = data.value(QLatin1String(DEBUGGER_FILE_VERSION_KEY), 0).toInt();
|
int version = data.value(QLatin1String(DEBUGGER_FILE_VERSION_KEY), 0).toInt();
|
||||||
if (version < 1)
|
if (version < 1)
|
||||||
return result;
|
return;
|
||||||
|
|
||||||
int count = data.value(QLatin1String(DEBUGGER_COUNT_KEY), 0).toInt();
|
int count = data.value(QLatin1String(DEBUGGER_COUNT_KEY), 0).toInt();
|
||||||
for (int i = 0; i < count; ++i) {
|
for (int i = 0; i < count; ++i) {
|
||||||
const QString key = QString::fromLatin1(DEBUGGER_DATA_KEY) + QString::number(i);
|
const QString key = QString::fromLatin1(DEBUGGER_DATA_KEY) + QString::number(i);
|
||||||
if (!data.contains(key))
|
if (!data.contains(key))
|
||||||
break;
|
continue;
|
||||||
const QVariantMap dbMap = data.value(key).toMap();
|
const QVariantMap dbMap = data.value(key).toMap();
|
||||||
DebuggerItem item;
|
DebuggerItem item;
|
||||||
item.fromMap(dbMap);
|
item.fromMap(dbMap);
|
||||||
result.append(item);
|
if (isSystem) {
|
||||||
|
item.setAutoDetected(true);
|
||||||
|
// SDK debuggers are always considered to be up-to-date, so no need to recheck them.
|
||||||
|
} else {
|
||||||
|
// User settings.
|
||||||
|
if (item.isAutoDetected() && !item.isValid()) {
|
||||||
|
qWarning() << QString::fromLatin1("DebuggerItem \"%1\" (%2) dropped since it is not valid")
|
||||||
|
.arg(item.command().toString()).arg(item.id().toString());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DebuggerItemManager::registerDebugger(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<DebuggerItem> DebuggerItemManager::m_debuggers;
|
QList<DebuggerItem> DebuggerItemManager::m_debuggers;
|
||||||
@@ -361,7 +404,7 @@ DebuggerItemModel *DebuggerItemManager::model()
|
|||||||
return m_model;
|
return m_model;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerItemManager::autoDetectCdbDebugger()
|
void DebuggerItemManager::autoDetectCdbDebuggers()
|
||||||
{
|
{
|
||||||
QList<FileName> cdbs;
|
QList<FileName> cdbs;
|
||||||
|
|
||||||
@@ -419,16 +462,34 @@ void DebuggerItemManager::autoDetectCdbDebugger()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerItemManager::autoDetectDebuggers()
|
void DebuggerItemManager::autoDetectGdbOrLldbDebuggers()
|
||||||
{
|
{
|
||||||
autoDetectCdbDebugger();
|
|
||||||
|
|
||||||
QStringList filters;
|
QStringList filters;
|
||||||
filters.append(QLatin1String("gdb-i686-pc-mingw32"));
|
filters.append(QLatin1String("gdb-i686-pc-mingw32"));
|
||||||
filters.append(QLatin1String("gdb"));
|
filters.append(QLatin1String("gdb"));
|
||||||
filters.append(QLatin1String("lldb"));
|
filters.append(QLatin1String("lldb"));
|
||||||
filters.append(QLatin1String("lldb-*"));
|
filters.append(QLatin1String("lldb-*"));
|
||||||
|
|
||||||
|
// DebuggerItem result;
|
||||||
|
// result.setAutoDetected(true);
|
||||||
|
// result.setDisplayName(tr("Auto-detected for Tool Chain %1").arg(tc->displayName()));
|
||||||
|
/*
|
||||||
|
// Check suggestions from the SDK.
|
||||||
|
Environment env = Environment::systemEnvironment();
|
||||||
|
if (tc) {
|
||||||
|
tc->addToEnvironment(env); // Find MinGW gdb in toolchain environment.
|
||||||
|
QString path = tc->suggestedDebugger().toString();
|
||||||
|
if (!path.isEmpty()) {
|
||||||
|
const QFileInfo fi(path);
|
||||||
|
if (!fi.isAbsolute())
|
||||||
|
path = env.searchInPath(path);
|
||||||
|
result.command = FileName::fromString(path);
|
||||||
|
result.engineType = engineTypeFromBinary(path);
|
||||||
|
return maybeAddDebugger(result, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
QFileInfoList suspects;
|
QFileInfoList suspects;
|
||||||
|
|
||||||
QStringList path = Environment::systemEnvironment().path();
|
QStringList path = Environment::systemEnvironment().path();
|
||||||
@@ -512,46 +573,16 @@ const DebuggerItem *DebuggerItemManager::findById(const QVariant &id)
|
|||||||
|
|
||||||
void DebuggerItemManager::restoreDebuggers()
|
void DebuggerItemManager::restoreDebuggers()
|
||||||
{
|
{
|
||||||
QList<DebuggerItem> dbsToCheck;
|
|
||||||
|
|
||||||
// Read debuggers from SDK
|
// Read debuggers from SDK
|
||||||
QFileInfo systemSettingsFile(Core::ICore::settings(QSettings::SystemScope)->fileName());
|
QFileInfo systemSettingsFile(Core::ICore::settings(QSettings::SystemScope)->fileName());
|
||||||
QList<DebuggerItem> dbsToRegister =
|
readDebuggers(FileName::fromString(systemSettingsFile.absolutePath() + QLatin1String(DEBUGGER_FILENAME)), true);
|
||||||
readDebuggers(FileName::fromString(systemSettingsFile.absolutePath() + QLatin1String(DEBUGGER_FILENAME)));
|
|
||||||
|
|
||||||
// These are autodetected.
|
|
||||||
for (int i = 0, n = dbsToRegister.size(); i != n; ++i)
|
|
||||||
dbsToRegister[i].setAutoDetected(true);
|
|
||||||
|
|
||||||
// SDK debuggers are always considered to be up-to-date, so no need to recheck them.
|
|
||||||
|
|
||||||
// Read all debuggers from user file.
|
// Read all debuggers from user file.
|
||||||
foreach (const DebuggerItem &item, readDebuggers(userSettingsFileName())) {
|
readDebuggers(userSettingsFileName(), false);
|
||||||
if (item.isAutoDetected())
|
|
||||||
dbsToCheck.append(item);
|
|
||||||
else
|
|
||||||
dbsToRegister.append(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keep debuggers that were not rediscovered but are still executable and delete the rest
|
|
||||||
foreach (const DebuggerItem &item, dbsToCheck) {
|
|
||||||
if (!item.isValid()) {
|
|
||||||
qWarning() << QString::fromLatin1("DebuggerItem \"%1\" (%2) dropped since it is not valid")
|
|
||||||
.arg(item.command().toString()).arg(item.id().toString());
|
|
||||||
} else {
|
|
||||||
dbsToRegister.append(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0, n = dbsToRegister.size(); i != n; ++i) {
|
|
||||||
DebuggerItem item = dbsToRegister.at(i);
|
|
||||||
if (findByCommand(item.command()))
|
|
||||||
continue;
|
|
||||||
addDebugger(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Auto detect current.
|
// Auto detect current.
|
||||||
autoDetectDebuggers();
|
autoDetectCdbDebuggers();
|
||||||
|
autoDetectGdbOrLldbDebuggers();
|
||||||
|
|
||||||
// Add debuggers from pre-3.x profiles.xml
|
// Add debuggers from pre-3.x profiles.xml
|
||||||
readLegacyDebuggers();
|
readLegacyDebuggers();
|
||||||
@@ -639,72 +670,6 @@ void DebuggerItemManager::setItemData(const QVariant &id, const QString &display
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant DebuggerItemManager::defaultDebugger(ToolChain *tc)
|
|
||||||
{
|
|
||||||
QTC_ASSERT(tc, return QVariant());
|
|
||||||
|
|
||||||
DebuggerItem result;
|
|
||||||
result.setAutoDetected(true);
|
|
||||||
result.setDisplayName(tr("Auto-detected for Tool Chain %1").arg(tc->displayName()));
|
|
||||||
|
|
||||||
Abi abi = Abi::hostAbi();
|
|
||||||
if (tc)
|
|
||||||
abi = tc->targetAbi();
|
|
||||||
|
|
||||||
// if (abis.first().wordWidth() == 32)
|
|
||||||
// result.first = cdb.toString();
|
|
||||||
// else if (abis.first().wordWidth() == 64)
|
|
||||||
// result.second = cdb.toString();
|
|
||||||
// // prefer 64bit debugger, even for 32bit binaries:
|
|
||||||
// if (!result.second.isEmpty())
|
|
||||||
// result.first = result.second;
|
|
||||||
|
|
||||||
|
|
||||||
foreach (const DebuggerItem &item, m_debuggers)
|
|
||||||
foreach (const Abi targetAbi, item.abis())
|
|
||||||
if (targetAbi.isCompatibleWith(abi))
|
|
||||||
return item.id();
|
|
||||||
|
|
||||||
return QVariant();
|
|
||||||
|
|
||||||
/*
|
|
||||||
// CDB for windows:
|
|
||||||
if (abi.os() == Abi::WindowsOS && abi.osFlavor() != Abi::WindowsMSysFlavor) {
|
|
||||||
QPair<QString, QString> cdbs = autoDetectCdbDebugger();
|
|
||||||
result.command = FileName::fromString(abi.wordWidth() == 32 ? cdbs.first : cdbs.second);
|
|
||||||
result.engineType = CdbEngineType;
|
|
||||||
return maybeAddDebugger(result, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check suggestions from the SDK.
|
|
||||||
Environment env = Environment::systemEnvironment();
|
|
||||||
if (tc) {
|
|
||||||
tc->addToEnvironment(env); // Find MinGW gdb in toolchain environment.
|
|
||||||
QString path = tc->suggestedDebugger().toString();
|
|
||||||
if (!path.isEmpty()) {
|
|
||||||
const QFileInfo fi(path);
|
|
||||||
if (!fi.isAbsolute())
|
|
||||||
path = env.searchInPath(path);
|
|
||||||
result.command = FileName::fromString(path);
|
|
||||||
result.engineType = engineTypeFromBinary(path);
|
|
||||||
return maybeAddDebugger(result, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default to GDB, system GDB
|
|
||||||
result.engineType = GdbEngineType;
|
|
||||||
QString gdb;
|
|
||||||
const QString systemGdb = QLatin1String("gdb");
|
|
||||||
// MinGW: Search for the python-enabled gdb first.
|
|
||||||
if (abi.os() == Abi::WindowsOS && abi.osFlavor() == Abi::WindowsMSysFlavor)
|
|
||||||
gdb = env.searchInPath(QLatin1String("gdb-i686-pc-mingw32"));
|
|
||||||
if (gdb.isEmpty())
|
|
||||||
gdb = env.searchInPath(systemGdb);
|
|
||||||
result.command = FileName::fromString(env.searchInPath(gdb.isEmpty() ? systemGdb : gdb));
|
|
||||||
return maybeAddDebugger(result, false);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
static QList<QStandardItem *> describeItem(const DebuggerItem &item)
|
static QList<QStandardItem *> describeItem(const DebuggerItem &item)
|
||||||
@@ -946,7 +911,9 @@ void DebuggerKitConfigWidget::manageDebuggers()
|
|||||||
|
|
||||||
void DebuggerKitConfigWidget::currentDebuggerChanged(int)
|
void DebuggerKitConfigWidget::currentDebuggerChanged(int)
|
||||||
{
|
{
|
||||||
m_kit->setValue(DebuggerKitInformation::id(), m_comboBox->itemData(m_comboBox->currentIndex()));
|
int currentIndex = m_comboBox->currentIndex();
|
||||||
|
QVariant id = m_comboBox->itemData(currentIndex);
|
||||||
|
m_kit->setValue(DebuggerKitInformation::id(), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerKitConfigWidget::onDebuggerAdded(const QVariant &id, const QString &displayName)
|
void DebuggerKitConfigWidget::onDebuggerAdded(const QVariant &id, const QString &displayName)
|
||||||
|
|||||||
@@ -185,6 +185,42 @@ void DebuggerItem::setAbi(const Abi &abi)
|
|||||||
m_abis.append(abi);
|
m_abis.append(abi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DebuggerItem::MatchLevel matchSingle(const Abi &debuggerAbi, const Abi &targetAbi)
|
||||||
|
{
|
||||||
|
if (debuggerAbi.architecture() != targetAbi.architecture())
|
||||||
|
return DebuggerItem::DoesNotMatch;
|
||||||
|
|
||||||
|
if (debuggerAbi.os() != targetAbi.os())
|
||||||
|
return DebuggerItem::DoesNotMatch;
|
||||||
|
|
||||||
|
if (debuggerAbi.binaryFormat() != targetAbi.binaryFormat())
|
||||||
|
return DebuggerItem::DoesNotMatch;
|
||||||
|
|
||||||
|
if (debuggerAbi.wordWidth() != targetAbi.wordWidth())
|
||||||
|
return DebuggerItem::DoesNotMatch;
|
||||||
|
|
||||||
|
if (debuggerAbi.os() == Abi::WindowsOS) {
|
||||||
|
if (debuggerAbi.osFlavor() == Abi::WindowsMSysFlavor && targetAbi.osFlavor() != Abi::WindowsMSysFlavor)
|
||||||
|
return DebuggerItem::DoesNotMatch;
|
||||||
|
if (debuggerAbi.osFlavor() != Abi::WindowsMSysFlavor && targetAbi.osFlavor() == Abi::WindowsMSysFlavor)
|
||||||
|
return DebuggerItem::DoesNotMatch;
|
||||||
|
return DebuggerItem::MatchesSomewhat;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DebuggerItem::MatchesPerfectly;
|
||||||
|
}
|
||||||
|
|
||||||
|
DebuggerItem::MatchLevel DebuggerItem::matchTarget(const Abi &targetAbi) const
|
||||||
|
{
|
||||||
|
MatchLevel bestMatch = DoesNotMatch;
|
||||||
|
foreach (const Abi &debuggerAbi, m_abis) {
|
||||||
|
MatchLevel currentMatch = matchSingle(debuggerAbi, targetAbi);
|
||||||
|
if (currentMatch > bestMatch)
|
||||||
|
bestMatch = currentMatch;
|
||||||
|
}
|
||||||
|
return bestMatch;
|
||||||
|
}
|
||||||
|
|
||||||
bool Debugger::DebuggerItem::isValid() const
|
bool Debugger::DebuggerItem::isValid() const
|
||||||
{
|
{
|
||||||
return m_engineType != NoEngineType;
|
return m_engineType != NoEngineType;
|
||||||
|
|||||||
@@ -77,6 +77,9 @@ public:
|
|||||||
void setAbis(const QList<ProjectExplorer::Abi> &abis);
|
void setAbis(const QList<ProjectExplorer::Abi> &abis);
|
||||||
void setAbi(const ProjectExplorer::Abi &abi);
|
void setAbi(const ProjectExplorer::Abi &abi);
|
||||||
|
|
||||||
|
enum MatchLevel { DoesNotMatch, MatchesSomewhat, MatchesPerfectly };
|
||||||
|
MatchLevel matchTarget(const ProjectExplorer::Abi &targetAbi) const;
|
||||||
|
|
||||||
QStringList abiNames() const;
|
QStringList abiNames() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -113,7 +116,6 @@ public:
|
|||||||
static const DebuggerItem *findByCommand(const Utils::FileName &command);
|
static const DebuggerItem *findByCommand(const Utils::FileName &command);
|
||||||
static const DebuggerItem *findById(const QVariant &id);
|
static const DebuggerItem *findById(const QVariant &id);
|
||||||
|
|
||||||
static QVariant defaultDebugger(ProjectExplorer::ToolChain *tc);
|
|
||||||
static void restoreDebuggers();
|
static void restoreDebuggers();
|
||||||
static QString uniqueDisplayName(const QString &base);
|
static QString uniqueDisplayName(const QString &base);
|
||||||
static void setItemData(const QVariant &id, const QString& displayName, const Utils::FileName &fileName);
|
static void setItemData(const QVariant &id, const QString& displayName, const Utils::FileName &fileName);
|
||||||
@@ -126,8 +128,8 @@ public slots:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
explicit DebuggerItemManager(QObject *parent = 0);
|
explicit DebuggerItemManager(QObject *parent = 0);
|
||||||
static void autoDetectDebuggers();
|
static void autoDetectGdbOrLldbDebuggers();
|
||||||
static void autoDetectCdbDebugger();
|
static void autoDetectCdbDebuggers();
|
||||||
static void readLegacyDebuggers();
|
static void readLegacyDebuggers();
|
||||||
|
|
||||||
static Utils::PersistentSettingsWriter *m_writer;
|
static Utils::PersistentSettingsWriter *m_writer;
|
||||||
|
|||||||
Reference in New Issue
Block a user