From a75cb044424f7d29b6841a32d325c0c5c1288f4c Mon Sep 17 00:00:00 2001 From: Assam Boudjelthia Date: Tue, 25 Feb 2020 00:19:28 +0200 Subject: [PATCH] Android: keep the debuggers list updated with auto detected toolchains Current autoDetected Android debuggers list is never cleaned, if one sets up many NDKs it could get really big and messy. This change tries to keep it clean from old or duplicate entries, as well as keep it chained to the autodection mechanism of Android toolchains and kits. Relies on 291807 to allow autoDection for kits, toolchains, debuggers to work out-of-box. Change-Id: I320a021f0435d80fd3d56c060caa316def533afa Reviewed-by: Alessandro Portale --- src/plugins/android/androidconfigurations.cpp | 68 +++++++++++++++++-- src/plugins/android/androidconfigurations.h | 1 + src/plugins/android/androidplugin.cpp | 2 +- 3 files changed, 63 insertions(+), 8 deletions(-) diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp index 0e794dd6d7e..90d6f875399 100644 --- a/src/plugins/android/androidconfigurations.cpp +++ b/src/plugins/android/androidconfigurations.cpp @@ -1090,22 +1090,73 @@ void AndroidConfigurations::removeOldToolChains() } } -static QVariant findOrRegisterDebugger(ToolChain *tc, const BaseQtVersion *qtVersion) +void AndroidConfigurations::removeUnusedDebuggers() { - const FilePath command = AndroidConfigurations::currentConfig().gdbPath(tc->targetAbi(), qtVersion); + QList uniqueNdks; + const QList qtVersions + = QtSupport::QtVersionManager::versions([](const QtSupport::BaseQtVersion *v) { + return v->type() == Constants::ANDROIDQT; + }); + + for (const QtSupport::BaseQtVersion *qt : qtVersions) { + FilePath ndkLocation = currentConfig().ndkLocation(qt); + if (!uniqueNdks.contains(ndkLocation)) + uniqueNdks.append(ndkLocation); + } + + const QList allDebuggers = Debugger::DebuggerItemManager::debuggers(); + for (const Debugger::DebuggerItem &debugger : allDebuggers) { + if (!debugger.displayName().contains("Android")) + continue; + + bool isChildOfNdk = false; + for (const FilePath &path : uniqueNdks) { + if (debugger.command().isChildOf(path)) { + isChildOfNdk = true; + break; + } + } + + if (!isChildOfNdk && debugger.isAutoDetected()) + Debugger::DebuggerItemManager::deregisterDebugger(debugger.id()); + } +} + +static QVariant findOrRegisterDebugger(ToolChain *tc, + const QStringList &abisList, + const BaseQtVersion *qtVersion) +{ + const FilePath command = AndroidConfigurations::currentConfig().gdbPath(tc->targetAbi(), + qtVersion); // check if the debugger is already registered, but ignoring the display name const Debugger::DebuggerItem *existing = Debugger::DebuggerItemManager::findByCommand(command); + + QList abis = Utils::transform(abisList, Abi::abiFromTargetTriplet); + + auto containsAbis = [abis](const Abis &secondAbis) { + for (const Abi &abi : secondAbis) { + if (!abis.contains(abi)) + return false; + } + return true; + }; + if (existing && existing->engineType() == Debugger::GdbEngineType && existing->isAutoDetected() - && existing->abis() == Abis{tc->targetAbi()}) + && containsAbis(existing->abis())) { + // update debugger info with new return existing->id(); + } + // debugger not found, register a new one Debugger::DebuggerItem debugger; debugger.setCommand(command); debugger.setEngineType(Debugger::GdbEngineType); debugger.setUnexpandedDisplayName( - AndroidConfigurations::tr("Android Debugger for %1").arg(tc->displayName())); + AndroidConfigurations::tr("Android Debugger (%1, NDK %2)") + .arg(abisList.join(", "), + AndroidConfigurations::currentConfig().ndkVersion(qtVersion).toString())); debugger.setAutoDetected(true); - debugger.setAbi(tc->targetAbi()); + debugger.setAbis(abis.toVector()); debugger.reinitializeFromFile(); return Debugger::DebuggerItemManager::registerDebugger(debugger); } @@ -1136,6 +1187,8 @@ void AndroidConfigurations::updateAutomaticKitList() return false; }); + removeUnusedDebuggers(); + QHash > qtVersionsForArch; const QList qtVersions = QtSupport::QtVersionManager::versions([](const QtSupport::BaseQtVersion *v) { @@ -1199,10 +1252,11 @@ void AndroidConfigurations::updateAutomaticKitList() ToolChainKitAspect::setToolChain(k, tc); QtSupport::QtKitAspect::setQtVersion(k, qt); DeviceKitAspect::setDevice(k, device); - Debugger::DebuggerKitAspect::setDebugger(k, findOrRegisterDebugger(tc, QtKitAspect::qtVersion(k))); + QStringList abis = static_cast(qt)->androidAbis(); + Debugger::DebuggerKitAspect::setDebugger(k, findOrRegisterDebugger(tc, abis, QtKitAspect::qtVersion(k))); k->makeSticky(); k->setUnexpandedDisplayName(tr("Android for %1 (Clang %2)") - .arg(static_cast(qt)->androidAbis().join(",")) + .arg(abis.join(",")) .arg(qt->displayName())); k->setValueSilently(Constants::ANDROID_KIT_NDK, currentConfig().ndkLocation(qt).toString()); k->setValueSilently(Constants::ANDROID_KIT_SDK, currentConfig().sdkLocation().toString()); diff --git a/src/plugins/android/androidconfigurations.h b/src/plugins/android/androidconfigurations.h index 4a4217e3a2c..b2f9ec02015 100644 --- a/src/plugins/android/androidconfigurations.h +++ b/src/plugins/android/androidconfigurations.h @@ -237,6 +237,7 @@ public: static QString defaultDevice(ProjectExplorer::Project *project, const QString &abi); // serial number or avd name static void clearDefaultDevices(ProjectExplorer::Project *project); static void registerNewToolChains(); + static void removeUnusedDebuggers(); static void removeOldToolChains(); static void updateAutomaticKitList(); static bool force32bitEmulator(); diff --git a/src/plugins/android/androidplugin.cpp b/src/plugins/android/androidplugin.cpp index 1fcdd9bd720..2e02d516492 100644 --- a/src/plugins/android/androidplugin.cpp +++ b/src/plugins/android/androidplugin.cpp @@ -177,8 +177,8 @@ void AndroidPlugin::kitsRestored() &AndroidPlugin::askUserAboutAndroidSetup, Qt::QueuedConnection); } - AndroidConfigurations::updateAutomaticKitList(); AndroidConfigurations::registerNewToolChains(); + AndroidConfigurations::updateAutomaticKitList(); connect(QtSupport::QtVersionManager::instance(), &QtSupport::QtVersionManager::qtVersionsChanged, AndroidConfigurations::instance(), &AndroidConfigurations::updateAutomaticKitList); disconnect(KitManager::instance(), &KitManager::kitsLoaded,