Debugger: Have a generic "GDB in PATH on Build Device" item

This is only checked at run-time, but allows smoother creation of
kits for standard setups as the (possibly remote) full path is
not needed.

Remove the DebuggerKitAspect::fixup() implementation. Too much magic
by now, and worst thing that could happen is a non-matching debugger
that will clearly bark when used.

Change-Id: If2414610d479a5b93c3e6227b8736ddc61f70635
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
hjk
2023-03-28 07:40:26 +02:00
parent 5cfc52a92c
commit 463e47bbdd
4 changed files with 44 additions and 81 deletions

View File

@@ -170,6 +170,7 @@ class DebuggerItemModel : public TreeModel<TreeItem, StaticTreeItem, DebuggerTre
{ {
public: public:
DebuggerItemModel(); DebuggerItemModel();
enum { Generic, AutoDetected, Manual };
QModelIndex lastIndex() const; QModelIndex lastIndex() const;
void setCurrentIndex(const QModelIndex &index); void setCurrentIndex(const QModelIndex &index);
@@ -202,16 +203,35 @@ const DebuggerItem *findDebugger(const Predicate &pred)
DebuggerItemModel::DebuggerItemModel() DebuggerItemModel::DebuggerItemModel()
{ {
setHeader({Tr::tr("Name"), Tr::tr("Path"), Tr::tr("Type")}); setHeader({Tr::tr("Name"), Tr::tr("Path"), Tr::tr("Type")});
rootItem()->appendChild(
new StaticTreeItem({ProjectExplorer::Constants::msgAutoDetected()}, auto generic = new StaticTreeItem(Tr::tr("Generic"));
{ProjectExplorer::Constants::msgAutoDetectedToolTip()})); auto autoDetected = new StaticTreeItem({ProjectExplorer::Constants::msgAutoDetected()},
{ProjectExplorer::Constants::msgAutoDetectedToolTip()});
rootItem()->appendChild(generic);
rootItem()->appendChild(autoDetected);
rootItem()->appendChild(new StaticTreeItem(ProjectExplorer::Constants::msgManual())); rootItem()->appendChild(new StaticTreeItem(ProjectExplorer::Constants::msgManual()));
DebuggerItem genericGdb(QVariant("gdb"));
genericGdb.setAutoDetected(true);
genericGdb.setEngineType(GdbEngineType);
genericGdb.setAbi(Abi());
genericGdb.setCommand("gdb");
genericGdb.setUnexpandedDisplayName(Tr::tr("%1 from PATH on Build Device").arg("GDB"));
generic->appendChild(new DebuggerTreeItem(genericGdb, false));
DebuggerItem genericLldb(QVariant("lldb"));
genericLldb.setAutoDetected(true);
genericLldb.setEngineType(LldbEngineType);
genericLldb.setAbi(Abi());
genericLldb.setCommand("lldb");
genericLldb.setUnexpandedDisplayName(Tr::tr("%1 from PATH on Build Device").arg("LLDB"));
generic->appendChild(new DebuggerTreeItem(genericLldb, false));
} }
void DebuggerItemModel::addDebugger(const DebuggerItem &item, bool changed) void DebuggerItemModel::addDebugger(const DebuggerItem &item, bool changed)
{ {
QTC_ASSERT(item.id().isValid(), return); QTC_ASSERT(item.id().isValid(), return);
int group = item.isAutoDetected() ? 0 : 1; int group = item.isAutoDetected() ? AutoDetected : Manual;
rootItem()->childAt(group)->appendChild(new DebuggerTreeItem(item, changed)); rootItem()->childAt(group)->appendChild(new DebuggerTreeItem(item, changed));
} }

View File

@@ -228,66 +228,6 @@ void DebuggerKitAspect::setup(Kit *k)
k->setValue(DebuggerKitAspect::id(), bestLevel != DebuggerItem::DoesNotMatch ? bestItem.id() : QVariant()); k->setValue(DebuggerKitAspect::id(), bestLevel != DebuggerItem::DoesNotMatch ? bestItem.id() : QVariant());
} }
// This handles the upgrade path from 2.8 to 3.0
void DebuggerKitAspect::fix(Kit *k)
{
QTC_ASSERT(k, return);
// This can be Id, binary path, but not "auto" anymore.
const QVariant rawId = k->value(DebuggerKitAspect::id());
if (rawId.toString().isEmpty()) // No debugger set, that is fine.
return;
if (rawId.type() == QVariant::String) {
const DebuggerItem * const item = DebuggerItemManager::findById(rawId);
if (!item) {
qWarning("Unknown debugger id %s in kit %s",
qPrintable(rawId.toString()), qPrintable(k->displayName()));
k->setValue(DebuggerKitAspect::id(), QVariant());
setup(k);
return;
}
Abi kitAbi;
if (ToolChainKitAspect::toolChains(k).isEmpty()) {
if (DeviceTypeKitAspect::deviceTypeId(k)
!= ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE) {
return;
}
kitAbi = Abi(Abi::UnknownArchitecture, Abi::hostAbi().os());
} else {
kitAbi = ToolChainKitAspect::targetAbi(k);
}
if (item->matchTarget(kitAbi) != DebuggerItem::DoesNotMatch)
return;
k->setValue(DebuggerKitAspect::id(), QVariant());
setup(k);
return; // All fine (now).
}
QMap<QString, QVariant> map = rawId.toMap();
QString binary = map.value("Binary").toString();
if (binary == "auto") {
// This should not happen as "auto" is handled by setup() already.
QTC_CHECK(false);
k->setValue(DebuggerKitAspect::id(), QVariant());
return;
}
FilePath fileName = FilePath::fromUserInput(binary);
const DebuggerItem *item = DebuggerItemManager::findByCommand(fileName);
if (!item) {
qWarning("Debugger command %s invalid in kit %s",
qPrintable(binary), qPrintable(k->displayName()));
k->setValue(DebuggerKitAspect::id(), QVariant());
return;
}
k->setValue(DebuggerKitAspect::id(), item->id());
}
// 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
// a verbose one with a list of errors. // a verbose one with a list of errors.
@@ -299,15 +239,15 @@ DebuggerKitAspect::ConfigurationErrors DebuggerKitAspect::configurationErrors(co
if (!item) if (!item)
return NoDebugger; return NoDebugger;
if (item->command().isEmpty()) const FilePath debugger = item->command();
if (debugger.isEmpty())
return NoDebugger; return NoDebugger;
if (debugger.isRelativePath())
return NoConfigurationError;
ConfigurationErrors result = NoConfigurationError; ConfigurationErrors result = NoConfigurationError;
const FilePath debugger = item->command(); if (!debugger.isExecutableFile())
const bool found = debugger.exists() && !debugger.isDir();
if (!found)
result |= DebuggerNotFound;
else if (!debugger.isExecutableFile())
result |= DebuggerNotExecutable; result |= DebuggerNotExecutable;
const Abi tcAbi = ToolChainKitAspect::targetAbi(k); const Abi tcAbi = ToolChainKitAspect::targetAbi(k);
@@ -318,16 +258,15 @@ DebuggerKitAspect::ConfigurationErrors DebuggerKitAspect::configurationErrors(co
result |= DebuggerDoesNotMatch; result |= DebuggerDoesNotMatch;
} }
if (!found) { if (item->engineType() == NoEngineType)
if (item->engineType() == NoEngineType) return NoDebugger;
return NoDebugger;
// We need an absolute path to be able to locate Python on Windows. // We need an absolute path to be able to locate Python on Windows.
if (item->engineType() == GdbEngineType) { if (item->engineType() == GdbEngineType) {
if (tcAbi.os() == Abi::WindowsOS && !debugger.isAbsolutePath()) if (tcAbi.os() == Abi::WindowsOS && !debugger.isAbsolutePath())
result |= DebuggerNeedsAbsolutePath; result |= DebuggerNeedsAbsolutePath;
}
} }
return result; return result;
} }
@@ -342,7 +281,12 @@ Runnable DebuggerKitAspect::runnable(const Kit *kit)
{ {
Runnable runnable; Runnable runnable;
if (const DebuggerItem *item = debugger(kit)) { if (const DebuggerItem *item = debugger(kit)) {
runnable.command = CommandLine{item->command()}; FilePath cmd = item->command();
if (cmd.isRelativePath()) {
if (const IDeviceConstPtr buildDevice = BuildDeviceKitAspect::device(kit))
cmd = buildDevice->searchExecutableInPath(cmd.path());
}
runnable.command.setExecutable(cmd);
runnable.workingDirectory = item->workingDirectory(); runnable.workingDirectory = item->workingDirectory();
runnable.environment = kit->runEnvironment(); runnable.environment = kit->runEnvironment();
runnable.environment.set("LC_NUMERIC", "C"); runnable.environment.set("LC_NUMERIC", "C");

View File

@@ -21,7 +21,6 @@ public:
{ return DebuggerKitAspect::validateDebugger(k); } { return DebuggerKitAspect::validateDebugger(k); }
void setup(ProjectExplorer::Kit *k) override; void setup(ProjectExplorer::Kit *k) override;
void fix(ProjectExplorer::Kit *k) override;
static const DebuggerItem *debugger(const ProjectExplorer::Kit *kit); static const DebuggerItem *debugger(const ProjectExplorer::Kit *kit);
static ProjectExplorer::Runnable runnable(const ProjectExplorer::Kit *kit); static ProjectExplorer::Runnable runnable(const ProjectExplorer::Kit *kit);

View File

@@ -339,7 +339,7 @@ Environment LinuxDevicePrivate::getEnvironment()
return m_environmentCache.value(); return m_environmentCache.value();
QtcProcess getEnvProc; QtcProcess getEnvProc;
getEnvProc.setCommand({FilePath("env").onDevice(q->rootPath()), {}}); getEnvProc.setCommand({q->filePath("env"), {}});
getEnvProc.runBlocking(); getEnvProc.runBlocking();
const QString remoteOutput = getEnvProc.cleanedStdOut(); const QString remoteOutput = getEnvProc.cleanedStdOut();