From 8d19b306ed2b2fd4a90ecc2b49baca31acd52077 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Wed, 28 Nov 2018 14:30:42 +0100 Subject: [PATCH] Android: Detect clang and gdb from older NDK Get some minimal compatibility with the older NDK that is used for Qt < 5.12 back. This detects clang-3.6 and gdb from NDK 10e. For building, the android-g++ mkspec continues to be used for Qt < 5.12 (it uses Qt's default mkspec, regardless of toolchain in the kit, because the toolchain reports to support both). Task-number: QTCREATORBUG-21595 Change-Id: I3487c38093f43ccae2418fb28807a50fbda101a8 Reviewed-by: Andy Shaw Reviewed-by: BogDan Vatra Reviewed-by: Christian Stenger --- src/plugins/android/androidconfigurations.cpp | 57 +++++++++++++------ src/plugins/android/androidconfigurations.h | 2 +- src/plugins/android/androidtoolchain.cpp | 2 +- 3 files changed, 43 insertions(+), 18 deletions(-) diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp index a52c63d3702..47c8fe1f0bf 100644 --- a/src/plugins/android/androidconfigurations.cpp +++ b/src/plugins/android/androidconfigurations.cpp @@ -405,6 +405,9 @@ FileName AndroidConfig::clangPath() const { FileName clangPath = m_ndkLocation; clangPath.appendPath("toolchains/llvm/prebuilt/"); + FileName oldNdkClangPath = m_ndkLocation; + oldNdkClangPath.appendPath("toolchains/llvm-3.6/prebuilt/"); + const QVector clangSearchPaths{clangPath, oldNdkClangPath}; // detect toolchain host QStringList hostPatterns; @@ -421,20 +424,30 @@ FileName AndroidConfig::clangPath() const default: /* unknown host */ return FileName(); } - QDirIterator iter(clangPath.toString(), hostPatterns, QDir::Dirs); - if (iter.hasNext()) { - iter.next(); - return clangPath.appendPath(iter.fileName()) - .appendPath(HostOsInfo::withExecutableSuffix("bin/clang")); + for (const FileName &path : clangSearchPaths) { + QDirIterator iter(path.toString(), hostPatterns, QDir::Dirs); + if (iter.hasNext()) { + iter.next(); + FileName found = path; + return found.appendPath(iter.fileName()) + .appendPath(HostOsInfo::withExecutableSuffix("bin/clang")); + } } - return clangPath; + return {}; } -FileName AndroidConfig::gdbPath() const +FileName AndroidConfig::gdbPath(const ProjectExplorer::Abi &abi) const { FileName path = m_ndkLocation; path.appendPath(QString("prebuilt/%1/bin/gdb%2").arg(toolchainHost(), QTC_HOST_EXE_SUFFIX)); + if (path.exists()) + return path; + // fallback for old NDKs (e.g. 10e) + path = m_ndkLocation; + path.appendPath( + QString("toolchains/%1-4.9/prebuilt/%2/bin/%3-gdb%4") + .arg(toolchainPrefix(abi), toolchainHost(), toolsPrefix(abi), QTC_HOST_EXE_SUFFIX)); return path; } @@ -991,6 +1004,26 @@ void AndroidConfigurations::removeOldToolChains() } } +static QVariant findOrRegisterDebugger(ToolChain *tc) +{ + const FileName command = tc->suggestedDebugger(); + // check if the debugger is already registered, but ignoring the display name + const Debugger::DebuggerItem *existing = Debugger::DebuggerItemManager::findByCommand(command); + if (existing && existing->engineType() == Debugger::GdbEngineType && existing->isAutoDetected() + && existing->abis() == QList{tc->targetAbi()}) + return existing->id(); + // debugger not found, register a new one + Debugger::DebuggerItem debugger; + debugger.setCommand(tc->suggestedDebugger()); + debugger.setEngineType(Debugger::GdbEngineType); + debugger.setUnexpandedDisplayName( + AndroidConfigurations::tr("Android Debugger for %1").arg(tc->displayName())); + debugger.setAutoDetected(true); + debugger.setAbi(tc->targetAbi()); + debugger.reinitializeFromFile(); + return Debugger::DebuggerItemManager::registerDebugger(debugger); +} + void AndroidConfigurations::updateAutomaticKitList() { const QList existingKits = Utils::filtered(KitManager::kits(), [](Kit *k) { @@ -1065,15 +1098,7 @@ void AndroidConfigurations::updateAutomaticKitList() toSetup = existingKit; } - Debugger::DebuggerItem debugger; - debugger.setCommand(tc->suggestedDebugger()); - debugger.setEngineType(Debugger::GdbEngineType); - debugger.setUnexpandedDisplayName(tr("Android Debugger for %1").arg(tc->displayName())); - debugger.setAutoDetected(true); - debugger.setAbi(tc->targetAbi()); - debugger.reinitializeFromFile(); - QVariant id = Debugger::DebuggerItemManager::registerDebugger(debugger); - Debugger::DebuggerKitInformation::setDebugger(toSetup, id); + Debugger::DebuggerKitInformation::setDebugger(toSetup, findOrRegisterDebugger(tc)); AndroidGdbServerKitInformation::setGdbSever(toSetup, currentConfig().gdbServer(tc->targetAbi())); toSetup->makeSticky(); diff --git a/src/plugins/android/androidconfigurations.h b/src/plugins/android/androidconfigurations.h index dff705bb1cd..70d97c129c5 100644 --- a/src/plugins/android/androidconfigurations.h +++ b/src/plugins/android/androidconfigurations.h @@ -134,7 +134,7 @@ public: Utils::FileName aaptToolPath() const; Utils::FileName clangPath() const; - Utils::FileName gdbPath() const; + Utils::FileName gdbPath(const ProjectExplorer::Abi &abi) const; Utils::FileName makePath() const; Utils::FileName keytoolPath() const; diff --git a/src/plugins/android/androidtoolchain.cpp b/src/plugins/android/androidtoolchain.cpp index 280e1d69849..dd8d4ccfb29 100644 --- a/src/plugins/android/androidtoolchain.cpp +++ b/src/plugins/android/androidtoolchain.cpp @@ -109,7 +109,7 @@ void AndroidToolChain::addToEnvironment(Environment &env) const FileName AndroidToolChain::suggestedDebugger() const { // TODO: Make use of LLDB if available. - return AndroidConfigurations::currentConfig().gdbPath(); + return AndroidConfigurations::currentConfig().gdbPath(targetAbi()); } FileName AndroidToolChain::suggestedGdbServer() const