Commit 32b484e2 authored by Tobias Hunger's avatar Tobias Hunger Committed by Tim Jenssen

Introduce ToolChainKitInformation::targetAbi(Kit *)

Use that in the debugger. That simplifies the logic a bit.

Change-Id: Ia72607283373ee0f89a91f347db0ef2c87cf9fb3
Reviewed-by: default avatarTim Jenssen <tim.jenssen@theqtcompany.com>
parent 7ab2ed57
......@@ -109,10 +109,8 @@ DebuggerKitChooser::DebuggerKitChooser(Mode mode, QWidget *parent)
// Match valid debuggers and restrict local debugging to compatible toolchains.
if (!DebuggerKitInformation::isValidDebugger(k))
return false;
if (m_mode == LocalDebugging) {
const ToolChain *tc = ToolChainKitInformation::toolChain(k, ToolChain::Language::Cxx);
return tc && tc->targetAbi().os() == m_hostAbi.os();
}
if (m_mode == LocalDebugging)
return ToolChainKitInformation::targetAbi(k).os() == m_hostAbi.os();
return true;
});
}
......
......@@ -57,15 +57,13 @@ DebuggerKitInformation::DebuggerKitInformation()
QVariant DebuggerKitInformation::defaultValue(const Kit *k) const
{
ToolChain *tc = ToolChainKitInformation::toolChain(k, ToolChain::Language::Cxx);
if (!tc)
return QVariant();
const Abi toolChainAbi = tc->targetAbi();
foreach (const DebuggerItem &item, DebuggerItemManager::debuggers())
foreach (const Abi targetAbi, item.abis())
const Abi toolChainAbi = ToolChainKitInformation::targetAbi(k);
foreach (const DebuggerItem &item, DebuggerItemManager::debuggers()) {
foreach (const Abi targetAbi, item.abis()) {
if (targetAbi.isCompatibleWith(toolChainAbi))
return item.id();
}
}
return QVariant();
}
......@@ -87,7 +85,7 @@ void DebuggerKitInformation::setup(Kit *k)
// </valuemap>
const QVariant rawId = k->value(DebuggerKitInformation::id());
const ToolChain *tc = ToolChainKitInformation::toolChain(k, ToolChain::Language::Cxx);
const Abi tcAbi = ToolChainKitInformation::targetAbi(k);
// Get the best of the available debugger matching the kit's toolchain.
// The general idea is to find an item that exactly matches what
......@@ -102,13 +100,7 @@ void DebuggerKitInformation::setup(Kit *k)
if (rawId.isNull()) {
// Initial setup of a kit.
if (tc) {
// Use item if target toolchain fits.
level = item.matchTarget(tc->targetAbi());
} else {
// Use item if host toolchain fits, but only as fallback.
level = std::min(item.matchTarget(Abi::hostAbi()), DebuggerItem::MatchesSomewhat);
}
level = item.matchTarget(tcAbi);
} else if (rawId.type() == QVariant::String) {
// New structure.
if (item.id() == rawId) {
......@@ -117,8 +109,7 @@ void DebuggerKitInformation::setup(Kit *k)
} else {
// This item does not match by ID, and is an unlikely candidate.
// However, consider using it as fallback if the tool chain fits.
if (tc)
level = std::min(item.matchTarget(tc->targetAbi()), DebuggerItem::MatchesSomewhat);
level = std::min(item.matchTarget(tcAbi), DebuggerItem::MatchesSomewhat);
}
} else {
// Old structure.
......@@ -129,31 +120,19 @@ void DebuggerKitInformation::setup(Kit *k)
// an engine type.
DebuggerEngineType autoEngine = DebuggerEngineType(map.value(QLatin1String("EngineType")).toInt());
if (item.engineType() == autoEngine) {
if (tc) {
// Use item if target toolchain fits.
level = item.matchTarget(tc->targetAbi());
} else {
// Use item if host toolchain fits, but only as fallback.
level = std::min(item.matchTarget(Abi::hostAbi()), DebuggerItem::MatchesSomewhat);
}
// Use item if host toolchain fits, but only as fallback.
level = std::min(item.matchTarget(tcAbi), DebuggerItem::MatchesSomewhat);
}
} else {
// We have an executable path.
FileName fileName = FileName::fromUserInput(binary);
if (item.command() == fileName) {
// And it's is the path of this item.
if (tc) {
// Use item if target toolchain fits.
level = item.matchTarget(tc->targetAbi());
} else {
// Use item if host toolchain fits, but only as fallback.
level = std::min(item.matchTarget(Abi::hostAbi()), DebuggerItem::MatchesSomewhat);
}
level = std::min(item.matchTarget(tcAbi), DebuggerItem::MatchesSomewhat);
} else {
// This item does not match by filename, and is an unlikely candidate.
// However, consider using it as fallback if the tool chain fits.
if (tc)
level = std::min(item.matchTarget(tc->targetAbi()), DebuggerItem::MatchesSomewhat);
level = std::min(item.matchTarget(tcAbi), DebuggerItem::MatchesSomewhat);
}
}
}
......@@ -237,8 +216,8 @@ static unsigned debuggerConfigurationErrors(const Kit *k)
else if (!fi.isExecutable())
result |= DebuggerNotExecutable;
const ToolChain *tc = ToolChainKitInformation::toolChain(k, ToolChain::Language::Cxx);
if (tc && item->matchTarget(tc->targetAbi()) == DebuggerItem::DoesNotMatch) {
const Abi tcAbi = ToolChainKitInformation::targetAbi(k);
if (item->matchTarget(tcAbi) == DebuggerItem::DoesNotMatch) {
// currently restricting the check to desktop devices, may be extended to all device types
const IDevice::ConstPtr device = DeviceKitInformation::device(k);
if (device && device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)
......@@ -251,7 +230,7 @@ static unsigned debuggerConfigurationErrors(const Kit *k)
// We need an absolute path to be able to locate Python on Windows.
if (item->engineType() == GdbEngineType) {
if (tc && tc->targetAbi().os() == Abi::WindowsOS && !fi.isAbsolute())
if (tcAbi.os() == Abi::WindowsOS && !fi.isAbsolute())
result |= DebuggerNeedsAbsolutePath;
}
}
......
......@@ -567,10 +567,8 @@ static std::function<bool(const Kit *)> cdbMatcher(char wordWidth = 0)
|| !DebuggerKitInformation::isValidDebugger(k)) {
return false;
}
if (wordWidth) {
const ToolChain *tc = ToolChainKitInformation::toolChain(k, ToolChain::Language::Cxx);
return tc && wordWidth == tc->targetAbi().wordWidth();
}
if (wordWidth)
ToolChainKitInformation::targetAbi(k).wordWidth();
return true;
};
}
......@@ -1103,18 +1101,15 @@ static Kit *guessKitFromParameters(const DebuggerRunParameters &rp)
if (!abis.isEmpty()) {
// Try exact abis.
kit = KitManager::find(KitMatcher([abis](const Kit *k) -> bool {
if (const ToolChain *tc = ToolChainKitInformation::toolChain(k, ToolChain::Language::Cxx))
return abis.contains(tc->targetAbi()) && DebuggerKitInformation::isValidDebugger(k);
return false;
const Abi tcAbi = ToolChainKitInformation::targetAbi(k);
return abis.contains(tcAbi) && DebuggerKitInformation::isValidDebugger(k);
}));
if (!kit) {
// Or something compatible.
kit = KitManager::find(KitMatcher([abis](const Kit *k) -> bool {
if (const ToolChain *tc = ToolChainKitInformation::toolChain(k, ToolChain::Language::Cxx))
foreach (const Abi &a, abis)
if (a.isCompatibleWith(tc->targetAbi()) && DebuggerKitInformation::isValidDebugger(k))
return true;
return false;
const Abi tcAbi = ToolChainKitInformation::targetAbi(k);
return DebuggerKitInformation::isValidDebugger(k)
&& Utils::contains(abis, [tcAbi](const Abi &a) { return a.isCompatibleWith(tcAbi); });
}));
}
}
......@@ -2080,9 +2075,8 @@ DebuggerRunControl *DebuggerPluginPrivate::attachToRunningProcess(Kit *kit,
return 0;
}
bool isWindows = false;
if (const ToolChain *tc = ToolChainKitInformation::toolChain(kit, ToolChain::Language::Cxx))
isWindows = tc->targetAbi().os() == Abi::WindowsOS;
const Abi tcAbi = ToolChainKitInformation::targetAbi(kit);
const bool isWindows = (tcAbi.os() == Abi::WindowsOS);
if (isWindows && isWinProcessBeingDebugged(process.pid)) {
AsynchronousMessageBox::warning(tr("Process Already Under Debugger Control"),
tr("The process %1 is already under the control of a debugger.\n"
......
......@@ -366,8 +366,7 @@ static DebuggerRunControl *doCreate(DebuggerRunParameters rp, RunConfiguration *
}
}
if (ToolChain *tc = ToolChainKitInformation::toolChain(kit, ToolChain::Language::Cxx))
rp.toolChainAbi = tc->targetAbi();
rp.toolChainAbi = ToolChainKitInformation::targetAbi(kit);
if (false) {
const QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(kit);
......
......@@ -290,6 +290,39 @@ void ToolChainKitInformation::setToolChain(Kit *k, ToolChain::Language l, ToolCh
k->setValue(id(), result);
}
Abi ToolChainKitInformation::targetAbi(const Kit *k)
{
QList<ToolChain *> tcList = toolChains(k);
// Find the best possible ABI for all the tool chains...
Abi cxxAbi;
QHash<Abi, int> abiCount;
foreach (ToolChain *tc, tcList) {
Abi ta = tc->targetAbi();
if (tc->language() == ToolChain::Language::Cxx)
cxxAbi = tc->targetAbi();
abiCount[ta] = (abiCount.contains(ta) ? abiCount[ta] + 1 : 1);
}
QVector<Abi> candidates;
int count = -1;
candidates.reserve(tcList.count());
for (auto i = abiCount.begin(); i != abiCount.end(); ++i) {
if (i.value() > count) {
candidates.clear();
candidates.append(i.key());
count = i.value();
} else if (i.value() == count) {
candidates.append(i.key());
}
}
// Found a good candidate:
if (candidates.isEmpty())
return Abi::hostAbi();
if (candidates.contains(cxxAbi)) // Use Cxx compiler as a tie breaker
return cxxAbi;
return candidates.at(0); // Use basically a random Abi...
}
QString ToolChainKitInformation::msgNoToolChainInTarget()
{
return tr("No compiler set in kit.");
......
......@@ -25,6 +25,7 @@
#pragma once
#include "abi.h"
#include "devicesupport/idevice.h"
#include "kitmanager.h"
#include "kit.h"
......@@ -96,6 +97,7 @@ public:
static QList<ToolChain *> toolChains(const Kit *k);
static void setToolChain(Kit *k, ToolChain *tc);
static void setToolChain(Kit *k, ToolChain::Language l, ToolChain *tc);
static Abi targetAbi(const Kit *k);
static QString msgNoToolChainInTarget();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment