forked from qt-creator/qt-creator
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:
@@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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,7 +258,6 @@ DebuggerKitAspect::ConfigurationErrors DebuggerKitAspect::configurationErrors(co
|
|||||||
result |= DebuggerDoesNotMatch;
|
result |= DebuggerDoesNotMatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found) {
|
|
||||||
if (item->engineType() == NoEngineType)
|
if (item->engineType() == NoEngineType)
|
||||||
return NoDebugger;
|
return NoDebugger;
|
||||||
|
|
||||||
@@ -327,7 +266,7 @@ DebuggerKitAspect::ConfigurationErrors DebuggerKitAspect::configurationErrors(co
|
|||||||
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");
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user