Merge remote-tracking branch 'origin/4.8'

Change-Id: I5b18233936e3b2cd674df92a694ba73b5a3ed752
This commit is contained in:
Orgad Shaneh
2018-12-02 22:07:22 +02:00
28 changed files with 242 additions and 70 deletions

View File

@@ -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();

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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,

View File

@@ -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