ProjectExplorer: Reduce use of Runnable in SimpleTargetRunner

Runnable functionality is nowadays mostly accessed more directly
in QtcProcess and its setup functions.

Change-Id: I2a2b5433aef1d464dc58d5a35069376dee051d57
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
This commit is contained in:
hjk
2022-05-23 16:09:43 +02:00
parent ae42604904
commit f79a71df7b
13 changed files with 123 additions and 110 deletions

View File

@@ -199,11 +199,9 @@ RunWorker *GdbServerProvider::targetRunner(RunControl *runControl) const
if (m_startupMode != GdbServerProvider::StartupOnNetwork)
return nullptr;
Runnable r;
r.command = command();
// Command arguments are in host OS style as the bare metal's GDB servers are launched
// on the host, not on that target.
return new GdbServerProviderRunner(runControl, r);
return new GdbServerProviderRunner(runControl, command());
}
bool GdbServerProvider::fromMap(const QVariantMap &data)
@@ -341,14 +339,15 @@ QString GdbServerProviderConfigWidget::defaultResetCommandsTooltip()
// GdbServerProviderRunner
GdbServerProviderRunner::GdbServerProviderRunner(ProjectExplorer::RunControl *runControl,
const ProjectExplorer::Runnable &runnable)
const Utils::CommandLine &commandLine)
: SimpleTargetRunner(runControl)
{
setId("BareMetalGdbServer");
// Baremetal's GDB servers are launched on the host, not on the target.
Runnable devicelessRunnable = runnable;
devicelessRunnable.device.reset();
setStarter([this, devicelessRunnable] { doStart(devicelessRunnable); });
setStartModifier([this, commandLine] {
setCommandLine(commandLine);
forceRunOnHost();
});
}
} // namespace Internal

View File

@@ -126,7 +126,7 @@ class GdbServerProviderRunner final : public ProjectExplorer::SimpleTargetRunner
{
public:
explicit GdbServerProviderRunner(ProjectExplorer::RunControl *runControl,
const ProjectExplorer::Runnable &runnable);
const Utils::CommandLine &commandLine);
};
} // namespace Internal

View File

@@ -142,13 +142,11 @@ public:
QdbDeviceRunSupport(RunControl *runControl)
: SimpleTargetRunner(runControl)
{
setStarter([this, runControl] {
Runnable r = runControl->runnable();
// FIXME: Spaces!
r.command.setArguments(r.command.executable().toString() + ' ' + r.command.arguments());
r.command.setExecutable(FilePath::fromString(Constants::AppcontrollerFilepath));
r.device = runControl->device();
doStart(r);
setStartModifier([this] {
CommandLine cmd;
cmd.setExecutable(FilePath::fromString(Constants::AppcontrollerFilepath));
cmd.addCommandLineAsArgs(commandLine());
setCommandLine(cmd);
});
}
};

View File

@@ -1042,35 +1042,31 @@ DebugServerRunner::DebugServerRunner(RunControl *runControl, DebugServerPortsGat
: SimpleTargetRunner(runControl)
{
setId("DebugServerRunner");
const Runnable mainRunnable = runControl->runnable();
addStartDependency(portsGatherer);
QTC_ASSERT(portsGatherer, reportFailure(); return);
setStarter([this, runControl, mainRunnable, portsGatherer] {
setStartModifier([this, runControl, portsGatherer] {
QTC_ASSERT(portsGatherer, reportFailure(); return);
Runnable debugServer;
debugServer.environment = mainRunnable.environment;
debugServer.workingDirectory = mainRunnable.workingDirectory;
QStringList args = ProcessArgs::splitArgs(mainRunnable.command.arguments(), OsTypeLinux);
const bool isQmlDebugging = portsGatherer->useQmlServer();
const bool isCppDebugging = portsGatherer->useGdbServer();
CommandLine cmd;
QStringList args = ProcessArgs::splitArgs(commandLine().arguments(), OsTypeLinux);
if (isQmlDebugging) {
args.prepend(QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices,
portsGatherer->qmlServer()));
}
if (isQmlDebugging && !isCppDebugging) {
debugServer.command.setExecutable(mainRunnable.command.executable()); // FIXME: Case should not happen?
cmd.setExecutable(commandLine().executable()); // FIXME: Case should not happen?
} else {
debugServer.command.setExecutable(runControl->device()->debugServerPath());
if (debugServer.command.isEmpty())
debugServer.command.setExecutable("gdbserver");
cmd.setExecutable(runControl->device()->debugServerPath());
if (cmd.isEmpty())
cmd.setExecutable("gdbserver");
args.clear();
if (debugServer.command.executable().toString().contains("lldb-server")) {
if (cmd.executable().toString().contains("lldb-server")) {
args.append("platform");
args.append("--listen");
args.append(QString("*:%1").arg(portsGatherer->gdbServer().port()));
@@ -1086,9 +1082,9 @@ DebugServerRunner::DebugServerRunner(RunControl *runControl, DebugServerPortsGat
args.append(QString::number(m_pid.pid()));
}
}
debugServer.command.setArguments(ProcessArgs::joinArgs(args, OsTypeLinux));
debugServer.device = runControl->device();
doStart(debugServer);
cmd.setArguments(ProcessArgs::joinArgs(args, OsTypeLinux));
setCommandLine(cmd);
});
}

View File

@@ -88,15 +88,12 @@ public:
FlashAndRunWorker(RunControl *runControl)
: SimpleTargetRunner(runControl)
{
setStarter([this, runControl] {
setStartModifier([this, runControl] {
const Target *target = runControl->target();
Runnable r;
r.command = {cmakeFilePath(target),
runControl->aspect<StringAspect>()->value,
CommandLine::Raw};
r.workingDirectory = target->activeBuildConfiguration()->buildDirectory();
r.environment = target->activeBuildConfiguration()->environment();
SimpleTargetRunner::doStart(r);
setCommandLine({cmakeFilePath(target), runControl->aspect<StringAspect>()->value,
CommandLine::Raw});
setWorkingDirectory(target->activeBuildConfiguration()->buildDirectory());
setEnvironment(target->activeBuildConfiguration()->environment());
});
}
};

View File

@@ -1246,7 +1246,7 @@ public:
ProcessResultData m_resultData;
std::function<void()> m_starter;
std::function<void()> m_startModifier;
bool m_stopReported = false;
bool m_stopForced = false;
@@ -1481,17 +1481,6 @@ SimpleTargetRunner::SimpleTargetRunner(RunControl *runControl)
SimpleTargetRunner::~SimpleTargetRunner() = default;
void SimpleTargetRunner::start()
{
if (d->m_starter) {
d->m_starter();
} else {
Runnable runnable = runControl()->runnable();
runnable.device = runControl()->device();
doStart(runnable);
}
}
void SimpleTargetRunnerPrivate::forwardDone()
{
if (m_stopReported)
@@ -1523,8 +1512,14 @@ void SimpleTargetRunnerPrivate::forwardStarted()
q->reportStarted();
}
void SimpleTargetRunner::doStart(const Runnable &runnable)
void SimpleTargetRunner::start()
{
d->m_runnable = runControl()->runnable();
d->m_runnable.device = runControl()->device();
if (d->m_startModifier)
d->m_startModifier();
bool useTerminal = false;
if (auto terminalAspect = runControl()->aspect<TerminalAspect>())
useTerminal = terminalAspect->useTerminal;
@@ -1539,16 +1534,15 @@ void SimpleTargetRunner::doStart(const Runnable &runnable)
d->m_process.setTerminalMode(useTerminal ? Utils::TerminalMode::On : Utils::TerminalMode::Off);
d->m_runAsRoot = runAsRoot;
const QString msg = RunControl::tr("Starting %1...").arg(runnable.command.toUserOutput());
const QString msg = RunControl::tr("Starting %1...").arg(d->m_runnable.command.toUserOutput());
appendMessage(msg, Utils::NormalMessageFormat);
const bool isDesktop = runnable.device.isNull()
|| runnable.device.dynamicCast<const DesktopDevice>();
if (isDesktop && runnable.command.isEmpty()) {
const bool isDesktop = d->m_runnable.device.isNull()
|| d->m_runnable.device.dynamicCast<const DesktopDevice>();
if (isDesktop && d->m_runnable.command.isEmpty()) {
reportFailure(RunControl::tr("No executable specified."));
return;
}
d->m_runnable = runnable;
d->start();
}
@@ -1558,11 +1552,40 @@ void SimpleTargetRunner::stop()
d->stop();
}
void SimpleTargetRunner::setStarter(const std::function<void ()> &starter)
void SimpleTargetRunner::setStartModifier(const std::function<void ()> &startModifier)
{
d->m_starter = starter;
d->m_startModifier = startModifier;
}
CommandLine SimpleTargetRunner::commandLine() const
{
return d->m_runnable.command;
}
void SimpleTargetRunner::setCommandLine(const Utils::CommandLine &commandLine)
{
d->m_runnable.command = commandLine;
}
void SimpleTargetRunner::setEnvironment(const Environment &environment)
{
d->m_runnable.environment = environment;
}
void SimpleTargetRunner::setWorkingDirectory(const FilePath &workingDirectory)
{
d->m_runnable.workingDirectory = workingDirectory;
}
void SimpleTargetRunner::forceRunOnHost()
{
d->m_runnable.device = {};
const FilePath executable = d->m_runnable.command.executable();
if (executable.needsDevice()) {
QTC_CHECK(false);
d->m_runnable.command.setExecutable(FilePath::fromString(executable.path()));
}
}
// RunWorkerPrivate

View File

@@ -298,14 +298,22 @@ public:
~SimpleTargetRunner() override;
protected:
void setStarter(const std::function<void()> &starter);
void doStart(const Runnable &runnable);
void setStartModifier(const std::function<void()> &startModifier);
Utils::CommandLine commandLine() const;
void setCommandLine(const Utils::CommandLine &commandLine);
void setEnvironment(const Utils::Environment &environment);
void setWorkingDirectory(const Utils::FilePath &workingDirectory);
void forceRunOnHost();
private:
void start() final;
void stop() final;
const Runnable &runnable() const = delete;
void setRunnable(const Runnable &) = delete;
const std::unique_ptr<Internal::SimpleTargetRunnerPrivate> d;
};

View File

@@ -41,6 +41,8 @@
#include <utils/url.h>
#include <utils/fileutils.h>
using namespace Utils;
namespace QmlPreview {
static const QString QmlServerUrl = "QmlServerUrl";
@@ -126,9 +128,10 @@ LocalQmlPreviewSupport::LocalQmlPreviewSupport(ProjectExplorer::RunControl *runC
addStopDependency(preview);
addStartDependency(preview);
setStarter([this, runControl, serverUrl] {
ProjectExplorer::Runnable runnable = runControl->runnable();
QStringList qmlProjectRunConfigurationArguments = runnable.command.splitArguments();
setStartModifier([this, runControl, serverUrl] {
CommandLine cmd = commandLine();
QStringList qmlProjectRunConfigurationArguments = cmd.splitArguments();
const auto currentTarget = runControl->target();
const auto *qmlBuildSystem = qobject_cast<QmlProjectManager::QmlBuildSystem *>(currentTarget->buildSystem());
@@ -142,15 +145,15 @@ LocalQmlPreviewSupport::LocalQmlPreviewSupport(ProjectExplorer::RunControl *runC
if (!currentFile.isEmpty() && qmlProjectRunConfigurationArguments.last().contains(mainScriptFromProject)) {
qmlProjectRunConfigurationArguments.removeLast();
runnable.command = Utils::CommandLine(runnable.command.executable(), qmlProjectRunConfigurationArguments);
runnable.command.addArg(currentFile);
cmd = Utils::CommandLine(cmd.executable(), qmlProjectRunConfigurationArguments);
cmd.addArg(currentFile);
}
}
runnable.command.addArg(QmlDebug::qmlDebugLocalArguments(QmlDebug::QmlPreviewServices,
serverUrl.path()));
runnable.device.reset();
doStart(runnable);
cmd.addArg(QmlDebug::qmlDebugLocalArguments(QmlDebug::QmlPreviewServices, serverUrl.path()));
setCommandLine(cmd);
forceRunOnHost();
});
}

View File

@@ -25,7 +25,6 @@
#include "qmlprofilerruncontrol.h"
#include "qmlprofilerclientmanager.h"
#include "qmlprofilertool.h"
#include <coreplugin/icore.h>
@@ -236,8 +235,7 @@ LocalQmlProfilerSupport::LocalQmlProfilerSupport(RunControl *runControl, const Q
// In the TCP case, it doesn't hurt either to start the profiler before.
addStartDependency(profiler);
setStarter([this, runControl, profiler, serverUrl] {
Runnable debuggee = runControl->runnable();
setStartModifier([this, profiler, serverUrl] {
QUrl serverUrl = profiler->serverUrl();
QString code;
@@ -251,12 +249,13 @@ LocalQmlProfilerSupport::LocalQmlProfilerSupport(RunControl *runControl, const Q
QString arguments = Utils::ProcessArgs::quoteArg(
QmlDebug::qmlDebugCommandLineArguments(QmlDebug::QmlProfilerServices, code, true));
if (!debuggee.command.arguments().isEmpty())
arguments += ' ' + debuggee.command.arguments();
Utils::CommandLine cmd = commandLine();
const QString oldArgs = cmd.arguments();
cmd.setArguments(arguments);
cmd.addArgs(oldArgs, Utils::CommandLine::Raw);
setCommandLine(cmd);
debuggee.command.setArguments(arguments);
debuggee.device.reset();
doStart(debuggee);
forceRunOnHost();
});
}

View File

@@ -56,14 +56,13 @@ QnxQmlProfilerSupport::QnxQmlProfilerSupport(RunControl *runControl)
profiler->addStartDependency(this);
addStopDependency(profiler);
setStarter([this, runControl, portsGatherer, profiler] {
setStartModifier([this, portsGatherer, profiler] {
const QUrl serverUrl = portsGatherer->findEndPoint();
profiler->recordData("QmlServerUrl", serverUrl);
Runnable r = runControl->runnable();
r.command.addArg(QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlProfilerServices, serverUrl));
r.device = runControl->device();
doStart(r);
CommandLine cmd = commandLine();
cmd.addArg(QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlProfilerServices, serverUrl));
setCommandLine(cmd);
});
}

View File

@@ -26,11 +26,9 @@
#include "qnxdebugsupport.h"
#include "qnxconstants.h"
#include "qnxdevice.h"
#include "qnxrunconfiguration.h"
#include "slog2inforunner.h"
#include "qnxqtversion.h"
#include "qnxutils.h"
#include <coreplugin/icore.h>
@@ -103,21 +101,21 @@ public:
{
setId("QnxDebuggeeRunner");
setStarter([this, runControl, portsGatherer] {
Runnable r = runControl->runnable();
setStartModifier([this, portsGatherer] {
CommandLine cmd = commandLine();
QStringList arguments;
if (portsGatherer->useGdbServer()) {
int pdebugPort = portsGatherer->gdbServer().port();
r.command.setExecutable(FilePath::fromString(QNX_DEBUG_EXECUTABLE));
cmd.setExecutable(FilePath::fromString(QNX_DEBUG_EXECUTABLE));
arguments.append(QString::number(pdebugPort));
}
if (portsGatherer->useQmlServer()) {
arguments.append(QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices,
portsGatherer->qmlServer()));
}
r.command.setArguments(ProcessArgs::joinArgs(arguments));
r.device = runControl->device();
doStart(r);
cmd.setArguments(ProcessArgs::joinArgs(arguments));
setCommandLine(cmd);
});
}
};
@@ -197,13 +195,9 @@ public:
setId("PDebugRunner");
addStartDependency(portsGatherer);
setStarter([this, runControl, portsGatherer] {
setStartModifier([this, portsGatherer] {
const int pdebugPort = portsGatherer->gdbServer().port();
Runnable r;
r.command = {QNX_DEBUG_EXECUTABLE, {QString::number(pdebugPort)}};
r.device = runControl->device();
doStart(r);
setCommandLine({QNX_DEBUG_EXECUTABLE, {QString::number(pdebugPort)}});
});
}
};

View File

@@ -51,16 +51,15 @@ RemoteLinuxQmlToolingSupport::RemoteLinuxQmlToolingSupport(RunControl *runContro
runworker->addStartDependency(this);
addStopDependency(runworker);
setStarter([this, runControl, portsGatherer, runworker] {
setStartModifier([this, runControl, portsGatherer, runworker] {
const QUrl serverUrl = portsGatherer->findEndPoint();
runworker->recordData("QmlServerUrl", serverUrl);
QmlDebug::QmlDebugServicesPreset services = QmlDebug::servicesForRunMode(runControl->runMode());
Runnable r = runControl->runnable();
r.command.addArg(QmlDebug::qmlDebugTcpArguments(services, serverUrl));
r.device = runControl->device();
doStart(r);
CommandLine cmd = commandLine();
cmd.addArg(QmlDebug::qmlDebugTcpArguments(services, serverUrl));
setCommandLine(cmd);
});
}

View File

@@ -120,16 +120,14 @@ public:
auto portsGatherer = new PortsGatherer(runControl);
addStartDependency(portsGatherer);
setStarter([this, runControl, portsGatherer] {
Runnable r;
setStartModifier([this, runControl, portsGatherer] {
const QString browserId =
runControl->aspect<WebBrowserSelectionAspect>()->currentBrowser;
r.command = emrunCommand(runControl->target(),
runControl->buildKey(),
browserId,
QString::number(portsGatherer->findEndPoint().port()));
r.environment = runControl->buildEnvironment();
SimpleTargetRunner::doStart(r);
setCommandLine(emrunCommand(runControl->target(),
runControl->buildKey(),
browserId,
QString::number(portsGatherer->findEndPoint().port())));
setEnvironment(runControl->buildEnvironment());
});
}
};