forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/4.8'
Change-Id: I5b18233936e3b2cd674df92a694ba73b5a3ed752
This commit is contained in:
@@ -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<FileName> 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<Abi>{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<Kit *> 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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -253,9 +253,10 @@ bool AndroidRunnerWorker::uploadFile(const QString &from, const QString &to, con
|
||||
return false;
|
||||
runAdb({"shell", "run-as", m_packageName, "rm", to});
|
||||
const QByteArray data = f.readAll();
|
||||
QString output;
|
||||
const bool res = runAdb({"shell", "run-as", m_packageName, QString("sh -c 'base64 -d > %1'").arg(to)},
|
||||
nullptr, data.toBase64());
|
||||
if (!res)
|
||||
&output, data.toBase64());
|
||||
if (!res || output.contains("base64: not found"))
|
||||
return false;
|
||||
return runAdb({"shell", "run-as", m_packageName, "chmod", flags, to});
|
||||
}
|
||||
@@ -400,13 +401,30 @@ void AndroidRunnerWorker::asyncStartHelper()
|
||||
// e.g. on Android 8 with NDK 10e
|
||||
runAdb({"shell", "run-as", m_packageName, "chmod", "a+x", packageDir.trimmed()});
|
||||
|
||||
QString gdbServerExecutable;
|
||||
QString gdbServerPrefix = "./lib/";
|
||||
if (m_gdbserverPath.isEmpty() || !uploadFile(m_gdbserverPath, "gdbserver")) {
|
||||
emit remoteProcessFinished(tr("Cannot find/copy C++ debug server."));
|
||||
return;
|
||||
// upload failed - check for old devices
|
||||
QString output;
|
||||
if (runAdb({"shell", "run-as", m_packageName, "ls", "lib/"}, &output)) {
|
||||
for (const auto &line: output.split('\n')) {
|
||||
if (line.indexOf("gdbserver") != -1/* || line.indexOf("lldb-server") != -1*/) {
|
||||
gdbServerExecutable = line.trimmed();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (gdbServerExecutable.isEmpty()) {
|
||||
emit remoteProcessFinished(tr("Cannot find/copy C++ debug server."));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
gdbServerPrefix = "./";
|
||||
gdbServerExecutable = "gdbserver";
|
||||
}
|
||||
|
||||
QString debuggerServerErr;
|
||||
if (!startDebuggerServer(packageDir, &debuggerServerErr)) {
|
||||
if (!startDebuggerServer(packageDir, gdbServerPrefix, gdbServerExecutable, &debuggerServerErr)) {
|
||||
emit remoteProcessFinished(debuggerServerErr);
|
||||
return;
|
||||
}
|
||||
@@ -450,16 +468,19 @@ void AndroidRunnerWorker::asyncStartHelper()
|
||||
}
|
||||
}
|
||||
|
||||
bool AndroidRunnerWorker::startDebuggerServer(QString packageDir, QString *errorStr)
|
||||
bool AndroidRunnerWorker::startDebuggerServer(const QString &packageDir,
|
||||
const QString &gdbServerPrefix,
|
||||
const QString &gdbServerExecutable,
|
||||
QString *errorStr)
|
||||
{
|
||||
QString gdbServerSocket = packageDir + "/debug-socket";
|
||||
runAdb({"shell", "run-as", m_packageName, "killall", "gdbserver"});
|
||||
runAdb({"shell", "run-as", m_packageName, "killall", gdbServerExecutable});
|
||||
runAdb({"shell", "run-as", m_packageName, "rm", gdbServerSocket});
|
||||
|
||||
QString gdbProcessErr;
|
||||
QStringList gdbServerArgs = selector();
|
||||
gdbServerArgs << "shell" << "run-as" << m_packageName << "./gdbserver" << "--multi"
|
||||
<< "+" + gdbServerSocket;
|
||||
gdbServerArgs << "shell" << "run-as" << m_packageName << gdbServerPrefix + gdbServerExecutable
|
||||
<< "--multi" << "+" + gdbServerSocket;
|
||||
m_gdbServerProcess.reset(AndroidManager::runAdbCommandDetached(gdbServerArgs, &gdbProcessErr));
|
||||
|
||||
if (!m_gdbServerProcess) {
|
||||
|
||||
@@ -73,7 +73,8 @@ signals:
|
||||
|
||||
protected:
|
||||
void asyncStartHelper();
|
||||
bool startDebuggerServer(QString packageDir, QString *errorStr = nullptr);
|
||||
bool startDebuggerServer(const QString &packageDir, const QString &gdbServerPrefix,
|
||||
const QString &gdbServerExecutable, QString *errorStr = nullptr);
|
||||
|
||||
enum class JDBState {
|
||||
Idle,
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user