AppMan: Add support for qmlprofiling and qmlpreview

Change-Id: I9142489f99288c4313495f14602a8c4b42776c65
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Dominik Holland
2024-01-11 14:20:16 +01:00
committed by hjk
parent 75ac93db00
commit a9b3e8a852
3 changed files with 154 additions and 60 deletions

View File

@@ -27,6 +27,7 @@ public:
AppManagerRunConfigurationFactory runConfigFactory; AppManagerRunConfigurationFactory runConfigFactory;
AppManagerRunWorkerFactory runWorkerFactory; AppManagerRunWorkerFactory runWorkerFactory;
AppManagerDebugWorkerFactory debugWorkerFactory; AppManagerDebugWorkerFactory debugWorkerFactory;
AppManagerQmlToolingWorkerFactory toolingWorkerFactory;
}; };
AppManagerPlugin::~AppManagerPlugin() AppManagerPlugin::~AppManagerPlugin()

View File

@@ -28,6 +28,7 @@
#include <qtsupport/baseqtversion.h> #include <qtsupport/baseqtversion.h>
#include <qtsupport/qtkitaspect.h> #include <qtsupport/qtkitaspect.h>
#include <utils/process.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
using namespace ProjectExplorer; using namespace ProjectExplorer;
@@ -65,18 +66,36 @@ public:
}; };
// AppManDebugLauncher // AppManInferiorRunner
class AppManDebugLauncher : public SimpleTargetRunner class AppManInferiorRunner : public SimpleTargetRunner
{ {
public: public:
AppManDebugLauncher(RunControl *runControl, Debugger::DebugServerPortsGatherer *portsGatherer) AppManInferiorRunner(RunControl *runControl,
: SimpleTargetRunner(runControl) bool usePerf, bool useGdbServer, bool useQmlServer,
QmlDebug::QmlDebugServicesPreset qmlServices)
: SimpleTargetRunner(runControl),
m_usePerf(usePerf), m_useGdbServer(useGdbServer), m_useQmlServer(useQmlServer),
m_qmlServices(qmlServices)
{ {
setId(AppManager::Constants::DEBUG_LAUNCHER_ID); setId(AppManager::Constants::DEBUG_LAUNCHER_ID);
QTC_ASSERT(portsGatherer, return);
setStartModifier([this, runControl, portsGatherer] { connect(&m_launcher, &Process::started, this, &RunWorker::reportStarted);
connect(&m_launcher, &Process::done, this, &RunWorker::reportStopped);
connect(&m_launcher, &Process::readyReadStandardOutput, this, [this] {
appendMessage(m_launcher.readAllStandardOutput(), StdOutFormat);
});
connect(&m_launcher, &Process::readyReadStandardError, this, [this] {
appendMessage(m_launcher.readAllStandardError(), StdErrFormat);
});
m_portsGatherer = new Debugger::DebugServerPortsGatherer(runControl);
m_portsGatherer->setUseGdbServer(useGdbServer || usePerf);
m_portsGatherer->setUseQmlServer(useQmlServer);
addStartDependency(m_portsGatherer);
setStartModifier([this, runControl] {
const auto targetInformation = TargetInformation(runControl->target()); const auto targetInformation = TargetInformation(runControl->target());
if (!targetInformation.isValid()) { if (!targetInformation.isValid()) {
@@ -84,22 +103,37 @@ public:
return; return;
} }
// const int perfPort = m_portsGatherer->gdbServer().port();
const int gdbServerPort = m_portsGatherer->gdbServer().port();
const int qmlServerPort = m_portsGatherer->qmlServer().port();
CommandLine cmd{FilePath::fromString(getToolFilePath(Constants::APPMAN_CONTROLLER, CommandLine cmd{FilePath::fromString(getToolFilePath(Constants::APPMAN_CONTROLLER,
runControl->kit(), runControl->kit(),
targetInformation.device))}; targetInformation.device))};
cmd.addArg("debug-application"); cmd.addArg("debug-application");
if (portsGatherer->useGdbServer() || portsGatherer->useQmlServer()) { if (m_useGdbServer || m_useQmlServer) {
QStringList debugArgs; QStringList debugArgs;
if (portsGatherer->useGdbServer()) { if (m_useGdbServer) {
debugArgs.append(QString("gdbserver :%1").arg(portsGatherer->gdbServer().port())); debugArgs.append(QString("gdbserver :%1").arg(gdbServerPort));
} }
if (portsGatherer->useQmlServer()) { if (m_useQmlServer) {
debugArgs.append(QString("%program% -qmljsdebugger=port:%1,block %arguments%") debugArgs.append(QString("%program% %1 %arguments%")
.arg(portsGatherer->qmlServer().port())); .arg(qmlDebugCommandLineArguments(m_qmlServices,
QString("port:%1").arg(qmlServerPort),
true)));
} }
cmd.addArg(debugArgs.join(' ')); cmd.addArg(debugArgs.join(' '));
} }
//FIXME UNTESTED CODE
if (m_usePerf) {
Store settingsData = runControl->settingsData("Analyzer.Perf.Settings");
QVariant perfRecordArgs = settingsData.value("Analyzer.Perf.RecordArguments");
QString args = Utils::transform(perfRecordArgs.toStringList(), [](QString arg) {
return arg.replace(',', ",,");
}).join(',');
cmd.addArg(QString("perf record %1 -o - --").arg(args));
}
cmd.addArg("-eio"); cmd.addArg("-eio");
cmd.addArg(targetInformation.manifest.id); cmd.addArg(targetInformation.manifest.id);
@@ -113,6 +147,18 @@ public:
appendMessage(tr("Using: %1").arg(cmd.toUserOutput()), NormalMessageFormat); appendMessage(tr("Using: %1").arg(cmd.toUserOutput()), NormalMessageFormat);
}); });
} }
QUrl perfServer() const { return m_portsGatherer->gdbServer(); }
QUrl gdbServer() const { return m_portsGatherer->gdbServer(); }
QUrl qmlServer() const { return m_portsGatherer->qmlServer(); }
private:
Debugger::DebugServerPortsGatherer *m_portsGatherer = nullptr;
bool m_usePerf;
bool m_useGdbServer;
bool m_useQmlServer;
QmlDebug::QmlDebugServicesPreset m_qmlServices;
Process m_launcher;
}; };
@@ -120,18 +166,25 @@ public:
class AppManagerDebugSupport : public Debugger::DebuggerRunTool class AppManagerDebugSupport : public Debugger::DebuggerRunTool
{ {
private:
QString m_symbolFile;
AppManInferiorRunner *m_debuggee = nullptr;
public: public:
AppManagerDebugSupport(RunControl *runControl) AppManagerDebugSupport(RunControl *runControl)
: DebuggerRunTool(runControl) : DebuggerRunTool(runControl)
{ {
setId("ApplicationManagerPlugin.Debug.Support"); setId("ApplicationManagerPlugin.Debug.Support");
setUsePortsGatherer(isCppDebugging(), isQmlDebugging()); //setUsePortsGatherer(isCppDebugging(), isQmlDebugging());
auto apmDebugLauncher = new Internal::AppManDebugLauncher(runControl, portsGatherer()); m_debuggee = new AppManInferiorRunner(runControl, false, isCppDebugging(), isQmlDebugging(),
apmDebugLauncher->addStartDependency(portsGatherer()); QmlDebug::QmlDebuggerServices);
addStartDependency(apmDebugLauncher); addStartDependency(m_debuggee);
addStopDependency(m_debuggee);
m_debuggee->addStopDependency(this);
Target *target = runControl->target(); Target *target = runControl->target();
@@ -154,63 +207,81 @@ public:
} }
private: private:
void start() override; void start() override
{
if (m_symbolFile.isEmpty()) {
reportFailure(tr("Cannot debug: Local executable is not set."));
return;
}
QString m_symbolFile; setStartMode(Debugger::AttachToRemoteServer);
setCloseMode(Debugger::KillAndExitMonitorAtClose);
if (isQmlDebugging())
setQmlServer(m_debuggee->qmlServer());
if (isCppDebugging()) {
setUseExtendedRemote(false);
setUseContinueInsteadOfRun(true);
setContinueAfterAttach(true);
setRemoteChannel(m_debuggee->gdbServer());
setSymbolFile(FilePath::fromString(m_symbolFile));
QtSupport::QtVersion *version = QtSupport::QtKitAspect::qtVersion(runControl()->kit());
if (version) {
setSolibSearchPath(version->qtSoPaths());
addSearchDirectory(version->qmlPath());
}
auto sysroot = SysRootKitAspect().sysRoot(runControl()->kit());
if (sysroot.isEmpty())
setSysRoot("/");
else
setSysRoot(sysroot);
}
DebuggerRunTool::start();
}
}; };
void AppManagerDebugSupport::start() // AppManagerQmlToolingSupport
class AppManagerQmlToolingSupport final : public RunWorker
{ {
if (m_symbolFile.isEmpty()) { public:
reportFailure(tr("Cannot debug: Local executable is not set.")); explicit AppManagerQmlToolingSupport(RunControl *runControl);
return;
}
setStartMode(Debugger::AttachToRemoteServer); private:
setCloseMode(Debugger::KillAndExitMonitorAtClose); void start() override;
ProcessRunData inferior = runControl()->runnable(); AppManInferiorRunner *m_runner = nullptr;
RunWorker *m_worker = nullptr;
};
if (isQmlDebugging()) AppManagerQmlToolingSupport::AppManagerQmlToolingSupport(RunControl *runControl)
setQmlServer(portsGatherer()->qmlServer()); : RunWorker(runControl)
{
setId("AppManagerQmlToolingSupport");
if (isCppDebugging()) { QmlDebug::QmlDebugServicesPreset services = QmlDebug::servicesForRunMode(runControl->runMode());
setUseExtendedRemote(false); m_runner = new AppManInferiorRunner(runControl, false, false, true, services);
setUseContinueInsteadOfRun(true); addStartDependency(m_runner);
inferior.command.setArguments({}); addStopDependency(m_runner);
if (isQmlDebugging()) {
inferior.command.addArg(QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices,
portsGatherer()->qmlServer()));
}
setRemoteChannel(portsGatherer()->gdbServer());
setSymbolFile(FilePath::fromString(m_symbolFile));
QtSupport::QtVersion *version = QtSupport::QtKitAspect::qtVersion(runControl()->kit()); m_worker = runControl->createWorker(QmlDebug::runnerIdForRunMode(runControl->runMode()));
if (version) { m_worker->addStartDependency(this);
setSolibSearchPath(version->qtSoPaths()); addStopDependency(m_worker);
addSearchDirectory(version->qmlPath());
}
auto sysroot = SysRootKitAspect().sysRoot(runControl()->kit());
if (sysroot.isEmpty())
setSysRoot("/");
else
setSysRoot(sysroot);
}
setInferior(inferior);
DebuggerRunTool::start();
} }
void AppManagerQmlToolingSupport::start()
{
m_worker->recordData("QmlServerUrl", m_runner->qmlServer());
reportStarted();
}
// Factories // Factories
AppManagerDebugWorkerFactory::AppManagerDebugWorkerFactory()
{
setProduct<AppManagerDebugSupport>();
addSupportedRunMode(ProjectExplorer::Constants::DEBUG_RUN_MODE);
addSupportedRunConfig(Constants::RUNCONFIGURATION_ID);
}
AppManagerRunWorkerFactory::AppManagerRunWorkerFactory() AppManagerRunWorkerFactory::AppManagerRunWorkerFactory()
{ {
setProduct<AppManagerRunner>(); setProduct<AppManagerRunner>();
@@ -218,4 +289,20 @@ AppManagerRunWorkerFactory::AppManagerRunWorkerFactory()
addSupportedRunConfig(Constants::RUNCONFIGURATION_ID); addSupportedRunConfig(Constants::RUNCONFIGURATION_ID);
} }
AppManagerDebugWorkerFactory::AppManagerDebugWorkerFactory()
{
setProduct<AppManagerDebugSupport>();
addSupportedRunMode(ProjectExplorer::Constants::DEBUG_RUN_MODE);
addSupportedRunConfig(Constants::RUNCONFIGURATION_ID);
}
AppManagerQmlToolingWorkerFactory::AppManagerQmlToolingWorkerFactory()
{
setProduct<AppManagerQmlToolingSupport>();
addSupportedRunMode(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
addSupportedRunMode(ProjectExplorer::Constants::QML_PREVIEW_RUN_MODE);
addSupportedRunConfig(Constants::RUNCONFIGURATION_ID);
}
} // AppManager::Internal } // AppManager::Internal

View File

@@ -22,5 +22,11 @@ public:
AppManagerDebugWorkerFactory(); AppManagerDebugWorkerFactory();
}; };
class AppManagerQmlToolingWorkerFactory : public ProjectExplorer::RunWorkerFactory
{
public:
AppManagerQmlToolingWorkerFactory();
};
} // namespace Internal } // namespace Internal
} // namespace AppManager } // namespace AppManager