2022-08-19 15:59:36 +02:00
|
|
|
// Copyright (C) 2016 BogDan Vatra <bog_dan_ro@yahoo.com>
|
|
|
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
2012-04-18 20:30:57 +03:00
|
|
|
|
|
|
|
|
#include "androiddebugsupport.h"
|
|
|
|
|
|
2018-12-05 10:29:48 +01:00
|
|
|
#include "androidconstants.h"
|
2012-04-18 20:30:57 +03:00
|
|
|
#include "androidrunner.h"
|
2012-04-24 15:49:09 +02:00
|
|
|
#include "androidmanager.h"
|
2019-02-18 11:18:05 +01:00
|
|
|
#include "androidqtversion.h"
|
2012-04-18 20:30:57 +03:00
|
|
|
|
2012-09-03 18:31:44 +02:00
|
|
|
#include <debugger/debuggerkitinformation.h>
|
2013-03-27 13:03:15 +01:00
|
|
|
#include <debugger/debuggerrunconfigurationaspect.h>
|
2012-04-18 20:30:57 +03:00
|
|
|
|
2014-06-24 16:47:38 +02:00
|
|
|
#include <projectexplorer/project.h>
|
2018-12-05 10:29:48 +01:00
|
|
|
#include <projectexplorer/projectnodes.h>
|
2012-04-24 15:49:09 +02:00
|
|
|
#include <projectexplorer/target.h>
|
2013-03-25 17:13:18 +01:00
|
|
|
#include <projectexplorer/toolchain.h>
|
2014-06-24 16:47:38 +02:00
|
|
|
|
2012-09-03 18:31:44 +02:00
|
|
|
#include <qtsupport/qtkitinformation.h>
|
2012-04-18 20:30:57 +03:00
|
|
|
|
2022-11-16 14:33:11 +01:00
|
|
|
#include <utils/fileutils.h>
|
2016-04-19 14:01:44 +02:00
|
|
|
#include <utils/hostosinfo.h>
|
|
|
|
|
|
2018-07-05 08:13:08 +02:00
|
|
|
#include <QHostAddress>
|
2018-12-05 10:29:48 +01:00
|
|
|
#include <QJsonDocument>
|
|
|
|
|
#include <QLoggingCategory>
|
2018-06-18 11:49:14 +02:00
|
|
|
|
|
|
|
|
namespace {
|
2020-01-15 14:39:23 +01:00
|
|
|
static Q_LOGGING_CATEGORY(androidDebugSupportLog, "qtc.android.run.androiddebugsupport", QtWarningMsg)
|
2018-06-18 11:49:14 +02:00
|
|
|
}
|
2012-04-18 20:30:57 +03:00
|
|
|
|
|
|
|
|
using namespace Debugger;
|
|
|
|
|
using namespace ProjectExplorer;
|
2020-05-13 08:39:37 +02:00
|
|
|
using namespace Utils;
|
2012-04-18 20:30:57 +03:00
|
|
|
|
|
|
|
|
namespace Android {
|
|
|
|
|
namespace Internal {
|
|
|
|
|
|
2022-11-16 14:33:11 +01:00
|
|
|
static FilePaths getSoLibSearchPath(const ProjectNode *node)
|
2018-12-05 10:29:48 +01:00
|
|
|
{
|
|
|
|
|
if (!node)
|
|
|
|
|
return {};
|
|
|
|
|
|
2022-11-16 14:33:11 +01:00
|
|
|
FilePaths res;
|
2018-12-18 17:52:19 +01:00
|
|
|
node->forEachProjectNode([&res](const ProjectNode *node) {
|
2022-11-16 14:33:11 +01:00
|
|
|
const QStringList paths = node->data(Constants::AndroidSoLibPath).toStringList();
|
|
|
|
|
res.append(Utils::transform(paths, &FilePath::fromUserInput));
|
2018-12-05 10:29:48 +01:00
|
|
|
});
|
|
|
|
|
|
2022-11-16 14:33:11 +01:00
|
|
|
const FilePath jsonFile = AndroidQtVersion::androidDeploymentSettings(
|
|
|
|
|
node->getProject()->activeTarget());
|
|
|
|
|
FileReader reader;
|
|
|
|
|
if (reader.fetch(jsonFile)) {
|
2018-12-05 10:29:48 +01:00
|
|
|
QJsonParseError error;
|
2022-11-16 14:33:11 +01:00
|
|
|
QJsonDocument doc = QJsonDocument::fromJson(reader.data(), &error);
|
2018-12-05 10:29:48 +01:00
|
|
|
if (error.error == QJsonParseError::NoError) {
|
|
|
|
|
auto rootObj = doc.object();
|
|
|
|
|
auto it = rootObj.find("stdcpp-path");
|
|
|
|
|
if (it != rootObj.constEnd())
|
2022-11-16 14:33:11 +01:00
|
|
|
res.append(FilePath::fromUserInput(it.value().toString()));
|
2018-12-05 10:29:48 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-16 14:33:11 +01:00
|
|
|
FilePath::removeDuplicates(res);
|
2018-12-05 10:29:48 +01:00
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-16 14:33:11 +01:00
|
|
|
static FilePaths getExtraLibs(const ProjectNode *node)
|
2018-12-05 10:29:48 +01:00
|
|
|
{
|
|
|
|
|
if (!node)
|
|
|
|
|
return {};
|
2022-11-16 14:33:11 +01:00
|
|
|
|
|
|
|
|
const QStringList paths = node->data(Constants::AndroidExtraLibs).toStringList();
|
|
|
|
|
FilePaths res = Utils::transform(paths, &FilePath::fromUserInput);
|
|
|
|
|
|
|
|
|
|
FilePath::removeDuplicates(res);
|
|
|
|
|
return res;
|
2018-12-05 10:29:48 +01:00
|
|
|
}
|
|
|
|
|
|
2018-08-02 11:00:06 +02:00
|
|
|
AndroidDebugSupport::AndroidDebugSupport(RunControl *runControl, const QString &intentName)
|
2017-05-19 14:40:49 +02:00
|
|
|
: Debugger::DebuggerRunTool(runControl)
|
2012-04-18 20:30:57 +03:00
|
|
|
{
|
2018-08-21 08:28:27 +02:00
|
|
|
setId("AndroidDebugger");
|
2020-04-15 09:01:38 +02:00
|
|
|
setLldbPlatform("remote-android");
|
2018-08-02 11:00:06 +02:00
|
|
|
m_runner = new AndroidRunner(runControl, intentName);
|
2017-08-08 14:09:50 +02:00
|
|
|
addStartDependency(m_runner);
|
2017-05-19 14:40:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AndroidDebugSupport::start()
|
|
|
|
|
{
|
Avoid some visible uses of RunControl::runConfiguration()
For a long time, probably from the very beginning, a RunControl
was meant to hold (a copy of) data needed for its operation, that was
valid at the time of its construction, to be resilient in cases
where RunConfiguration setting were changed while the RunControl
was running, or to properly re-run with the original settings.
Unfortunately, the task was repetitive, as RunConfiguration
classes had no generic access to properties / "aspects"
and there was was the runConfiguration() accessor (probably
for mostly unrelated reasons in the output pane handling) which
made the idea of just casting that to the original runConfiguration
and access the data directly there appealing, with all the
expected consequences.
This patch here partially addresses the issue by copying some
more of the related data at RunControl construction time and
adjust the using code, avoiding most uses of the runConfiguration()
accessor in a mostly mechanical matter.
Complete removal appears possible, but will be less mechanical
in "difficult" plugins like ios, so this is left for later.
The new accessors in RunControl are very much ad-hoc, leaving
room for improvement, e.g. by consolidating the access to the
run config settings aspects with the other runconfig aspects
or similar. For now the goal is to remove the runConfiguration()
accessor, and to as much as possible fixed data after RunControl
setup is finished.
Next step would be to officially allow construction of RunControls
without a specific RunConfiguration by setting the necessary
data independently, removing the need for the various workarounds
that are currently used for the purpose of faking (parts of) the
effect of the non-existing RunConfiguration or refusing to operate
at all, even if it would be possible.
Change-Id: If8e5596da8422c70e90f97270389adbe6d0b46f2
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
2019-03-11 15:42:43 +01:00
|
|
|
Target *target = runControl()->target();
|
2017-05-19 14:40:49 +02:00
|
|
|
Kit *kit = target->kit();
|
2012-08-14 15:52:17 +02:00
|
|
|
|
2017-08-24 16:53:53 +02:00
|
|
|
setStartMode(AttachToRemoteServer);
|
2018-06-18 11:49:14 +02:00
|
|
|
const QString packageName = AndroidManager::packageName(target);
|
|
|
|
|
setRunControlName(packageName);
|
2017-08-24 16:53:53 +02:00
|
|
|
setUseContinueInsteadOfRun(true);
|
|
|
|
|
setAttachPid(m_runner->pid());
|
|
|
|
|
|
2022-01-21 16:06:36 +01:00
|
|
|
QtSupport::QtVersion *qtVersion = QtSupport::QtKitAspect::qtVersion(kit);
|
2020-02-24 10:56:57 +01:00
|
|
|
if (!Utils::HostOsInfo::isWindowsHost()
|
|
|
|
|
&& (qtVersion
|
|
|
|
|
&& AndroidConfigurations::currentConfig().ndkVersion(qtVersion)
|
|
|
|
|
>= QVersionNumber(11, 0, 0))) {
|
2018-06-18 11:49:14 +02:00
|
|
|
qCDebug(androidDebugSupportLog) << "UseTargetAsync: " << true;
|
2017-08-24 16:53:53 +02:00
|
|
|
setUseTargetAsync(true);
|
2017-05-05 12:26:23 +02:00
|
|
|
}
|
2012-06-24 19:32:45 -07:00
|
|
|
|
2017-05-19 14:40:49 +02:00
|
|
|
if (isCppDebugging()) {
|
2018-06-18 11:49:14 +02:00
|
|
|
qCDebug(androidDebugSupportLog) << "C++ debugging enabled";
|
2019-03-13 17:44:13 +01:00
|
|
|
const ProjectNode *node = target->project()->findNodeForBuildKey(runControl()->buildKey());
|
2022-11-16 14:33:11 +01:00
|
|
|
FilePaths solibSearchPath = getSoLibSearchPath(node);
|
2019-08-30 11:09:59 +02:00
|
|
|
if (qtVersion)
|
|
|
|
|
solibSearchPath.append(qtVersion->qtSoPaths());
|
2022-11-16 14:33:11 +01:00
|
|
|
const FilePaths extraLibs = getExtraLibs(node);
|
|
|
|
|
solibSearchPath.append(extraLibs);
|
2021-08-23 21:36:55 +03:00
|
|
|
|
2022-06-22 15:15:48 +03:00
|
|
|
FilePath buildDir = AndroidManager::buildDirectory(target);
|
2021-08-23 21:36:55 +03:00
|
|
|
const RunConfiguration *activeRunConfig = target->activeRunConfiguration();
|
|
|
|
|
if (activeRunConfig)
|
2022-11-16 14:33:11 +01:00
|
|
|
solibSearchPath.append(activeRunConfig->buildTargetInfo().workingDirectory);
|
|
|
|
|
solibSearchPath.append(buildDir);
|
|
|
|
|
const FilePath androidLibsPath = AndroidManager::androidBuildDirectory(target)
|
2022-06-23 10:26:34 +03:00
|
|
|
.pathAppended("libs")
|
2022-11-16 14:33:11 +01:00
|
|
|
.pathAppended(AndroidManager::apkDevicePreferredAbi(target));
|
2022-06-23 10:26:34 +03:00
|
|
|
solibSearchPath.append(androidLibsPath);
|
2022-11-16 14:33:11 +01:00
|
|
|
FilePath::removeDuplicates(solibSearchPath);
|
2017-08-24 16:53:53 +02:00
|
|
|
setSolibSearchPath(solibSearchPath);
|
2022-07-06 18:02:52 +02:00
|
|
|
qCDebug(androidDebugSupportLog).noquote() << "SoLibSearchPath: " << solibSearchPath;
|
2021-08-23 21:36:55 +03:00
|
|
|
setSymbolFile(buildDir.pathAppended("app_process"));
|
2017-08-24 16:53:53 +02:00
|
|
|
setSkipExecutableValidation(true);
|
|
|
|
|
setUseExtendedRemote(true);
|
2019-12-03 09:26:05 +02:00
|
|
|
QString devicePreferredAbi = AndroidManager::apkDevicePreferredAbi(target);
|
2019-08-26 14:19:07 +03:00
|
|
|
setAbi(AndroidManager::androidAbi2Abi(devicePreferredAbi));
|
2020-05-13 08:39:37 +02:00
|
|
|
|
|
|
|
|
if (cppEngineType() == LldbEngineType) {
|
2022-10-20 16:15:02 +02:00
|
|
|
QString deviceSerialNumber = AndroidManager::deviceSerialNumber(target);
|
|
|
|
|
const int colonPos = deviceSerialNumber.indexOf(QLatin1Char(':'));
|
|
|
|
|
if (colonPos > 0) {
|
|
|
|
|
// When wireless debugging is used then the device serial number will include a port number
|
|
|
|
|
// The port number must be removed to form a valid hostname
|
|
|
|
|
deviceSerialNumber.truncate(colonPos);
|
|
|
|
|
}
|
|
|
|
|
setRemoteChannel("adb://" + deviceSerialNumber,
|
2021-12-15 20:13:33 +01:00
|
|
|
m_runner->debugServerPort().number());
|
2020-05-13 08:39:37 +02:00
|
|
|
} else {
|
2021-12-15 20:13:33 +01:00
|
|
|
QUrl debugServer;
|
|
|
|
|
debugServer.setPort(m_runner->debugServerPort().number());
|
2020-05-13 08:39:37 +02:00
|
|
|
debugServer.setHost(QHostAddress(QHostAddress::LocalHost).toString());
|
|
|
|
|
setRemoteChannel(debugServer);
|
|
|
|
|
}
|
2018-06-18 11:49:14 +02:00
|
|
|
|
2019-02-18 11:18:05 +01:00
|
|
|
auto qt = static_cast<AndroidQtVersion *>(qtVersion);
|
|
|
|
|
const int minimumNdk = qt ? qt->minimumNDK() : 0;
|
|
|
|
|
|
Avoid some visible uses of RunControl::runConfiguration()
For a long time, probably from the very beginning, a RunControl
was meant to hold (a copy of) data needed for its operation, that was
valid at the time of its construction, to be resilient in cases
where RunConfiguration setting were changed while the RunControl
was running, or to properly re-run with the original settings.
Unfortunately, the task was repetitive, as RunConfiguration
classes had no generic access to properties / "aspects"
and there was was the runConfiguration() accessor (probably
for mostly unrelated reasons in the output pane handling) which
made the idea of just casting that to the original runConfiguration
and access the data directly there appealing, with all the
expected consequences.
This patch here partially addresses the issue by copying some
more of the related data at RunControl construction time and
adjust the using code, avoiding most uses of the runConfiguration()
accessor in a mostly mechanical matter.
Complete removal appears possible, but will be less mechanical
in "difficult" plugins like ios, so this is left for later.
The new accessors in RunControl are very much ad-hoc, leaving
room for improvement, e.g. by consolidating the access to the
run config settings aspects with the other runconfig aspects
or similar. For now the goal is to remove the runConfiguration()
accessor, and to as much as possible fixed data after RunControl
setup is finished.
Next step would be to officially allow construction of RunControls
without a specific RunConfiguration by setting the necessary
data independently, removing the need for the various workarounds
that are currently used for the purpose of faking (parts of) the
effect of the non-existing RunConfiguration or refusing to operate
at all, even if it would be possible.
Change-Id: If8e5596da8422c70e90f97270389adbe6d0b46f2
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
2019-03-11 15:42:43 +01:00
|
|
|
int sdkVersion = qMax(AndroidManager::minimumSDK(kit), minimumNdk);
|
2020-02-24 10:56:57 +01:00
|
|
|
if (qtVersion) {
|
2021-12-31 21:01:46 +01:00
|
|
|
const FilePath ndkLocation =
|
|
|
|
|
AndroidConfigurations::currentConfig().ndkLocation(qtVersion);
|
|
|
|
|
Utils::FilePath sysRoot = ndkLocation
|
2020-02-19 17:35:56 +01:00
|
|
|
/ "platforms"
|
|
|
|
|
/ QString("android-%1").arg(sdkVersion)
|
2021-12-31 21:01:46 +01:00
|
|
|
/ devicePreferredAbi; // Legacy Ndk structure
|
|
|
|
|
if (!sysRoot.exists())
|
|
|
|
|
sysRoot = AndroidConfig::toolchainPathFromNdk(ndkLocation) / "sysroot";
|
2020-02-24 10:56:57 +01:00
|
|
|
setSysRoot(sysRoot);
|
2022-07-06 18:02:52 +02:00
|
|
|
qCDebug(androidDebugSupportLog).noquote() << "Sysroot: " << sysRoot.toUserOutput();
|
2020-02-24 10:56:57 +01:00
|
|
|
}
|
2012-06-24 19:32:45 -07:00
|
|
|
}
|
2017-05-19 14:40:49 +02:00
|
|
|
if (isQmlDebugging()) {
|
2018-06-18 11:49:14 +02:00
|
|
|
qCDebug(androidDebugSupportLog) << "QML debugging enabled. QML server: "
|
|
|
|
|
<< m_runner->qmlServer().toDisplayString();
|
2017-08-24 16:53:53 +02:00
|
|
|
setQmlServer(m_runner->qmlServer());
|
2012-06-24 19:32:45 -07:00
|
|
|
//TODO: Not sure if these are the right paths.
|
2017-08-24 16:53:53 +02:00
|
|
|
if (qtVersion)
|
2018-08-21 19:03:46 +02:00
|
|
|
addSearchDirectory(qtVersion->qmlPath());
|
2012-06-24 19:32:45 -07:00
|
|
|
}
|
2012-04-18 20:30:57 +03:00
|
|
|
|
2020-07-01 18:10:02 +03:00
|
|
|
qCDebug(androidDebugSupportLog) << "Starting debugger - package name: " << packageName
|
|
|
|
|
<< ", PID: " << m_runner->pid().pid();
|
2017-05-19 14:40:49 +02:00
|
|
|
DebuggerRunTool::start();
|
2013-02-27 15:12:36 +01:00
|
|
|
}
|
|
|
|
|
|
2017-05-19 14:40:49 +02:00
|
|
|
void AndroidDebugSupport::stop()
|
2012-04-18 20:30:57 +03:00
|
|
|
{
|
2018-06-18 11:49:14 +02:00
|
|
|
qCDebug(androidDebugSupportLog) << "Stop";
|
2017-05-19 14:40:49 +02:00
|
|
|
DebuggerRunTool::stop();
|
2012-04-18 20:30:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace Internal
|
2012-08-09 01:56:51 +02:00
|
|
|
} // namespace Android
|