forked from qt-creator/qt-creator
ProjectExplorer: Split Target and ToolRunners into smaller tasks
This increases re-usability of activities like 'port gathering', and makes their use less dependent on actual device implementations. Change-Id: I017cb74874f2b38c487ba2d03906a675d5618647 Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -27,8 +27,11 @@
|
||||
|
||||
#include "utils_global.h"
|
||||
#include "qtcassert.h"
|
||||
#include <limits>
|
||||
|
||||
#include <QMetaType>
|
||||
#include <QString>
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace Utils {
|
||||
|
||||
@@ -50,6 +53,8 @@ public:
|
||||
quint16 number() const { QTC_ASSERT(isValid(), return 0); return quint16(m_port); }
|
||||
bool isValid() const { return m_port != -1; }
|
||||
|
||||
QString toString() const { return QString::number(m_port); }
|
||||
|
||||
private:
|
||||
int m_port;
|
||||
};
|
||||
|
@@ -48,7 +48,8 @@ namespace Internal {
|
||||
|
||||
RunControl *AndroidAnalyzeSupport::createAnalyzeRunControl(RunConfiguration *runConfig, Core::Id runMode)
|
||||
{
|
||||
RunControl *runControl = Debugger::createAnalyzerRunControl(runConfig, runMode);
|
||||
auto runControl = new RunControl(runConfig, runMode);
|
||||
runControl->createWorker(runMode);
|
||||
QTC_ASSERT(runControl, return 0);
|
||||
AnalyzerConnection connection;
|
||||
if (runMode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) {
|
||||
@@ -64,7 +65,7 @@ RunControl *AndroidAnalyzeSupport::createAnalyzeRunControl(RunConfiguration *run
|
||||
}
|
||||
|
||||
AndroidAnalyzeSupport::AndroidAnalyzeSupport(RunControl *runControl)
|
||||
: ToolRunner(runControl)
|
||||
: RunWorker(runControl)
|
||||
{
|
||||
auto runner = new AndroidRunner(this, runControl->runConfiguration(), runControl->runMode());
|
||||
|
||||
|
@@ -34,7 +34,7 @@
|
||||
namespace Android {
|
||||
namespace Internal {
|
||||
|
||||
class AndroidAnalyzeSupport : public ProjectExplorer::ToolRunner
|
||||
class AndroidAnalyzeSupport : public ProjectExplorer::RunWorker
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
@@ -40,6 +40,7 @@ struct ANDROID_EXPORT AndroidRunnable
|
||||
QVector<QStringList> afterFinishADBCommands;
|
||||
QString deviceSerialNumber;
|
||||
|
||||
QString displayName() const { return packageName; }
|
||||
static void *staticTypeId;
|
||||
};
|
||||
|
||||
|
@@ -71,8 +71,9 @@ namespace Internal {
|
||||
|
||||
ClangStaticAnalyzerToolRunner::ClangStaticAnalyzerToolRunner(RunControl *runControl,
|
||||
QString *errorMessage)
|
||||
: ToolRunner(runControl)
|
||||
: RunWorker(runControl)
|
||||
{
|
||||
setDisplayName("ClangStaticAnalyzerRunner");
|
||||
runControl->setDisplayName(tr("Clang Static Analyzer"));
|
||||
runControl->setIcon(ProjectExplorer::Icons::ANALYZER_START_SMALL_TOOLBAR);
|
||||
runControl->setSupportsReRunning(false);
|
||||
@@ -585,7 +586,7 @@ void ClangStaticAnalyzerToolRunner::start()
|
||||
return;
|
||||
}
|
||||
|
||||
reportSuccess();
|
||||
reportStarted();
|
||||
|
||||
while (m_runners.size() < parallelRuns && !m_unitsToProcess.isEmpty())
|
||||
analyzeNextFile();
|
||||
|
@@ -47,7 +47,7 @@ struct AnalyzeUnit {
|
||||
};
|
||||
typedef QList<AnalyzeUnit> AnalyzeUnits;
|
||||
|
||||
class ClangStaticAnalyzerToolRunner : public ProjectExplorer::ToolRunner
|
||||
class ClangStaticAnalyzerToolRunner : public ProjectExplorer::RunWorker
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
@@ -145,7 +145,7 @@ ClangStaticAnalyzerTool::ClangStaticAnalyzerTool()
|
||||
{{ClangStaticAnalyzerDockId, m_diagnosticView, {}, Perspective::SplitVertical}}
|
||||
));
|
||||
|
||||
Debugger::registerAction(Constants::CLANGSTATICANALYZER_RUN_MODE, {});
|
||||
//Debugger::registerAction(Constants::CLANGSTATICANALYZER_RUN_MODE, {});
|
||||
action = new QAction(tr("Clang Static Analyzer"), this);
|
||||
action->setToolTip(toolTip);
|
||||
menu->addAction(ActionManager::registerAction(action, "ClangStaticAnalyzer.Action"),
|
||||
|
@@ -59,16 +59,12 @@ enum ToolMode {
|
||||
//AnyMode = DebugMode | ProfileMode | ReleaseMode
|
||||
};
|
||||
|
||||
using RunControlCreator = std::function<ProjectExplorer::RunControl *
|
||||
(ProjectExplorer::RunConfiguration *runConfiguration, Core::Id runMode)>;
|
||||
|
||||
// FIXME: Merge with something sensible.
|
||||
DEBUGGER_EXPORT bool wantRunTool(ToolMode toolMode, const QString &toolName);
|
||||
DEBUGGER_EXPORT void showCannotStartDialog(const QString &toolName);
|
||||
DEBUGGER_EXPORT ProjectExplorer::RunConfiguration *startupRunConfiguration();
|
||||
|
||||
// Register a tool for a given start mode.
|
||||
DEBUGGER_EXPORT void registerAction(Core::Id runMode, const RunControlCreator &runControlCreator);
|
||||
DEBUGGER_EXPORT void registerPerspective(const QByteArray &perspectiveId, const Utils::Perspective *perspective);
|
||||
DEBUGGER_EXPORT void registerToolbar(const QByteArray &perspectiveId, const Utils::ToolbarDescription &desc);
|
||||
|
||||
@@ -85,7 +81,4 @@ DEBUGGER_EXPORT void showPermanentStatusMessage(const QString &message);
|
||||
DEBUGGER_EXPORT QAction *createStartAction();
|
||||
DEBUGGER_EXPORT QAction *createStopAction();
|
||||
|
||||
DEBUGGER_EXPORT ProjectExplorer::RunControl *createAnalyzerRunControl(
|
||||
ProjectExplorer::RunConfiguration *runConfiguration, Core::Id runMode);
|
||||
|
||||
} // namespace Debugger
|
||||
|
@@ -561,7 +561,7 @@ void DebuggerEngine::setRunTool(DebuggerRunTool *runTool)
|
||||
d->m_runTool = runTool;
|
||||
}
|
||||
|
||||
void DebuggerEngine::prepare()
|
||||
void DebuggerEngine::start()
|
||||
{
|
||||
QTC_ASSERT(d->m_runTool, notifyEngineSetupFailed(); return);
|
||||
|
||||
@@ -602,25 +602,7 @@ void DebuggerEngine::prepare()
|
||||
}
|
||||
|
||||
d->queueSetupEngine();
|
||||
}
|
||||
|
||||
void DebuggerEngine::start()
|
||||
{
|
||||
Internal::runControlStarted(this);
|
||||
|
||||
// We might get a synchronous startFailed() notification on Windows,
|
||||
// when launching the process fails. Emit a proper finished() sequence.
|
||||
//runControl()->reportApplicationStart();
|
||||
|
||||
showMessage("QUEUE: SETUP INFERIOR");
|
||||
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << this << state());
|
||||
// if (isMasterEngine())
|
||||
d->queueSetupInferior();
|
||||
}
|
||||
|
||||
void DebuggerEngine::startDebugger()
|
||||
{
|
||||
d->queueRunEngine();
|
||||
}
|
||||
|
||||
void DebuggerEngine::resetLocation()
|
||||
@@ -822,7 +804,9 @@ void DebuggerEngine::notifyEngineSetupOk()
|
||||
|
||||
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << this << state());
|
||||
setState(EngineSetupOk);
|
||||
runTool()->reportSuccess();
|
||||
|
||||
Internal::runControlStarted(this);
|
||||
d->queueSetupInferior();
|
||||
}
|
||||
|
||||
void DebuggerEngine::setupSlaveInferior()
|
||||
@@ -1313,6 +1297,11 @@ void DebuggerEngine::setState(DebuggerState state, bool forced)
|
||||
DebuggerToolTipManager::registerEngine(this);
|
||||
}
|
||||
|
||||
if (state == InferiorUnrunnable || state == InferiorRunOk) {
|
||||
if (isMasterEngine() && runTool())
|
||||
runTool()->reportStarted();
|
||||
}
|
||||
|
||||
if (state == DebuggerFinished) {
|
||||
// Give up ownership on claimed breakpoints.
|
||||
foreach (Breakpoint bp, breakHandler()->engineBreakpoints(this))
|
||||
|
@@ -202,11 +202,8 @@ public:
|
||||
virtual void setRunTool(DebuggerRunTool *runTool);
|
||||
DebuggerRunTool *runTool() const;
|
||||
|
||||
void prepare();
|
||||
void start();
|
||||
|
||||
void startDebugger();
|
||||
|
||||
enum {
|
||||
// Remove need to qualify each use.
|
||||
NeedsTemporaryStop = DebuggerCommand::NeedsTemporaryStop,
|
||||
|
@@ -973,7 +973,6 @@ public:
|
||||
QPointer<QWidget> m_modeWindow;
|
||||
QPointer<DebugMode> m_mode;
|
||||
|
||||
QHash<Id, RunControlCreator> m_runControlCreators;
|
||||
ActionContainer *m_menu = 0;
|
||||
|
||||
// DockWidgetEventFilter m_resizeEventFilter;
|
||||
@@ -3527,11 +3526,6 @@ bool wantRunTool(ToolMode toolMode, const QString &toolName)
|
||||
return true;
|
||||
}
|
||||
|
||||
void registerAction(Id runMode, const RunControlCreator &runControlCreator)
|
||||
{
|
||||
dd->m_runControlCreators.insert(runMode, runControlCreator);
|
||||
}
|
||||
|
||||
void registerToolbar(const QByteArray &perspectiveId, const ToolbarDescription &desc)
|
||||
{
|
||||
auto toolbar = new QWidget;
|
||||
@@ -3605,14 +3599,6 @@ void showPermanentStatusMessage(const QString &message)
|
||||
dd->m_mainWindow->showStatusMessage(message, -1);
|
||||
}
|
||||
|
||||
RunControl *createAnalyzerRunControl(RunConfiguration *runConfiguration, Id runMode)
|
||||
{
|
||||
RunControlCreator rcc = dd->m_runControlCreators.value(runMode);
|
||||
if (rcc)
|
||||
return rcc(runConfiguration, runMode);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
namespace Internal {
|
||||
|
||||
static bool s_testRun = false;
|
||||
|
@@ -109,19 +109,15 @@ static QLatin1String engineTypeName(DebuggerEngineType et)
|
||||
return QLatin1String("No engine");
|
||||
}
|
||||
|
||||
void DebuggerRunTool::prepare()
|
||||
void DebuggerRunTool::start()
|
||||
{
|
||||
Debugger::Internal::saveModeToRestore();
|
||||
Debugger::selectPerspective(Debugger::Constants::CppPerspectiveId);
|
||||
TaskHub::clearTasks(Debugger::Constants::TASK_CATEGORY_DEBUGGER_DEBUGINFO);
|
||||
TaskHub::clearTasks(Debugger::Constants::TASK_CATEGORY_DEBUGGER_RUNTIME);
|
||||
|
||||
m_engine->prepare();
|
||||
}
|
||||
|
||||
void DebuggerRunTool::start()
|
||||
{
|
||||
DebuggerEngine *engine = m_engine;
|
||||
|
||||
QTC_ASSERT(engine, return);
|
||||
const DebuggerRunParameters &rp = engine->runParameters();
|
||||
// User canceled input dialog asking for executable when working on library project.
|
||||
@@ -177,11 +173,6 @@ void DebuggerRunTool::notifyEngineRemoteSetupFinished(const RemoteSetupResult &r
|
||||
m_engine->notifyEngineRemoteSetupFinished(result);
|
||||
}
|
||||
|
||||
void DebuggerRunTool::setRemoteParameters(const RemoteSetupResult &result)
|
||||
{
|
||||
m_engine->setRemoteParameters(result);
|
||||
}
|
||||
|
||||
void DebuggerRunTool::stop()
|
||||
{
|
||||
m_engine->quitDebugger();
|
||||
@@ -199,7 +190,7 @@ void DebuggerRunTool::onTargetFailure()
|
||||
|
||||
void DebuggerRunTool::debuggingFinished()
|
||||
{
|
||||
runControl()->reportApplicationStop();
|
||||
reportStopped();
|
||||
}
|
||||
|
||||
DebuggerStartParameters &DebuggerRunTool::startParameters()
|
||||
@@ -495,10 +486,11 @@ static DebuggerRunConfigurationAspect *debuggerAspect(const RunControl *runContr
|
||||
/// DebuggerRunTool
|
||||
|
||||
DebuggerRunTool::DebuggerRunTool(RunControl *runControl)
|
||||
: ToolRunner(runControl),
|
||||
: RunWorker(runControl),
|
||||
m_isCppDebugging(debuggerAspect(runControl)->useCppDebugger()),
|
||||
m_isQmlDebugging(debuggerAspect(runControl)->useQmlDebugger())
|
||||
{
|
||||
setDisplayName("DebuggerRunTool");
|
||||
}
|
||||
|
||||
DebuggerRunTool::DebuggerRunTool(RunControl *runControl, const DebuggerStartParameters &sp, QString *errorMessage)
|
||||
@@ -577,7 +569,7 @@ DebuggerRunTool::~DebuggerRunTool()
|
||||
|
||||
void DebuggerRunTool::onFinished()
|
||||
{
|
||||
appendMessage(tr("Debugging has finished") + '\n', NormalMessageFormat);
|
||||
appendMessage(tr("Debugging has finished"), NormalMessageFormat);
|
||||
runControlFinished(m_engine);
|
||||
}
|
||||
|
||||
@@ -619,8 +611,9 @@ public:
|
||||
QTC_ASSERT(runConfig, return 0);
|
||||
QTC_ASSERT(mode == DebugRunMode || mode == DebugRunModeWithBreakOnMain, return 0);
|
||||
|
||||
DebuggerStartParameters sp;
|
||||
auto runControl = new RunControl(runConfig, mode);
|
||||
(void) new DebuggerRunTool(runControl, DebuggerStartParameters(), errorMessage);
|
||||
(void) new DebuggerRunTool(runControl, sp, errorMessage);
|
||||
return runControl;
|
||||
}
|
||||
|
||||
@@ -690,10 +683,109 @@ RunControl *createAndScheduleRun(const DebuggerRunParameters &rp, Kit *kit)
|
||||
QTC_ASSERT(runConfig, return nullptr);
|
||||
auto runControl = new RunControl(runConfig, DebugRunMode);
|
||||
(void) new DebuggerRunTool(runControl, rp);
|
||||
QTC_ASSERT(runControl, return nullptr);
|
||||
ProjectExplorerPlugin::startRunControl(runControl);
|
||||
return runControl;
|
||||
}
|
||||
|
||||
} // Internal
|
||||
|
||||
// GdbServerPortGatherer
|
||||
|
||||
GdbServerPortsGatherer::GdbServerPortsGatherer(RunControl *runControl)
|
||||
: RunWorker(runControl)
|
||||
{
|
||||
}
|
||||
|
||||
GdbServerPortsGatherer::~GdbServerPortsGatherer()
|
||||
{
|
||||
}
|
||||
|
||||
void GdbServerPortsGatherer::start()
|
||||
{
|
||||
appendMessage(tr("Checking available ports..."), NormalMessageFormat);
|
||||
connect(&m_portsGatherer, &DeviceUsedPortsGatherer::error, this, [this](const QString &msg) {
|
||||
reportFailure(msg);
|
||||
});
|
||||
connect(&m_portsGatherer, &DeviceUsedPortsGatherer::portListReady, this, [this] {
|
||||
Utils::PortList portList = device()->freePorts();
|
||||
appendMessage(tr("Found %1 free ports").arg(portList.count()), NormalMessageFormat);
|
||||
if (m_useGdbServer) {
|
||||
m_gdbServerPort = m_portsGatherer.getNextFreePort(&portList);
|
||||
if (!m_gdbServerPort.isValid()) {
|
||||
reportFailure(tr("Not enough free ports on device for C++ debugging."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (m_useQmlServer) {
|
||||
m_qmlServerPort = m_portsGatherer.getNextFreePort(&portList);
|
||||
if (!m_qmlServerPort.isValid()) {
|
||||
reportFailure(tr("Not enough free ports on device for QML debugging."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
reportStarted();
|
||||
});
|
||||
m_portsGatherer.start(device());
|
||||
}
|
||||
|
||||
|
||||
// GdbServerRunner
|
||||
|
||||
GdbServerRunner::GdbServerRunner(RunControl *runControl)
|
||||
: RunWorker(runControl)
|
||||
{
|
||||
setDisplayName("GdbServerRunner");
|
||||
}
|
||||
|
||||
GdbServerRunner::~GdbServerRunner()
|
||||
{
|
||||
}
|
||||
|
||||
void GdbServerRunner::start()
|
||||
{
|
||||
auto portsGatherer = runControl()->worker<GdbServerPortsGatherer>();
|
||||
QTC_ASSERT(portsGatherer, reportFailure(); return);
|
||||
|
||||
StandardRunnable r = runnable().as<StandardRunnable>();
|
||||
QStringList args = QtcProcess::splitArgs(r.commandLineArguments, OsTypeLinux);
|
||||
QString command;
|
||||
|
||||
const bool isQmlDebugging = portsGatherer->useQmlServer();
|
||||
const bool isCppDebugging = portsGatherer->useGdbServer();
|
||||
|
||||
if (isQmlDebugging) {
|
||||
args.prepend(QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices,
|
||||
portsGatherer->qmlServerPort()));
|
||||
}
|
||||
|
||||
if (isQmlDebugging && !isCppDebugging) {
|
||||
command = r.executable;
|
||||
} else {
|
||||
command = device()->debugServerPath();
|
||||
if (command.isEmpty())
|
||||
command = "gdbserver";
|
||||
args.clear();
|
||||
args.append(QString("--multi"));
|
||||
args.append(QString(":%1").arg(portsGatherer->gdbServerPort().number()));
|
||||
}
|
||||
r.executable = command;
|
||||
r.commandLineArguments = QtcProcess::joinArgs(args, OsTypeLinux);
|
||||
|
||||
connect(&m_gdbServer, &ApplicationLauncher::error, this, [this] {
|
||||
reportFailure(tr("GDBserver start failed"));
|
||||
});
|
||||
connect(&m_gdbServer, &ApplicationLauncher::remoteProcessStarted, this, [this] {
|
||||
appendMessage(tr("GDBserver started") + '\n', NormalMessageFormat);
|
||||
reportStarted();
|
||||
});
|
||||
|
||||
appendMessage(tr("Starting GDBserver...") + '\n', NormalMessageFormat);
|
||||
m_gdbServer.start(r, device());
|
||||
}
|
||||
|
||||
void GdbServerRunner::onFinished()
|
||||
{
|
||||
m_gdbServer.stop();
|
||||
}
|
||||
|
||||
} // namespace Debugger
|
||||
|
@@ -30,13 +30,14 @@
|
||||
#include "debuggerengine.h"
|
||||
|
||||
#include <projectexplorer/runconfiguration.h>
|
||||
#include <projectexplorer/devicesupport/deviceusedportsgatherer.h>
|
||||
|
||||
namespace Debugger {
|
||||
|
||||
class RemoteSetupResult;
|
||||
class DebuggerStartParameters;
|
||||
|
||||
class DEBUGGER_EXPORT DebuggerRunTool : public ProjectExplorer::ToolRunner
|
||||
class DEBUGGER_EXPORT DebuggerRunTool : public ProjectExplorer::RunWorker
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -60,16 +61,14 @@ public:
|
||||
|
||||
void showMessage(const QString &msg, int channel = LogDebug, int timeout = -1);
|
||||
|
||||
void prepare() override;
|
||||
void start() override;
|
||||
void stop() override;
|
||||
void onTargetFailure() override;
|
||||
void onFinished() override;
|
||||
|
||||
void startFailed();
|
||||
void onTargetFailure();
|
||||
void notifyEngineRemoteServerRunning(const QByteArray &msg, int pid);
|
||||
void notifyEngineRemoteSetupFinished(const RemoteSetupResult &result);
|
||||
void setRemoteParameters(const RemoteSetupResult &result);
|
||||
void notifyInferiorIll();
|
||||
Q_SLOT void notifyInferiorExited();
|
||||
void quitDebugger();
|
||||
@@ -97,4 +96,48 @@ private:
|
||||
const bool m_isQmlDebugging;
|
||||
};
|
||||
|
||||
class DEBUGGER_EXPORT GdbServerPortsGatherer : public ProjectExplorer::RunWorker
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit GdbServerPortsGatherer(ProjectExplorer::RunControl *runControl);
|
||||
~GdbServerPortsGatherer();
|
||||
|
||||
void setUseGdbServer(bool useIt) { m_useGdbServer = useIt; }
|
||||
bool useGdbServer() const { return m_useGdbServer; }
|
||||
Utils::Port gdbServerPort() const { return m_gdbServerPort; }
|
||||
|
||||
void setUseQmlServer(bool useIt) { m_useQmlServer = useIt; }
|
||||
bool useQmlServer() const { return m_useQmlServer; }
|
||||
Utils::Port qmlServerPort() const { return m_qmlServerPort; }
|
||||
|
||||
private:
|
||||
void start();
|
||||
|
||||
ProjectExplorer::DeviceUsedPortsGatherer m_portsGatherer;
|
||||
bool m_useGdbServer = false;
|
||||
bool m_useQmlServer = false;
|
||||
Utils::Port m_gdbServerPort;
|
||||
Utils::Port m_qmlServerPort;
|
||||
};
|
||||
|
||||
class DEBUGGER_EXPORT GdbServerRunner : public ProjectExplorer::RunWorker
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit GdbServerRunner(ProjectExplorer::RunControl *runControl);
|
||||
~GdbServerRunner();
|
||||
|
||||
private:
|
||||
void start() override;
|
||||
void onFinished() override;
|
||||
|
||||
ProjectExplorer::ApplicationLauncher m_gdbServer;
|
||||
};
|
||||
|
||||
extern DEBUGGER_EXPORT const char GdbServerRunnerWorkerId[];
|
||||
extern DEBUGGER_EXPORT const char GdbServerPortGathererWorkerId[];
|
||||
|
||||
} // namespace Debugger
|
||||
|
@@ -32,7 +32,7 @@ namespace Ios {
|
||||
namespace Internal {
|
||||
|
||||
IosAnalyzeSupport::IosAnalyzeSupport(RunControl *runControl, bool cppDebug, bool qmlDebug)
|
||||
: ToolRunner(runControl),
|
||||
: RunWorker(runControl),
|
||||
m_runner(new IosRunner(this, runControl, cppDebug, qmlDebug ? QmlDebug::QmlProfilerServices :
|
||||
QmlDebug::NoQmlDebugServices))
|
||||
{
|
||||
|
@@ -34,7 +34,7 @@ namespace Internal {
|
||||
|
||||
class IosRunner;
|
||||
|
||||
class IosAnalyzeSupport : public ProjectExplorer::ToolRunner
|
||||
class IosAnalyzeSupport : public ProjectExplorer::RunWorker
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
@@ -184,11 +184,8 @@ RunControl *IosRunControlFactory::create(RunConfiguration *runConfig,
|
||||
if (mode == ProjectExplorer::Constants::NORMAL_RUN_MODE)
|
||||
res = new Ios::Internal::IosRunControl(rc);
|
||||
else if (mode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) {
|
||||
RunControl *runControl = Debugger::createAnalyzerRunControl(runConfig, mode);
|
||||
QTC_ASSERT(runControl, return 0);
|
||||
IDevice::ConstPtr device = DeviceKitInformation::device(target->kit());
|
||||
if (device.isNull())
|
||||
return 0;
|
||||
auto runControl = new RunControl(runConfig, mode);
|
||||
runControl->createWorker(mode);
|
||||
auto iosRunConfig = qobject_cast<IosRunConfiguration *>(runConfig);
|
||||
StandardRunnable runnable;
|
||||
runnable.executable = iosRunConfig->localExecutable().toUserOutput();
|
||||
|
@@ -525,11 +525,16 @@ void AppOutputPane::attachToRunControl()
|
||||
void AppOutputPane::stopRunControl()
|
||||
{
|
||||
const int index = currentIndex();
|
||||
QTC_ASSERT(index != -1 && m_runControlTabs.at(index).runControl->isRunning(), return);
|
||||
|
||||
QTC_ASSERT(index != -1, return);
|
||||
RunControl *rc = m_runControlTabs.at(index).runControl;
|
||||
QTC_ASSERT(rc, return);
|
||||
|
||||
if (rc->isRunning() && optionallyPromptToStop(rc))
|
||||
rc->initiateStop();
|
||||
else if (rc->isStarting()) {
|
||||
QTC_CHECK(false);
|
||||
rc->initiateStop();
|
||||
}
|
||||
|
||||
if (debug)
|
||||
qDebug() << "OutputPane::stopRunControl " << rc;
|
||||
|
@@ -190,4 +190,40 @@ void DeviceUsedPortsGatherer::handleRemoteStdErr()
|
||||
d->remoteStderr += d->process->readAllStandardError();
|
||||
}
|
||||
|
||||
// PortGatherer
|
||||
|
||||
PortsGatherer::PortsGatherer(RunControl *runControl)
|
||||
: RunWorker(runControl)
|
||||
{
|
||||
setDisplayName("PortGatherer");
|
||||
}
|
||||
|
||||
PortsGatherer::~PortsGatherer()
|
||||
{
|
||||
}
|
||||
|
||||
void PortsGatherer::start()
|
||||
{
|
||||
appendMessage(tr("Checking available ports...") + '\n', NormalMessageFormat);
|
||||
connect(&m_portsGatherer, &DeviceUsedPortsGatherer::error, this, [this](const QString &msg) {
|
||||
reportFailure(msg);
|
||||
});
|
||||
connect(&m_portsGatherer, &DeviceUsedPortsGatherer::portListReady, this, [this] {
|
||||
m_portList = device()->freePorts();
|
||||
appendMessage(tr("Found %1 free ports").arg(m_portList.count()) + '\n', NormalMessageFormat);
|
||||
reportStarted();
|
||||
});
|
||||
m_portsGatherer.start(device());
|
||||
}
|
||||
|
||||
Port PortsGatherer::findPort()
|
||||
{
|
||||
return m_portsGatherer.getNextFreePort(&m_portList);
|
||||
}
|
||||
|
||||
void PortsGatherer::stop()
|
||||
{
|
||||
m_portsGatherer.stop();
|
||||
}
|
||||
|
||||
} // namespace ProjectExplorer
|
||||
|
@@ -27,10 +27,9 @@
|
||||
|
||||
#include "idevice.h"
|
||||
|
||||
namespace Utils {
|
||||
class Port;
|
||||
class PortList;
|
||||
} // namespace Utils
|
||||
#include <projectexplorer/runconfiguration.h>
|
||||
|
||||
#include <utils/portlist.h>
|
||||
|
||||
namespace ProjectExplorer {
|
||||
namespace Internal { class DeviceUsedPortsGathererPrivate; }
|
||||
@@ -64,4 +63,23 @@ private:
|
||||
Internal::DeviceUsedPortsGathererPrivate * const d;
|
||||
};
|
||||
|
||||
class PROJECTEXPLORER_EXPORT PortsGatherer : public RunWorker
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PortsGatherer(RunControl *runControl);
|
||||
~PortsGatherer() override;
|
||||
|
||||
Utils::Port findPort();
|
||||
|
||||
protected:
|
||||
void start() override;
|
||||
void stop() override;
|
||||
|
||||
private:
|
||||
DeviceUsedPortsGatherer m_portsGatherer;
|
||||
Utils::PortList m_portList;
|
||||
};
|
||||
|
||||
} // namespace ProjectExplorer
|
||||
|
@@ -35,6 +35,8 @@
|
||||
#include <QSharedPointer>
|
||||
#include <QVariantMap>
|
||||
|
||||
#include <functional>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QWidget;
|
||||
QT_END_NAMESPACE
|
||||
@@ -54,6 +56,8 @@ class Connection;
|
||||
class DeviceProcess;
|
||||
class DeviceProcessList;
|
||||
class Kit;
|
||||
class RunControl;
|
||||
class RunWorker;
|
||||
|
||||
namespace Internal { class IDevicePrivate; }
|
||||
|
||||
@@ -162,6 +166,8 @@ public:
|
||||
virtual DeviceProcessSignalOperation::Ptr signalOperation() const = 0;
|
||||
virtual DeviceEnvironmentFetcher::Ptr environmentFetcher() const;
|
||||
|
||||
virtual std::function<RunWorker *(RunControl *)> workerCreator(Core::Id) const { return {}; }
|
||||
|
||||
enum DeviceState { DeviceReadyToUse, DeviceConnected, DeviceDisconnected, DeviceStateUnknown };
|
||||
DeviceState deviceState() const;
|
||||
void setDeviceState(const DeviceState state);
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -51,11 +51,10 @@ class RunConfiguration;
|
||||
class RunConfigWidget;
|
||||
class RunControl;
|
||||
class Target;
|
||||
class TargetRunner;
|
||||
class ToolRunner;
|
||||
|
||||
namespace Internal {
|
||||
class RunControlPrivate;
|
||||
class RunWorkerPrivate;
|
||||
class SimpleRunControlPrivate;
|
||||
} // Internal
|
||||
|
||||
@@ -148,6 +147,7 @@ class PROJECTEXPLORER_EXPORT Runnable
|
||||
virtual ~Concept() {}
|
||||
virtual Concept *clone() const = 0;
|
||||
virtual bool canReUseOutputPane(const std::unique_ptr<Concept> &other) const = 0;
|
||||
virtual QString displayName() const = 0;
|
||||
virtual void *typeId() const = 0;
|
||||
};
|
||||
|
||||
@@ -168,6 +168,8 @@ class PROJECTEXPLORER_EXPORT Runnable
|
||||
return m_data == that->m_data;
|
||||
}
|
||||
|
||||
QString displayName() const override { return m_data.displayName(); }
|
||||
|
||||
void *typeId() const override { return T::staticTypeId; }
|
||||
|
||||
T m_data;
|
||||
@@ -190,6 +192,7 @@ public:
|
||||
}
|
||||
|
||||
bool canReUseOutputPane(const Runnable &other) const;
|
||||
QString displayName() const { return d->displayName(); }
|
||||
|
||||
private:
|
||||
std::unique_ptr<Concept> d;
|
||||
@@ -351,6 +354,61 @@ signals:
|
||||
void displayNameChanged(const QString &);
|
||||
};
|
||||
|
||||
class PROJECTEXPLORER_EXPORT RunWorker : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit RunWorker(RunControl *runControl);
|
||||
~RunWorker() override;
|
||||
|
||||
RunControl *runControl() const;
|
||||
|
||||
void addDependency(RunWorker *dependency);
|
||||
|
||||
QString displayName() const;
|
||||
void setDisplayName(const QString &displayName);
|
||||
|
||||
void setStartTimeout(int ms);
|
||||
void setStopTimeout(int ms);
|
||||
|
||||
void reportData(int channel, const QVariant &data);
|
||||
|
||||
void recordData(const QString &channel, const QVariant &data);
|
||||
QVariant recordedData(const QString &channel);
|
||||
|
||||
// Part of read-only interface of RunControl for convenience.
|
||||
void appendMessage(const QString &msg, Utils::OutputFormat format);
|
||||
IDevice::ConstPtr device() const;
|
||||
const Runnable &runnable() const;
|
||||
const Connection &connection() const;
|
||||
Core::Id runMode() const;
|
||||
|
||||
// States
|
||||
void initiateStart();
|
||||
void reportStarted();
|
||||
|
||||
void initiateStop();
|
||||
void reportStopped();
|
||||
|
||||
void reportFailure(const QString &msg = QString());
|
||||
|
||||
signals:
|
||||
void dataReported(int channel, const QVariant &data);
|
||||
void started();
|
||||
void stopped();
|
||||
|
||||
protected:
|
||||
void virtual start();
|
||||
void virtual stop();
|
||||
void virtual onFinished() {}
|
||||
|
||||
private:
|
||||
friend class Internal::RunControlPrivate;
|
||||
friend class Internal::RunWorkerPrivate;
|
||||
Internal::RunWorkerPrivate *d;
|
||||
};
|
||||
|
||||
/**
|
||||
* A RunControl controls the running of an application or tool
|
||||
* on a target device. It controls start and stop, and handles
|
||||
@@ -380,6 +438,8 @@ public:
|
||||
void setDisplayName(const QString &displayName);
|
||||
|
||||
bool isRunning() const;
|
||||
bool isStarting() const;
|
||||
bool isStopping() const;
|
||||
|
||||
void setIcon(const Utils::Icon &icon);
|
||||
Utils::Icon icon() const;
|
||||
@@ -402,12 +462,6 @@ public:
|
||||
const Connection &connection() const;
|
||||
void setConnection(const Connection &connection);
|
||||
|
||||
ToolRunner *toolRunner() const;
|
||||
void setToolRunner(ToolRunner *tool);
|
||||
|
||||
TargetRunner *targetRunner() const;
|
||||
void setTargetRunner(TargetRunner *tool);
|
||||
|
||||
virtual void appendMessage(const QString &msg, Utils::OutputFormat format);
|
||||
virtual void bringApplicationToForeground();
|
||||
|
||||
@@ -415,8 +469,9 @@ public:
|
||||
virtual void notifyRemoteSetupFailed(const QString &) {} // Same.
|
||||
virtual void notifyRemoteFinished() {} // Same.
|
||||
|
||||
void reportApplicationStart(); // Call this when the application starts to run
|
||||
void reportApplicationStop(); // Call this when the application has stopped for any reason
|
||||
void reportApplicationStart(); // FIXME: Don't use
|
||||
void reportApplicationStop(); // FIXME: Don't use
|
||||
void reportFailure(const QString &msg = QString());
|
||||
|
||||
static bool showPromptToStopDialog(const QString &title, const QString &text,
|
||||
const QString &stopButtonText = QString(),
|
||||
@@ -426,6 +481,25 @@ public:
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
|
||||
using WorkerCreator = std::function<RunWorker *(RunControl *)>;
|
||||
static void registerWorkerCreator(Core::Id id, const WorkerCreator &workerCreator);
|
||||
RunWorker *workerById(Core::Id id) const;
|
||||
QList<QPointer<RunWorker>> workers() const;
|
||||
|
||||
template <class T> T *worker() const {
|
||||
for (const QPointer<RunWorker> &worker : workers()) {
|
||||
if (worker) {
|
||||
if (auto res = qobject_cast<T *>(worker.data()))
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
using RunWorkerCreator = std::function<RunWorker *(RunControl *)>;
|
||||
static void registerRunWorkerCreator(Core::Id id, const RunWorkerCreator &creator);
|
||||
RunWorker *createWorker(Core::Id id);
|
||||
|
||||
signals:
|
||||
void appendMessageRequested(ProjectExplorer::RunControl *runControl,
|
||||
const QString &msg, Utils::OutputFormat format);
|
||||
@@ -436,114 +510,29 @@ signals:
|
||||
void applicationProcessHandleChanged(QPrivateSignal); // Use setApplicationProcessHandle
|
||||
|
||||
private:
|
||||
friend class Internal::RunControlPrivate;
|
||||
friend class TargetRunner;
|
||||
friend class ToolRunner;
|
||||
friend class RunWorker;
|
||||
friend class Internal::RunWorkerPrivate;
|
||||
|
||||
void bringApplicationToForegroundInternal();
|
||||
Internal::RunControlPrivate *d;
|
||||
};
|
||||
|
||||
/**
|
||||
* A base for target-specific additions to the RunControl.
|
||||
*/
|
||||
|
||||
class PROJECTEXPLORER_EXPORT TargetRunner : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TargetRunner(RunControl *runControl);
|
||||
~TargetRunner() override;
|
||||
|
||||
RunControl *runControl() const;
|
||||
void appendMessage(const QString &msg, Utils::OutputFormat format);
|
||||
IDevice::ConstPtr device() const;
|
||||
|
||||
// Preparation phase.
|
||||
virtual void prepare(); // Initiate setup. Needs to report result.
|
||||
// Startup phase.
|
||||
virtual void start(); // Initiates start. Needs to report result.
|
||||
// Stopping phase.
|
||||
virtual void stop(); // Initiates stop. Needs to report result.
|
||||
|
||||
//
|
||||
void reportStopped();
|
||||
// Generic success report, proceed to next stage.
|
||||
void reportSuccess();
|
||||
// Generic error, start ramp down.
|
||||
void reportFailure(const QString &msg = QString());
|
||||
|
||||
// Customization points. No reporting required nor wanted.
|
||||
virtual void onStop() {}
|
||||
virtual void onToolFailure() {}
|
||||
virtual void onTargetFailure() {}
|
||||
virtual void onFinished() {}
|
||||
|
||||
private:
|
||||
QPointer<RunControl> m_runControl;
|
||||
};
|
||||
|
||||
/**
|
||||
* A base for tool-specific additions to RunControl.
|
||||
*/
|
||||
|
||||
class PROJECTEXPLORER_EXPORT ToolRunner : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ToolRunner(RunControl *runControl);
|
||||
~ToolRunner() override;
|
||||
|
||||
RunControl *runControl() const;
|
||||
|
||||
// Part of read-only interface of RunControl for convenience.
|
||||
void appendMessage(const QString &msg, Utils::OutputFormat format);
|
||||
IDevice::ConstPtr device() const;
|
||||
const Runnable &runnable() const;
|
||||
const Connection &connection() const;
|
||||
|
||||
// Preparation phase.
|
||||
virtual void prepare(); // Initiates preparation, needs to report success or failure.
|
||||
// Start phase.
|
||||
virtual void start();
|
||||
// Stop phase.
|
||||
virtual void stop();
|
||||
|
||||
//
|
||||
void reportStopped();
|
||||
// Generic success report, proceed to next stage.
|
||||
void reportSuccess();
|
||||
// Generic error, start ramp down.
|
||||
void reportFailure(const QString &msg = QString());
|
||||
|
||||
// Customization points. No reporting required nor wanted.
|
||||
virtual void onStop() {}
|
||||
virtual void onToolFailure() {}
|
||||
virtual void onTargetFailure() {}
|
||||
virtual void onFinished() {}
|
||||
|
||||
private:
|
||||
QPointer<RunControl> m_runControl;
|
||||
};
|
||||
|
||||
/**
|
||||
* A simple TargetRunner for cases where a plain ApplicationLauncher is
|
||||
* sufficient for running purposes.
|
||||
*/
|
||||
|
||||
class PROJECTEXPLORER_EXPORT SimpleTargetRunner : public TargetRunner
|
||||
class PROJECTEXPLORER_EXPORT SimpleTargetRunner : public RunWorker
|
||||
{
|
||||
public:
|
||||
explicit SimpleTargetRunner(RunControl *runControl);
|
||||
|
||||
ApplicationLauncher *applicationLauncher() { return &m_launcher; }
|
||||
|
||||
private:
|
||||
protected:
|
||||
void start() override;
|
||||
void stop() override;
|
||||
|
||||
private:
|
||||
void onProcessStarted();
|
||||
void onProcessFinished(int exitCode, QProcess::ExitStatus status);
|
||||
|
||||
|
@@ -32,6 +32,7 @@
|
||||
|
||||
#include <utils/environment.h>
|
||||
|
||||
#include <QDir>
|
||||
#include <QUrl>
|
||||
|
||||
namespace ProjectExplorer {
|
||||
@@ -46,6 +47,7 @@ public:
|
||||
ApplicationLauncher::Mode runMode = ApplicationLauncher::Gui;
|
||||
IDevice::ConstPtr device; // Override the kit's device. Keep unset by default.
|
||||
|
||||
QString displayName() const { return QDir::toNativeSeparators(executable); }
|
||||
static void *staticTypeId;
|
||||
};
|
||||
|
||||
|
@@ -67,7 +67,6 @@ namespace QmlProfiler {
|
||||
class QmlProfilerRunControl::QmlProfilerRunControlPrivate
|
||||
{
|
||||
public:
|
||||
Internal::QmlProfilerTool *m_tool = 0;
|
||||
QmlProfilerStateManager *m_profilerState = 0;
|
||||
QTimer m_noDebugOutputTimer;
|
||||
};
|
||||
@@ -76,15 +75,13 @@ public:
|
||||
// QmlProfilerRunControl
|
||||
//
|
||||
|
||||
QmlProfilerRunControl::QmlProfilerRunControl(RunConfiguration *runConfiguration,
|
||||
Internal::QmlProfilerTool *tool)
|
||||
QmlProfilerRunControl::QmlProfilerRunControl(RunConfiguration *runConfiguration)
|
||||
: RunControl(runConfiguration, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE)
|
||||
, d(new QmlProfilerRunControlPrivate)
|
||||
{
|
||||
setIcon(ProjectExplorer::Icons::ANALYZER_START_SMALL_TOOLBAR);
|
||||
setSupportsReRunning(false);
|
||||
|
||||
d->m_tool = tool;
|
||||
// Only wait 4 seconds for the 'Waiting for connection' on application output, then just try to connect
|
||||
// (application output might be redirected / blocked)
|
||||
d->m_noDebugOutputTimer.setSingleShot(true);
|
||||
@@ -104,7 +101,7 @@ QmlProfilerRunControl::~QmlProfilerRunControl()
|
||||
void QmlProfilerRunControl::start()
|
||||
{
|
||||
reportApplicationStart();
|
||||
d->m_tool->finalizeRunControl(this);
|
||||
Internal::QmlProfilerTool::instance()->finalizeRunControl(this);
|
||||
QTC_ASSERT(d->m_profilerState, reportApplicationStop(); return);
|
||||
|
||||
QTC_ASSERT(connection().is<AnalyzerConnection>(), reportApplicationStop(); return);
|
||||
|
@@ -32,15 +32,12 @@
|
||||
|
||||
namespace QmlProfiler {
|
||||
|
||||
namespace Internal { class QmlProfilerTool; }
|
||||
|
||||
class QmlProfilerRunControl : public ProjectExplorer::RunControl
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QmlProfilerRunControl(ProjectExplorer::RunConfiguration *runConfiguration,
|
||||
Internal::QmlProfilerTool *tool);
|
||||
QmlProfilerRunControl(ProjectExplorer::RunConfiguration *runConfiguration);
|
||||
~QmlProfilerRunControl() override;
|
||||
|
||||
void registerProfilerStateManager( QmlProfilerStateManager *profilerState );
|
||||
|
@@ -92,10 +92,7 @@ RunControl *QmlProfilerRunControlFactory::create(RunConfiguration *runConfigurat
|
||||
connection.analyzerPort = LocalQmlProfilerRunner::findFreePort(connection.analyzerHost);
|
||||
}
|
||||
|
||||
auto runControl = qobject_cast<QmlProfilerRunControl *>
|
||||
(Debugger::createAnalyzerRunControl(runConfiguration, mode));
|
||||
QTC_ASSERT(runControl, return 0);
|
||||
|
||||
auto runControl = new QmlProfilerRunControl(runConfiguration);
|
||||
runControl->setRunnable(runnable);
|
||||
runControl->setConnection(connection);
|
||||
|
||||
|
@@ -127,9 +127,12 @@ public:
|
||||
bool m_toolBusy = false;
|
||||
};
|
||||
|
||||
static QmlProfilerTool *s_instance;
|
||||
|
||||
QmlProfilerTool::QmlProfilerTool(QObject *parent)
|
||||
: QObject(parent), d(new QmlProfilerToolPrivate)
|
||||
{
|
||||
s_instance = this;
|
||||
setObjectName(QLatin1String("QmlProfilerTool"));
|
||||
|
||||
d->m_profilerState = new QmlProfilerStateManager(this);
|
||||
@@ -244,8 +247,9 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent)
|
||||
// is available, then we can populate the file finder
|
||||
d->m_profilerModelManager->populateFileFinder();
|
||||
|
||||
auto runControlCreator = [this](RunConfiguration *runConfiguration, Core::Id) {
|
||||
return createRunControl(runConfiguration);
|
||||
auto runWorkerCreator = [this](RunControl *runControl) {
|
||||
// return createRunControl(runConfiguration);
|
||||
return nullptr; // FIXME
|
||||
};
|
||||
|
||||
QString description = tr("The QML Profiler can be used to find performance "
|
||||
@@ -254,7 +258,7 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent)
|
||||
d->m_startAction = Debugger::createStartAction();
|
||||
d->m_stopAction = Debugger::createStopAction();
|
||||
|
||||
Debugger::registerAction(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE, runControlCreator);
|
||||
RunControl::registerWorkerCreator(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE, runWorkerCreator);
|
||||
act = new QAction(tr("QML Profiler"), this);
|
||||
act->setToolTip(description);
|
||||
menu->addAction(ActionManager::registerAction(act, "QmlProfiler.Local"),
|
||||
@@ -270,7 +274,6 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent)
|
||||
act->setEnabled(d->m_startAction->isEnabled());
|
||||
});
|
||||
|
||||
Debugger::registerAction(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE, runControlCreator);
|
||||
act = new QAction(tr("QML Profiler (External)"), this);
|
||||
act->setToolTip(description);
|
||||
menu->addAction(ActionManager::registerAction(act, "QmlProfiler.Remote"),
|
||||
@@ -305,6 +308,11 @@ QmlProfilerTool::~QmlProfilerTool()
|
||||
delete d;
|
||||
}
|
||||
|
||||
QmlProfilerTool *QmlProfilerTool::instance()
|
||||
{
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
void QmlProfilerTool::updateRunActions()
|
||||
{
|
||||
if (d->m_toolBusy) {
|
||||
@@ -336,11 +344,11 @@ RunControl *QmlProfilerTool::createRunControl(RunConfiguration *runConfiguration
|
||||
}
|
||||
}
|
||||
|
||||
auto runControl = new QmlProfilerRunControl(runConfiguration, this);
|
||||
auto runControl = new QmlProfilerRunControl(runConfiguration);
|
||||
connect(runControl, &RunControl::finished, this, [this, runControl] {
|
||||
d->m_toolBusy = false;
|
||||
updateRunActions();
|
||||
disconnect(d->m_stopAction, &QAction::triggered, runControl, &QmlProfilerRunControl::stop);
|
||||
disconnect(d->m_stopAction, &QAction::triggered, runControl, &RunControl::stop);
|
||||
});
|
||||
|
||||
connect(d->m_stopAction, &QAction::triggered, runControl, &QmlProfilerRunControl::stop);
|
||||
|
@@ -49,6 +49,8 @@ public:
|
||||
explicit QmlProfilerTool(QObject *parent);
|
||||
~QmlProfilerTool();
|
||||
|
||||
static QmlProfilerTool *instance();
|
||||
|
||||
ProjectExplorer::RunControl *createRunControl(ProjectExplorer::RunConfiguration *runConfiguration = 0);
|
||||
void finalizeRunControl(QmlProfilerRunControl *runControl);
|
||||
|
||||
|
@@ -24,6 +24,9 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include "localqmlprofilerrunner_test.h"
|
||||
|
||||
#include "../qmlprofilerruncontrol.h"
|
||||
|
||||
#include <debugger/analyzer/analyzermanager.h>
|
||||
#include <debugger/analyzer/analyzerstartparameters.h>
|
||||
#include <QtTest>
|
||||
@@ -57,8 +60,7 @@ void LocalQmlProfilerRunnerTest::testRunner()
|
||||
// should not be used anywhere but cannot be empty
|
||||
configuration.socket = connection.analyzerSocket = QString("invalid");
|
||||
|
||||
rc = Debugger::createAnalyzerRunControl(
|
||||
nullptr, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
|
||||
rc = new QmlProfilerRunControl(nullptr);
|
||||
rc->setConnection(connection);
|
||||
auto runner = new LocalQmlProfilerRunner(configuration, rc);
|
||||
connectRunner(runner);
|
||||
@@ -79,8 +81,7 @@ void LocalQmlProfilerRunnerTest::testRunner1()
|
||||
configuration.debuggee.commandLineArguments = QString("-test QmlProfiler,");
|
||||
|
||||
delete rc;
|
||||
rc = Debugger::createAnalyzerRunControl(
|
||||
nullptr, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
|
||||
rc = new QmlProfilerRunControl(nullptr);
|
||||
rc->setConnection(connection);
|
||||
auto runner = new LocalQmlProfilerRunner(configuration, rc);
|
||||
connectRunner(runner);
|
||||
@@ -100,8 +101,7 @@ void LocalQmlProfilerRunnerTest::testRunner2()
|
||||
connection.analyzerSocket.clear();
|
||||
configuration.port = connection.analyzerPort =
|
||||
LocalQmlProfilerRunner::findFreePort(connection.analyzerHost);
|
||||
rc = Debugger::createAnalyzerRunControl(
|
||||
nullptr, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
|
||||
rc = new QmlProfilerRunControl(nullptr);
|
||||
rc->setConnection(connection);
|
||||
auto runner = new LocalQmlProfilerRunner(configuration, rc);
|
||||
connectRunner(runner);
|
||||
|
@@ -9,13 +9,11 @@ SOURCES += qnxplugin.cpp \
|
||||
qnxdevicewizard.cpp \
|
||||
qnxrunconfiguration.cpp \
|
||||
qnxruncontrolfactory.cpp \
|
||||
qnxabstractrunsupport.cpp \
|
||||
qnxanalyzesupport.cpp \
|
||||
qnxdebugsupport.cpp \
|
||||
qnxdeploystepfactory.cpp \
|
||||
qnxdeployconfigurationfactory.cpp \
|
||||
qnxrunconfigurationfactory.cpp \
|
||||
qnxruncontrol.cpp \
|
||||
qnxqtversionfactory.cpp \
|
||||
qnxqtversion.cpp \
|
||||
qnxdeployconfiguration.cpp \
|
||||
@@ -44,13 +42,11 @@ HEADERS += qnxplugin.h\
|
||||
qnxdevicewizard.h \
|
||||
qnxrunconfiguration.h \
|
||||
qnxruncontrolfactory.h \
|
||||
qnxabstractrunsupport.h \
|
||||
qnxanalyzesupport.h \
|
||||
qnxdebugsupport.h \
|
||||
qnxdeploystepfactory.h \
|
||||
qnxdeployconfigurationfactory.h \
|
||||
qnxrunconfigurationfactory.h \
|
||||
qnxruncontrol.h \
|
||||
qnxqtversionfactory.h \
|
||||
qnxqtversion.h \
|
||||
qnxdeployconfiguration.h \
|
||||
|
@@ -33,8 +33,6 @@ QtcPlugin {
|
||||
"qnxconstants.h",
|
||||
"qnxconfiguration.cpp",
|
||||
"qnxconfiguration.h",
|
||||
"qnxabstractrunsupport.cpp",
|
||||
"qnxabstractrunsupport.h",
|
||||
"qnxanalyzesupport.cpp",
|
||||
"qnxanalyzesupport.h",
|
||||
"qnxdebugsupport.cpp",
|
||||
@@ -78,8 +76,6 @@ QtcPlugin {
|
||||
"qnxrunconfiguration.h",
|
||||
"qnxrunconfigurationfactory.cpp",
|
||||
"qnxrunconfigurationfactory.h",
|
||||
"qnxruncontrol.cpp",
|
||||
"qnxruncontrol.h",
|
||||
"qnxruncontrolfactory.cpp",
|
||||
"qnxruncontrolfactory.h",
|
||||
"qnxutils.cpp",
|
||||
|
@@ -1,124 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qnxabstractrunsupport.h"
|
||||
#include "qnxrunconfiguration.h"
|
||||
|
||||
#include <projectexplorer/devicesupport/deviceusedportsgatherer.h>
|
||||
#include <projectexplorer/kitinformation.h>
|
||||
#include <projectexplorer/target.h>
|
||||
#include <utils/portlist.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
using namespace RemoteLinux;
|
||||
|
||||
namespace Qnx {
|
||||
namespace Internal {
|
||||
|
||||
QnxAbstractRunSupport::QnxAbstractRunSupport(RunControl *runControl)
|
||||
: ToolRunner(runControl)
|
||||
, m_state(Inactive)
|
||||
{
|
||||
m_launcher = new ApplicationLauncher(this);
|
||||
m_portsGatherer = new DeviceUsedPortsGatherer(this);
|
||||
|
||||
connect(m_portsGatherer, &DeviceUsedPortsGatherer::error,
|
||||
this, &QnxAbstractRunSupport::handleError);
|
||||
connect(m_portsGatherer, &DeviceUsedPortsGatherer::portListReady,
|
||||
this, &QnxAbstractRunSupport::handlePortListReady);
|
||||
}
|
||||
|
||||
void QnxAbstractRunSupport::handleAdapterSetupRequested()
|
||||
{
|
||||
QTC_ASSERT(m_state == Inactive, return);
|
||||
|
||||
m_state = GatheringPorts;
|
||||
m_portsGatherer->start(m_device);
|
||||
}
|
||||
|
||||
void QnxAbstractRunSupport::handlePortListReady()
|
||||
{
|
||||
QTC_ASSERT(m_state == GatheringPorts, return);
|
||||
m_portList = device()->freePorts();
|
||||
startExecution();
|
||||
}
|
||||
|
||||
void QnxAbstractRunSupport::handleRemoteProcessStarted()
|
||||
{
|
||||
m_state = Running;
|
||||
}
|
||||
|
||||
void QnxAbstractRunSupport::handleRemoteProcessFinished(bool)
|
||||
{
|
||||
}
|
||||
|
||||
void QnxAbstractRunSupport::setFinished()
|
||||
{
|
||||
if (m_state != GatheringPorts && m_state != Inactive)
|
||||
m_launcher->stop();
|
||||
|
||||
m_state = Inactive;
|
||||
}
|
||||
|
||||
QnxAbstractRunSupport::State QnxAbstractRunSupport::state() const
|
||||
{
|
||||
return m_state;
|
||||
}
|
||||
|
||||
void QnxAbstractRunSupport::setState(QnxAbstractRunSupport::State state)
|
||||
{
|
||||
m_state = state;
|
||||
}
|
||||
|
||||
ApplicationLauncher *QnxAbstractRunSupport::appRunner() const
|
||||
{
|
||||
return m_launcher;
|
||||
}
|
||||
|
||||
void QnxAbstractRunSupport::handleProgressReport(const QString &)
|
||||
{
|
||||
}
|
||||
|
||||
void QnxAbstractRunSupport::handleRemoteOutput(const QByteArray &)
|
||||
{
|
||||
}
|
||||
|
||||
void QnxAbstractRunSupport::handleError(const QString &)
|
||||
{
|
||||
}
|
||||
|
||||
bool QnxAbstractRunSupport::setPort(Utils::Port &port)
|
||||
{
|
||||
port = m_portsGatherer->getNextFreePort(&m_portList);
|
||||
if (!port.isValid()) {
|
||||
handleError(tr("Not enough free ports on device for debugging."));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Qnx
|
@@ -1,91 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <projectexplorer/devicesupport/idevice.h>
|
||||
#include <projectexplorer/runconfiguration.h>
|
||||
|
||||
#include <utils/environment.h>
|
||||
#include <utils/portlist.h>
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
namespace ProjectExplorer {
|
||||
class ApplicationLauncher;
|
||||
class DeviceUsedPortsGatherer;
|
||||
}
|
||||
|
||||
namespace Qnx {
|
||||
namespace Internal {
|
||||
|
||||
class QnxAbstractRunSupport : public ProjectExplorer::ToolRunner
|
||||
{
|
||||
Q_OBJECT
|
||||
protected:
|
||||
enum State {
|
||||
Inactive,
|
||||
GatheringPorts,
|
||||
StartingRemoteProcess,
|
||||
Running
|
||||
};
|
||||
|
||||
public:
|
||||
explicit QnxAbstractRunSupport(ProjectExplorer::RunControl *runControl);
|
||||
|
||||
protected:
|
||||
bool setPort(Utils::Port &port);
|
||||
virtual void startExecution() = 0;
|
||||
|
||||
void setFinished();
|
||||
|
||||
State state() const;
|
||||
void setState(State state);
|
||||
|
||||
ProjectExplorer::ApplicationLauncher *appRunner() const;
|
||||
|
||||
public slots:
|
||||
virtual void handleAdapterSetupRequested();
|
||||
|
||||
virtual void handleRemoteProcessStarted();
|
||||
virtual void handleRemoteProcessFinished(bool);
|
||||
virtual void handleProgressReport(const QString &progressOutput);
|
||||
virtual void handleRemoteOutput(const QByteArray &output);
|
||||
virtual void handleError(const QString &);
|
||||
|
||||
private slots:
|
||||
void handlePortListReady();
|
||||
|
||||
private:
|
||||
ProjectExplorer::DeviceUsedPortsGatherer * m_portsGatherer;
|
||||
Utils::PortList m_portList;
|
||||
ProjectExplorer::IDevice::ConstPtr m_device;
|
||||
ProjectExplorer::ApplicationLauncher *m_launcher;
|
||||
State m_state;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Qnx
|
@@ -29,12 +29,15 @@
|
||||
#include "qnxrunconfiguration.h"
|
||||
#include "slog2inforunner.h"
|
||||
|
||||
#include <projectexplorer/devicesupport/deviceusedportsgatherer.h>
|
||||
#include <projectexplorer/kitinformation.h>
|
||||
#include <projectexplorer/runnables.h>
|
||||
#include <projectexplorer/target.h>
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/qtcprocess.h>
|
||||
#include <qmldebug/qmldebugcommandlinearguments.h>
|
||||
#include <qmldebug/qmloutputparser.h>
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
using namespace Utils;
|
||||
@@ -42,122 +45,64 @@ using namespace Utils;
|
||||
namespace Qnx {
|
||||
namespace Internal {
|
||||
|
||||
QnxAnalyzeSupport::QnxAnalyzeSupport(RunControl *runControl)
|
||||
: QnxAbstractRunSupport(runControl)
|
||||
, m_runnable(runControl->runnable().as<StandardRunnable>())
|
||||
, m_qmlPort(-1)
|
||||
class QnxAnalyzeeRunner : public ProjectExplorer::SimpleTargetRunner
|
||||
{
|
||||
const ApplicationLauncher *runner = appRunner();
|
||||
connect(runner, &ApplicationLauncher::reportError,
|
||||
this, &QnxAnalyzeSupport::handleError);
|
||||
connect(runner, &ApplicationLauncher::remoteProcessStarted,
|
||||
this, &QnxAbstractRunSupport::handleRemoteProcessStarted);
|
||||
connect(runner, &ApplicationLauncher::finished,
|
||||
this, &QnxAnalyzeSupport::handleRemoteProcessFinished);
|
||||
connect(runner, &ApplicationLauncher::reportProgress,
|
||||
this, &QnxAnalyzeSupport::handleProgressReport);
|
||||
connect(runner, &ApplicationLauncher::remoteStdout,
|
||||
this, &QnxAnalyzeSupport::handleRemoteOutput);
|
||||
connect(runner, &ApplicationLauncher::remoteStderr,
|
||||
this, &QnxAnalyzeSupport::handleRemoteOutput);
|
||||
|
||||
connect(runControl, &RunControl::starting,
|
||||
this, &QnxAnalyzeSupport::handleAdapterSetupRequested);
|
||||
connect(runControl, &RunControl::finished,
|
||||
this, &QnxAnalyzeSupport::setFinished);
|
||||
|
||||
connect(&m_outputParser, &QmlDebug::QmlOutputParser::waitingForConnectionOnPort,
|
||||
this, &QnxAnalyzeSupport::remoteIsRunning);
|
||||
|
||||
IDevice::ConstPtr dev = DeviceKitInformation::device(runControl->runConfiguration()->target()->kit());
|
||||
QnxDevice::ConstPtr qnxDevice = dev.dynamicCast<const QnxDevice>();
|
||||
|
||||
auto qnxRunConfig = qobject_cast<QnxRunConfiguration *>(runControl->runConfiguration());
|
||||
const QString applicationId = FileName::fromString(qnxRunConfig->remoteExecutableFilePath()).fileName();
|
||||
m_slog2Info = new Slog2InfoRunner(applicationId, qnxDevice, this);
|
||||
connect(m_slog2Info, &Slog2InfoRunner::output,
|
||||
this, &QnxAnalyzeSupport::showMessage);
|
||||
connect(runner, &ApplicationLauncher::remoteProcessStarted,
|
||||
m_slog2Info, &Slog2InfoRunner::start);
|
||||
if (qnxDevice->qnxVersion() > 0x060500)
|
||||
connect(m_slog2Info, &Slog2InfoRunner::commandMissing,
|
||||
this, &QnxAnalyzeSupport::printMissingWarning);
|
||||
public:
|
||||
QnxAnalyzeeRunner(ProjectExplorer::RunControl *runControl)
|
||||
: SimpleTargetRunner(runControl)
|
||||
{
|
||||
setDisplayName("QnxAnalyzeeRunner");
|
||||
}
|
||||
|
||||
void QnxAnalyzeSupport::handleAdapterSetupRequested()
|
||||
private:
|
||||
void start() override
|
||||
{
|
||||
QTC_ASSERT(state() == Inactive, return);
|
||||
auto portsGatherer = runControl()->worker<PortsGatherer>();
|
||||
Utils::Port port = portsGatherer->findPort();
|
||||
|
||||
showMessage(tr("Preparing remote side...") + QLatin1Char('\n'), NormalMessageFormat);
|
||||
QnxAbstractRunSupport::handleAdapterSetupRequested();
|
||||
}
|
||||
|
||||
void QnxAnalyzeSupport::startExecution()
|
||||
{
|
||||
if (state() == Inactive)
|
||||
return;
|
||||
|
||||
if (!setPort(m_qmlPort) && !m_qmlPort.isValid())
|
||||
return;
|
||||
|
||||
setState(StartingRemoteProcess);
|
||||
|
||||
StandardRunnable r = m_runnable;
|
||||
auto r = runnable().as<StandardRunnable>();
|
||||
if (!r.commandLineArguments.isEmpty())
|
||||
r.commandLineArguments += QLatin1Char(' ');
|
||||
r.commandLineArguments += QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlProfilerServices,
|
||||
m_qmlPort);
|
||||
appRunner()->start(r, device());
|
||||
}
|
||||
r.commandLineArguments += ' ';
|
||||
r.commandLineArguments +=
|
||||
QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlProfilerServices, port);
|
||||
|
||||
void QnxAnalyzeSupport::handleRemoteProcessFinished(bool success)
|
||||
runControl()->setRunnable(r);
|
||||
|
||||
SimpleTargetRunner::start();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// QnxDebugSupport
|
||||
|
||||
QnxAnalyzeSupport::QnxAnalyzeSupport(RunControl *runControl)
|
||||
: RunWorker(runControl)
|
||||
{
|
||||
if (!success)
|
||||
showMessage(tr("The %1 process closed unexpectedly.").arg(m_runnable.executable),
|
||||
NormalMessageFormat);
|
||||
runControl()->notifyRemoteFinished();
|
||||
setDisplayName("QnxAnalyzeSupport");
|
||||
appendMessage(tr("Preparing remote side..."), Utils::LogMessageFormat);
|
||||
|
||||
m_slog2Info->stop();
|
||||
auto portsGatherer = new PortsGatherer(runControl);
|
||||
|
||||
auto debuggeeRunner = new QnxAnalyzeeRunner(runControl);
|
||||
debuggeeRunner->addDependency(portsGatherer);
|
||||
|
||||
auto slog2InfoRunner = new Slog2InfoRunner(runControl);
|
||||
slog2InfoRunner->addDependency(debuggeeRunner);
|
||||
|
||||
addDependency(slog2InfoRunner);
|
||||
|
||||
// QmlDebug::QmlOutputParser m_outputParser;
|
||||
// FIXME: m_outputParser needs to be fed with application output
|
||||
// connect(&m_outputParser, &QmlDebug::QmlOutputParser::waitingForConnectionOnPort,
|
||||
// this, &QnxAnalyzeSupport::remoteIsRunning);
|
||||
|
||||
// m_outputParser.processOutput(msg);
|
||||
}
|
||||
|
||||
void QnxAnalyzeSupport::handleProgressReport(const QString &progressOutput)
|
||||
void QnxAnalyzeSupport::start()
|
||||
{
|
||||
showMessage(progressOutput + QLatin1Char('\n'), NormalMessageFormat);
|
||||
}
|
||||
|
||||
void QnxAnalyzeSupport::handleRemoteOutput(const QByteArray &output)
|
||||
{
|
||||
QTC_ASSERT(state() == Inactive || state() == Running, return);
|
||||
|
||||
showMessage(QString::fromUtf8(output), StdOutFormat);
|
||||
}
|
||||
|
||||
void QnxAnalyzeSupport::handleError(const QString &error)
|
||||
{
|
||||
if (state() == Running) {
|
||||
showMessage(error, ErrorMessageFormat);
|
||||
} else if (state() != Inactive) {
|
||||
showMessage(tr("Initial setup failed: %1").arg(error), NormalMessageFormat);
|
||||
setFinished();
|
||||
}
|
||||
}
|
||||
|
||||
void QnxAnalyzeSupport::remoteIsRunning()
|
||||
{
|
||||
runControl()->notifyRemoteSetupDone(m_qmlPort);
|
||||
}
|
||||
|
||||
void QnxAnalyzeSupport::showMessage(const QString &msg, OutputFormat format)
|
||||
{
|
||||
if (state() != Inactive)
|
||||
runControl()->appendMessage(msg, format);
|
||||
m_outputParser.processOutput(msg);
|
||||
}
|
||||
|
||||
void QnxAnalyzeSupport::printMissingWarning()
|
||||
{
|
||||
showMessage(tr("Warning: \"slog2info\" is not found on the device, debug output not available."),
|
||||
ErrorMessageFormat);
|
||||
// runControl()->notifyRemoteSetupDone(m_qmlPort);
|
||||
reportStarted();
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
@@ -25,18 +25,14 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "qnxabstractrunsupport.h"
|
||||
|
||||
#include <projectexplorer/runnables.h>
|
||||
#include <utils/outputformat.h>
|
||||
#include <qmldebug/qmloutputparser.h>
|
||||
#include <projectexplorer/runconfiguration.h>
|
||||
|
||||
namespace Qnx {
|
||||
namespace Internal {
|
||||
|
||||
class Slog2InfoRunner;
|
||||
|
||||
class QnxAnalyzeSupport : public QnxAbstractRunSupport
|
||||
class QnxAnalyzeSupport : public ProjectExplorer::RunWorker
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -44,24 +40,7 @@ public:
|
||||
explicit QnxAnalyzeSupport(ProjectExplorer::RunControl *runControl);
|
||||
|
||||
private:
|
||||
void handleAdapterSetupRequested() override;
|
||||
|
||||
void handleRemoteProcessFinished(bool success) override;
|
||||
void handleProgressReport(const QString &progressOutput) override;
|
||||
void handleRemoteOutput(const QByteArray &output) override;
|
||||
void handleError(const QString &error) override;
|
||||
|
||||
void showMessage(const QString &, Utils::OutputFormat);
|
||||
void printMissingWarning();
|
||||
|
||||
void remoteIsRunning();
|
||||
void startExecution() override;
|
||||
|
||||
ProjectExplorer::StandardRunnable m_runnable;
|
||||
QmlDebug::QmlOutputParser m_outputParser;
|
||||
Utils::Port m_qmlPort;
|
||||
|
||||
Slog2InfoRunner *m_slog2Info;
|
||||
void start() override;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
@@ -146,9 +146,9 @@ void QnxAttachDebugSupport::attachToProcess()
|
||||
stopPDebug();
|
||||
return;
|
||||
}
|
||||
connect(qobject_cast<Debugger::DebuggerRunTool *>(runControl->toolRunner()),
|
||||
&Debugger::DebuggerRunTool::stateChanged,
|
||||
this, &QnxAttachDebugSupport::handleDebuggerStateChanged);
|
||||
// connect(qobject_cast<Debugger::DebuggerRunTool *>(runControl->toolRunner()),
|
||||
// &Debugger::DebuggerRunTool::stateChanged,
|
||||
// this, &QnxAttachDebugSupport::handleDebuggerStateChanged);
|
||||
ProjectExplorerPlugin::startRunControl(runControl);
|
||||
}
|
||||
|
||||
|
@@ -28,182 +28,123 @@
|
||||
#include "qnxdevice.h"
|
||||
#include "qnxrunconfiguration.h"
|
||||
#include "slog2inforunner.h"
|
||||
#include "qnxqtversion.h"
|
||||
#include "qnxutils.h"
|
||||
|
||||
#include <debugger/debuggerrunconfigurationaspect.h>
|
||||
#include <debugger/debuggerruncontrol.h>
|
||||
#include <debugger/debuggerstartparameters.h>
|
||||
|
||||
#include <projectexplorer/applicationlauncher.h>
|
||||
#include <projectexplorer/devicesupport/deviceusedportsgatherer.h>
|
||||
#include <projectexplorer/kitinformation.h>
|
||||
#include <projectexplorer/runnables.h>
|
||||
#include <projectexplorer/target.h>
|
||||
|
||||
#include <qmldebug/qmldebugcommandlinearguments.h>
|
||||
#include <qtsupport/qtkitinformation.h>
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/qtcprocess.h>
|
||||
#include <qmldebug/qmldebugcommandlinearguments.h>
|
||||
|
||||
using namespace Debugger;
|
||||
using namespace ProjectExplorer;
|
||||
|
||||
namespace Qnx {
|
||||
namespace Internal {
|
||||
|
||||
QnxDebugSupport::QnxDebugSupport(RunControl *runControl)
|
||||
: QnxAbstractRunSupport(runControl)
|
||||
// QnxDebuggeeRunner
|
||||
|
||||
class QnxDebuggeeRunner : public ProjectExplorer::SimpleTargetRunner
|
||||
{
|
||||
auto runConfig = runControl->runConfiguration();
|
||||
m_useCppDebugger = runConfig->extraAspect<Debugger::DebuggerRunConfigurationAspect>()->useCppDebugger();
|
||||
m_useQmlDebugger = runConfig->extraAspect<Debugger::DebuggerRunConfigurationAspect>()->useQmlDebugger();
|
||||
m_runnable = runConfig->runnable().as<StandardRunnable>();
|
||||
|
||||
const ApplicationLauncher *runner = appRunner();
|
||||
connect(runner, &ApplicationLauncher::reportError, this, &QnxDebugSupport::handleError);
|
||||
connect(runner, &ApplicationLauncher::remoteProcessStarted, this, &QnxDebugSupport::handleRemoteProcessStarted);
|
||||
connect(runner, &ApplicationLauncher::finished, this, &QnxDebugSupport::handleRemoteProcessFinished);
|
||||
connect(runner, &ApplicationLauncher::reportProgress, this, &QnxDebugSupport::handleProgressReport);
|
||||
connect(runner, &ApplicationLauncher::remoteStdout, this, &QnxDebugSupport::handleRemoteOutput);
|
||||
connect(runner, &ApplicationLauncher::remoteStderr, this, &QnxDebugSupport::handleRemoteOutput);
|
||||
|
||||
connect(toolRunner(), &Debugger::DebuggerRunTool::requestRemoteSetup,
|
||||
this, &QnxDebugSupport::handleAdapterSetupRequested);
|
||||
connect(runControl, &RunControl::finished,
|
||||
this, &QnxDebugSupport::handleDebuggingFinished);
|
||||
|
||||
auto qnxRunConfig = qobject_cast<QnxRunConfiguration *>(runControl->runConfiguration());
|
||||
const QString applicationId = Utils::FileName::fromString(qnxRunConfig->remoteExecutableFilePath()).fileName();
|
||||
IDevice::ConstPtr dev = DeviceKitInformation::device(runConfig->target()->kit());
|
||||
QnxDevice::ConstPtr qnxDevice = dev.dynamicCast<const QnxDevice>();
|
||||
|
||||
m_slog2Info = new Slog2InfoRunner(applicationId, qnxDevice, this);
|
||||
connect(m_slog2Info, &Slog2InfoRunner::output, this, &QnxDebugSupport::handleApplicationOutput);
|
||||
connect(runner, &ApplicationLauncher::remoteProcessStarted, m_slog2Info, &Slog2InfoRunner::start);
|
||||
if (qnxDevice->qnxVersion() > 0x060500)
|
||||
connect(m_slog2Info, &Slog2InfoRunner::commandMissing, this, &QnxDebugSupport::printMissingWarning);
|
||||
public:
|
||||
QnxDebuggeeRunner(ProjectExplorer::RunControl *runControl)
|
||||
: SimpleTargetRunner(runControl)
|
||||
{
|
||||
setDisplayName("QnxDebuggeeRunner");
|
||||
}
|
||||
|
||||
void QnxDebugSupport::handleAdapterSetupRequested()
|
||||
private:
|
||||
void start() override
|
||||
{
|
||||
QTC_ASSERT(state() == Inactive, return);
|
||||
auto portsGatherer = runControl()->worker<GdbServerPortsGatherer>();
|
||||
|
||||
toolRunner()->showMessage(tr("Preparing remote side...") + '\n', Debugger::AppStuff);
|
||||
QnxAbstractRunSupport::handleAdapterSetupRequested();
|
||||
}
|
||||
|
||||
void QnxDebugSupport::startExecution()
|
||||
{
|
||||
if (state() == Inactive)
|
||||
return;
|
||||
|
||||
if (m_useCppDebugger && !setPort(m_pdebugPort))
|
||||
return;
|
||||
if (m_useQmlDebugger && !setPort(m_qmlPort))
|
||||
return;
|
||||
|
||||
setState(StartingRemoteProcess);
|
||||
|
||||
StandardRunnable r = m_runnable;
|
||||
StandardRunnable r = runnable().as<StandardRunnable>();
|
||||
QStringList arguments;
|
||||
if (m_useCppDebugger)
|
||||
arguments << QString::number(m_pdebugPort.number());
|
||||
else {
|
||||
if (m_useQmlDebugger) {
|
||||
if (portsGatherer->useGdbServer()) {
|
||||
Utils::Port pdebugPort = portsGatherer->gdbServerPort();
|
||||
r.executable = Constants::QNX_DEBUG_EXECUTABLE;
|
||||
arguments.append(pdebugPort.toString());
|
||||
}
|
||||
if (portsGatherer->useQmlServer()) {
|
||||
arguments.append(QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices,
|
||||
m_qmlPort));
|
||||
portsGatherer->qmlServerPort()));
|
||||
}
|
||||
arguments.append(Utils::QtcProcess::splitArgs(r.commandLineArguments));
|
||||
}
|
||||
|
||||
r.executable = processExecutable();
|
||||
r.commandLineArguments = Utils::QtcProcess::joinArgs(arguments);
|
||||
r.environment = m_runnable.environment;
|
||||
r.workingDirectory = m_runnable.workingDirectory;
|
||||
appRunner()->start(r, device());
|
||||
}
|
||||
|
||||
void QnxDebugSupport::handleRemoteProcessStarted()
|
||||
SimpleTargetRunner::start();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// QnxDebugSupport
|
||||
|
||||
QnxDebugSupport::QnxDebugSupport(RunControl *runControl)
|
||||
: DebuggerRunTool(runControl)
|
||||
{
|
||||
QnxAbstractRunSupport::handleRemoteProcessStarted();
|
||||
Debugger::RemoteSetupResult result;
|
||||
result.success = true;
|
||||
result.gdbServerPort = m_pdebugPort;
|
||||
result.qmlServerPort = m_qmlPort;
|
||||
toolRunner()->notifyEngineRemoteSetupFinished(result);
|
||||
setDisplayName("QnxDebugSupport");
|
||||
appendMessage(tr("Preparing remote side..."), Utils::LogMessageFormat);
|
||||
|
||||
auto portsGatherer = new GdbServerPortsGatherer(runControl);
|
||||
portsGatherer->setUseGdbServer(isCppDebugging());
|
||||
portsGatherer->setUseQmlServer(isQmlDebugging());
|
||||
|
||||
auto debuggeeRunner = new QnxDebuggeeRunner(runControl);
|
||||
debuggeeRunner->addDependency(portsGatherer);
|
||||
|
||||
auto slog2InfoRunner = new Slog2InfoRunner(runControl);
|
||||
slog2InfoRunner->addDependency(debuggeeRunner);
|
||||
|
||||
addDependency(slog2InfoRunner);
|
||||
}
|
||||
|
||||
void QnxDebugSupport::handleRemoteProcessFinished(bool success)
|
||||
void QnxDebugSupport::start()
|
||||
{
|
||||
if (state() == Inactive)
|
||||
return;
|
||||
auto portsGatherer = runControl()->worker<GdbServerPortsGatherer>();
|
||||
Utils::Port pdebugPort = portsGatherer->gdbServerPort();
|
||||
|
||||
if (state() == Running) {
|
||||
if (!success)
|
||||
toolRunner()->notifyInferiorIll();
|
||||
auto runConfig = qobject_cast<QnxRunConfiguration *>(runControl()->runConfiguration());
|
||||
QTC_ASSERT(runConfig, return);
|
||||
Target *target = runConfig->target();
|
||||
Kit *k = target->kit();
|
||||
|
||||
} else {
|
||||
Debugger::RemoteSetupResult result;
|
||||
result.success = false;
|
||||
result.reason = tr("The %1 process closed unexpectedly.").arg(processExecutable());
|
||||
toolRunner()->notifyEngineRemoteSetupFinished(result);
|
||||
}
|
||||
DebuggerStartParameters params;
|
||||
params.startMode = AttachToRemoteServer;
|
||||
params.useCtrlCStub = true;
|
||||
params.inferior.executable = runConfig->remoteExecutableFilePath();
|
||||
params.symbolFile = runConfig->localExecutableFilePath();
|
||||
params.remoteChannel = QString("%1:%2").arg(device()->sshParameters().host).arg(pdebugPort.number());
|
||||
params.closeMode = KillAtClose;
|
||||
params.inferior.commandLineArguments = runConfig->arguments();
|
||||
|
||||
if (isQmlDebugging()) {
|
||||
params.qmlServer.host = device()->sshParameters().host;
|
||||
params.qmlServer.port = portsGatherer->qmlServerPort();
|
||||
params.inferior.commandLineArguments.replace("%qml_port%", params.qmlServer.port.toString());
|
||||
}
|
||||
|
||||
void QnxDebugSupport::handleDebuggingFinished()
|
||||
auto qtVersion = dynamic_cast<QnxQtVersion *>(QtSupport::QtKitInformation::qtVersion(k));
|
||||
if (qtVersion)
|
||||
params.solibSearchPath = QnxUtils::searchPaths(qtVersion);
|
||||
|
||||
reportStarted();
|
||||
}
|
||||
|
||||
void QnxDebugSupport::stop()
|
||||
{
|
||||
// setFinished() will kill "pdebug", but we also have to kill
|
||||
// the inferior process, as invoking "kill" in gdb doesn't work
|
||||
// on QNX gdb
|
||||
setFinished();
|
||||
m_slog2Info->stop();
|
||||
killInferiorProcess();
|
||||
}
|
||||
|
||||
QString QnxDebugSupport::processExecutable() const
|
||||
{
|
||||
return m_useCppDebugger? QLatin1String(Constants::QNX_DEBUG_EXECUTABLE) : m_runnable.executable;
|
||||
}
|
||||
|
||||
void QnxDebugSupport::killInferiorProcess()
|
||||
{
|
||||
device()->signalOperation()->killProcess(m_runnable.executable);
|
||||
}
|
||||
|
||||
void QnxDebugSupport::handleProgressReport(const QString &progressOutput)
|
||||
{
|
||||
toolRunner()->showMessage(progressOutput + QLatin1Char('\n'), Debugger::AppStuff);
|
||||
}
|
||||
|
||||
void QnxDebugSupport::handleRemoteOutput(const QByteArray &output)
|
||||
{
|
||||
QTC_ASSERT(state() == Inactive || state() == Running, return);
|
||||
toolRunner()->showMessage(QString::fromUtf8(output), Debugger::AppOutput);
|
||||
}
|
||||
|
||||
void QnxDebugSupport::handleError(const QString &error)
|
||||
{
|
||||
if (state() == Running) {
|
||||
toolRunner()->showMessage(error, Debugger::AppError);
|
||||
toolRunner()->notifyInferiorIll();
|
||||
} else if (state() != Inactive) {
|
||||
setFinished();
|
||||
Debugger::RemoteSetupResult result;
|
||||
result.success = false;
|
||||
result.reason = tr("Initial setup failed: %1").arg(error);
|
||||
toolRunner()->notifyEngineRemoteSetupFinished(result);
|
||||
}
|
||||
}
|
||||
|
||||
void QnxDebugSupport::printMissingWarning()
|
||||
{
|
||||
toolRunner()->showMessage(tr("Warning: \"slog2info\" is not found "
|
||||
"on the device, debug output not available."), Debugger::AppError);
|
||||
}
|
||||
|
||||
void QnxDebugSupport::handleApplicationOutput(const QString &msg, Utils::OutputFormat outputFormat)
|
||||
{
|
||||
Q_UNUSED(outputFormat);
|
||||
toolRunner()->showMessage(msg, Debugger::AppOutput);
|
||||
}
|
||||
|
||||
Debugger::DebuggerRunTool *QnxDebugSupport::toolRunner()
|
||||
{
|
||||
return qobject_cast<Debugger::DebuggerRunTool *>(runControl()->toolRunner());
|
||||
// We have to kill the inferior process, as invoking "kill" in
|
||||
// gdb doesn't work on QNX gdb.
|
||||
auto stdRunnable = runnable().as<StandardRunnable>();
|
||||
device()->signalOperation()->killProcess(stdRunnable.executable);
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
@@ -25,55 +25,21 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "qnxabstractrunsupport.h"
|
||||
|
||||
#include <projectexplorer/runnables.h>
|
||||
|
||||
#include <utils/outputformat.h>
|
||||
|
||||
namespace Debugger { class DebuggerRunTool; }
|
||||
#include <debugger/debuggerruncontrol.h>
|
||||
|
||||
namespace Qnx {
|
||||
namespace Internal {
|
||||
|
||||
class Slog2InfoRunner;
|
||||
|
||||
class QnxDebugSupport : public QnxAbstractRunSupport
|
||||
class QnxDebugSupport : public Debugger::DebuggerRunTool
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QnxDebugSupport(ProjectExplorer::RunControl *runControl);
|
||||
|
||||
void handleDebuggingFinished();
|
||||
|
||||
private:
|
||||
void handleAdapterSetupRequested() override;
|
||||
|
||||
void handleRemoteProcessStarted() override;
|
||||
void handleRemoteProcessFinished(bool success) override;
|
||||
void handleProgressReport(const QString &progressOutput) override;
|
||||
void handleRemoteOutput(const QByteArray &output) override;
|
||||
void handleError(const QString &error) override;
|
||||
|
||||
void printMissingWarning();
|
||||
void handleApplicationOutput(const QString &msg, Utils::OutputFormat outputFormat);
|
||||
|
||||
void startExecution() override;
|
||||
|
||||
Debugger::DebuggerRunTool *toolRunner();
|
||||
QString processExecutable() const;
|
||||
|
||||
void killInferiorProcess();
|
||||
|
||||
ProjectExplorer::StandardRunnable m_runnable;
|
||||
Slog2InfoRunner *m_slog2Info;
|
||||
|
||||
Utils::Port m_pdebugPort;
|
||||
Utils::Port m_qmlPort;
|
||||
|
||||
bool m_useCppDebugger;
|
||||
bool m_useQmlDebugger;
|
||||
void start() override;
|
||||
void stop() override;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
@@ -1,72 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 BlackBerry Limited. All rights reserved.
|
||||
** Contact: KDAB (info@kdab.com)
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qnxruncontrol.h"
|
||||
#include "qnxdevice.h"
|
||||
#include "qnxrunconfiguration.h"
|
||||
#include "slog2inforunner.h"
|
||||
|
||||
#include <projectexplorer/kitinformation.h>
|
||||
#include <projectexplorer/runconfiguration.h>
|
||||
#include <projectexplorer/target.h>
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
using namespace Utils;
|
||||
|
||||
namespace Qnx {
|
||||
namespace Internal {
|
||||
|
||||
QnxRunControl::QnxRunControl(RunConfiguration *runConfig)
|
||||
: RunControl(runConfig, ProjectExplorer::Constants::NORMAL_RUN_MODE)
|
||||
, m_slog2Info(0)
|
||||
{
|
||||
IDevice::ConstPtr dev = DeviceKitInformation::device(runConfig->target()->kit());
|
||||
QnxDevice::ConstPtr qnxDevice = dev.dynamicCast<const QnxDevice>();
|
||||
|
||||
QnxRunConfiguration *qnxRunConfig = qobject_cast<QnxRunConfiguration *>(runConfig);
|
||||
QTC_CHECK(qnxRunConfig);
|
||||
|
||||
const QString applicationId = FileName::fromString(qnxRunConfig->remoteExecutableFilePath()).fileName();
|
||||
m_slog2Info = new Slog2InfoRunner(applicationId, qnxDevice, this);
|
||||
connect(m_slog2Info, &Slog2InfoRunner::output,
|
||||
this, static_cast<void(RunControl::*)(const QString &, OutputFormat)>(&RunControl::appendMessage));
|
||||
connect(this, &RunControl::started, m_slog2Info, &Slog2InfoRunner::start);
|
||||
if (qnxDevice->qnxVersion() > 0x060500)
|
||||
connect(m_slog2Info, &Slog2InfoRunner::commandMissing, this, &QnxRunControl::printMissingWarning);
|
||||
}
|
||||
|
||||
void QnxRunControl::stop()
|
||||
{
|
||||
m_slog2Info->stop();
|
||||
RunControl::stop();
|
||||
}
|
||||
|
||||
void QnxRunControl::printMissingWarning()
|
||||
{
|
||||
appendMessage(tr("Warning: \"slog2info\" is not found on the device, debug output not available."), ErrorMessageFormat);
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Qnx
|
@@ -1,50 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 BlackBerry Limited. All rights reserved.
|
||||
** Contact: KDAB (info@kdab.com)
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <projectexplorer/runconfiguration.h>
|
||||
|
||||
namespace Qnx {
|
||||
namespace Internal {
|
||||
|
||||
class Slog2InfoRunner;
|
||||
|
||||
class QnxRunControl : public ProjectExplorer::RunControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QnxRunControl(ProjectExplorer::RunConfiguration *runConfig);
|
||||
|
||||
void stop() override;
|
||||
|
||||
private:
|
||||
void printMissingWarning();
|
||||
|
||||
Slog2InfoRunner *m_slog2Info;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Qnx
|
@@ -30,7 +30,7 @@
|
||||
#include "qnxdevice.h"
|
||||
#include "qnxanalyzesupport.h"
|
||||
#include "qnxqtversion.h"
|
||||
#include "qnxruncontrol.h"
|
||||
#include "slog2inforunner.h"
|
||||
#include "qnxutils.h"
|
||||
|
||||
#include <debugger/debuggerruncontrol.h>
|
||||
@@ -53,38 +53,6 @@ using namespace ProjectExplorer;
|
||||
namespace Qnx {
|
||||
namespace Internal {
|
||||
|
||||
static DebuggerStartParameters createDebuggerStartParameters(QnxRunConfiguration *runConfig)
|
||||
{
|
||||
DebuggerStartParameters params;
|
||||
Target *target = runConfig->target();
|
||||
Kit *k = target->kit();
|
||||
|
||||
const IDevice::ConstPtr device = DeviceKitInformation::device(k);
|
||||
if (device.isNull())
|
||||
return params;
|
||||
|
||||
params.startMode = AttachToRemoteServer;
|
||||
params.useCtrlCStub = true;
|
||||
params.inferior.executable = runConfig->remoteExecutableFilePath();
|
||||
params.symbolFile = runConfig->localExecutableFilePath();
|
||||
params.remoteChannel = device->sshParameters().host + QLatin1String(":-1");
|
||||
params.remoteSetupNeeded = true;
|
||||
params.closeMode = KillAtClose;
|
||||
params.inferior.commandLineArguments = runConfig->arguments();
|
||||
|
||||
auto aspect = runConfig->extraAspect<DebuggerRunConfigurationAspect>();
|
||||
if (aspect->useQmlDebugger()) {
|
||||
params.qmlServer.host = device->sshParameters().host;
|
||||
params.qmlServer.port = Utils::Port(); // QML port is handed out later
|
||||
}
|
||||
|
||||
auto qtVersion = dynamic_cast<QnxQtVersion *>(QtSupport::QtKitInformation::qtVersion(k));
|
||||
if (qtVersion)
|
||||
params.solibSearchPath = QnxUtils::searchPaths(qtVersion);
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
QnxRunControlFactory::QnxRunControlFactory(QObject *parent)
|
||||
: IRunControlFactory(parent)
|
||||
{
|
||||
@@ -108,48 +76,28 @@ bool QnxRunControlFactory::canRun(RunConfiguration *runConfiguration, Core::Id m
|
||||
if (dev.isNull())
|
||||
return false;
|
||||
|
||||
if (mode == ProjectExplorer::Constants::DEBUG_RUN_MODE
|
||||
|| mode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) {
|
||||
auto aspect = runConfiguration->extraAspect<DebuggerRunConfigurationAspect>();
|
||||
int portsUsed = aspect ? aspect->portsUsedByDebugger() : 0;
|
||||
return portsUsed <= dev->freePorts().count();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
RunControl *QnxRunControlFactory::create(RunConfiguration *runConfig, Core::Id mode, QString *)
|
||||
{
|
||||
QTC_ASSERT(canRun(runConfig, mode), return 0);
|
||||
auto rc = qobject_cast<QnxRunConfiguration *>(runConfig);
|
||||
QTC_ASSERT(rc, return 0);
|
||||
|
||||
if (mode == ProjectExplorer::Constants::NORMAL_RUN_MODE) {
|
||||
auto runControl = new QnxRunControl(rc);
|
||||
auto runControl = new RunControl(runConfig, mode);
|
||||
(void) new SimpleTargetRunner(runControl);
|
||||
return runControl;
|
||||
}
|
||||
|
||||
if (mode == ProjectExplorer::Constants::DEBUG_RUN_MODE) {
|
||||
const DebuggerStartParameters params = createDebuggerStartParameters(rc);
|
||||
auto runControl = new RunControl(runConfig, mode);
|
||||
// (void) new DebuggerRunTool(runControl, params, errorMessage); FIXME
|
||||
(void) new QnxDebugSupport(runControl);
|
||||
return runControl;
|
||||
}
|
||||
|
||||
if (mode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) {
|
||||
Kit *kit = runConfig->target()->kit();
|
||||
const IDevice::ConstPtr device = DeviceKitInformation::device(kit);
|
||||
if (device.isNull())
|
||||
return 0;
|
||||
RunControl *runControl = Debugger::createAnalyzerRunControl(runConfig, mode);
|
||||
QTC_ASSERT(runControl, return 0);
|
||||
AnalyzerConnection connection;
|
||||
connection.connParams = device->sshParameters();
|
||||
connection.analyzerHost = connection.connParams.host;
|
||||
connection.analyzerPort = Utils::Port(connection.connParams.port);
|
||||
runControl->setConnection(connection);
|
||||
RunControl *runControl = new RunControl(runConfig, mode);
|
||||
runControl->createWorker(mode);
|
||||
(void) new QnxAnalyzeSupport(runControl);
|
||||
return runControl;
|
||||
}
|
||||
|
@@ -25,7 +25,9 @@
|
||||
|
||||
#include "slog2inforunner.h"
|
||||
|
||||
#include "qnxdevice.h"
|
||||
#include "qnxdeviceprocess.h"
|
||||
#include "qnxrunconfiguration.h"
|
||||
|
||||
#include <projectexplorer/runnables.h>
|
||||
#include <utils/qtcassert.h>
|
||||
@@ -33,28 +35,33 @@
|
||||
#include <QRegExp>
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
using namespace Utils;
|
||||
|
||||
namespace Qnx {
|
||||
namespace Internal {
|
||||
|
||||
Slog2InfoRunner::Slog2InfoRunner(const QString &applicationId,
|
||||
const RemoteLinux::LinuxDevice::ConstPtr &device, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_applicationId(applicationId)
|
||||
, m_found(false)
|
||||
, m_currentLogs(false)
|
||||
Slog2InfoRunner::Slog2InfoRunner(RunControl *runControl)
|
||||
: RunWorker(runControl)
|
||||
{
|
||||
auto qnxRunConfig = qobject_cast<QnxRunConfiguration *>(runControl->runConfiguration());
|
||||
QTC_ASSERT(qnxRunConfig, return);
|
||||
m_applicationId = FileName::fromString(qnxRunConfig->remoteExecutableFilePath()).fileName();
|
||||
}
|
||||
|
||||
void Slog2InfoRunner::printMissingWarning()
|
||||
{
|
||||
appendMessage(tr("Warning: \"slog2info\" is not found on the device, debug output not available."), ErrorMessageFormat);
|
||||
// See QTCREATORBUG-10712 for details.
|
||||
// We need to limit length of ApplicationId to 63 otherwise it would not match one in slog2info.
|
||||
m_applicationId.truncate(63);
|
||||
|
||||
m_testProcess = new QnxDeviceProcess(device, this);
|
||||
m_testProcess = new QnxDeviceProcess(device(), this);
|
||||
connect(m_testProcess, &DeviceProcess::finished, this, &Slog2InfoRunner::handleTestProcessCompleted);
|
||||
|
||||
m_launchDateTimeProcess = new SshDeviceProcess(device, this);
|
||||
m_launchDateTimeProcess = new SshDeviceProcess(device(), this);
|
||||
connect(m_launchDateTimeProcess, &DeviceProcess::finished, this, &Slog2InfoRunner::launchSlog2Info);
|
||||
|
||||
m_logProcess = new QnxDeviceProcess(device, this);
|
||||
m_logProcess = new QnxDeviceProcess(device(), this);
|
||||
connect(m_logProcess, &DeviceProcess::readyReadStandardOutput, this, &Slog2InfoRunner::readLogStandardOutput);
|
||||
connect(m_logProcess, &DeviceProcess::readyReadStandardError, this, &Slog2InfoRunner::readLogStandardError);
|
||||
connect(m_logProcess, &DeviceProcess::error, this, &Slog2InfoRunner::handleLogError);
|
||||
@@ -88,10 +95,14 @@ bool Slog2InfoRunner::commandFound() const
|
||||
void Slog2InfoRunner::handleTestProcessCompleted()
|
||||
{
|
||||
m_found = (m_testProcess->exitCode() == 0);
|
||||
if (m_found)
|
||||
if (m_found) {
|
||||
readLaunchTime();
|
||||
else
|
||||
emit commandMissing();
|
||||
} else {
|
||||
QnxDevice::ConstPtr qnxDevice = device().dynamicCast<const QnxDevice>();
|
||||
if (qnxDevice->qnxVersion() > 0x060500) {
|
||||
printMissingWarning();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Slog2InfoRunner::readLaunchTime()
|
||||
@@ -174,18 +185,18 @@ void Slog2InfoRunner::processLogLine(const QString &line)
|
||||
if (bufferName == QLatin1String("default") && bufferId == 8900)
|
||||
return;
|
||||
|
||||
emit output(regexp.cap(6).trimmed() + QLatin1Char('\n'), Utils::StdOutFormat);
|
||||
appendMessage(regexp.cap(6).trimmed() + '\n', Utils::StdOutFormat);
|
||||
}
|
||||
|
||||
void Slog2InfoRunner::readLogStandardError()
|
||||
{
|
||||
const QString message = QString::fromLatin1(m_logProcess->readAllStandardError());
|
||||
emit output(message, Utils::StdErrFormat);
|
||||
appendMessage(QString::fromLatin1(m_logProcess->readAllStandardError()), Utils::StdErrFormat);
|
||||
}
|
||||
|
||||
void Slog2InfoRunner::handleLogError()
|
||||
{
|
||||
emit output(tr("Cannot show slog2info output. Error: %1").arg(m_logProcess->errorString()), Utils::StdErrFormat);
|
||||
appendMessage(tr("Cannot show slog2info output. Error: %1")
|
||||
.arg(m_logProcess->errorString()), Utils::StdErrFormat);
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
@@ -27,6 +27,7 @@
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <projectexplorer/runconfiguration.h>
|
||||
#include <remotelinux/linuxdevice.h>
|
||||
#include <utils/outputformat.h>
|
||||
|
||||
@@ -38,26 +39,23 @@ namespace ProjectExplorer { class SshDeviceProcess; }
|
||||
namespace Qnx {
|
||||
namespace Internal {
|
||||
|
||||
class Slog2InfoRunner : public QObject
|
||||
class Slog2InfoRunner : public ProjectExplorer::RunWorker
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit Slog2InfoRunner(const QString &applicationId, const RemoteLinux::LinuxDevice::ConstPtr &device, QObject *parent = 0);
|
||||
explicit Slog2InfoRunner(ProjectExplorer::RunControl *runControl);
|
||||
|
||||
void stop();
|
||||
void start() override;
|
||||
void stop() override;
|
||||
|
||||
bool commandFound() const;
|
||||
|
||||
public slots:
|
||||
void start();
|
||||
|
||||
signals:
|
||||
void commandMissing();
|
||||
void started();
|
||||
void finished();
|
||||
void output(const QString &msg, Utils::OutputFormat format);
|
||||
|
||||
private slots:
|
||||
private:
|
||||
void handleTestProcessCompleted();
|
||||
void launchSlog2Info();
|
||||
|
||||
@@ -65,22 +63,21 @@ private slots:
|
||||
void readLogStandardError();
|
||||
void handleLogError();
|
||||
|
||||
private:
|
||||
void printMissingWarning();
|
||||
void readLaunchTime();
|
||||
void processLog(bool force);
|
||||
void processLogLine(const QString &line);
|
||||
|
||||
QString m_applicationId;
|
||||
|
||||
bool m_found;
|
||||
|
||||
QDateTime m_launchDateTime;
|
||||
bool m_currentLogs;
|
||||
bool m_found = false;
|
||||
bool m_currentLogs = false;
|
||||
QString m_remainingData;
|
||||
|
||||
ProjectExplorer::SshDeviceProcess *m_launchDateTimeProcess;
|
||||
ProjectExplorer::SshDeviceProcess *m_testProcess;
|
||||
ProjectExplorer::SshDeviceProcess *m_logProcess;
|
||||
ProjectExplorer::SshDeviceProcess *m_launchDateTimeProcess = nullptr;
|
||||
ProjectExplorer::SshDeviceProcess *m_testProcess = nullptr;
|
||||
ProjectExplorer::SshDeviceProcess *m_logProcess = nullptr;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
@@ -25,89 +25,34 @@
|
||||
|
||||
#include "abstractremotelinuxrunsupport.h"
|
||||
|
||||
#include <projectexplorer/devicesupport/deviceusedportsgatherer.h>
|
||||
#include <projectexplorer/kitinformation.h>
|
||||
#include <projectexplorer/runnables.h>
|
||||
#include <projectexplorer/target.h>
|
||||
|
||||
#include <utils/environment.h>
|
||||
#include <utils/portlist.h>
|
||||
#include <utils/qtcprocess.h>
|
||||
|
||||
#include <qmldebug/qmldebugcommandlinearguments.h>
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
using namespace Utils;
|
||||
|
||||
namespace RemoteLinux {
|
||||
namespace Internal {
|
||||
|
||||
class AbstractRemoteLinuxRunSupportPrivate
|
||||
// FifoGatherer
|
||||
|
||||
FifoGatherer::FifoGatherer(RunControl *runControl)
|
||||
: RunWorker(runControl)
|
||||
{
|
||||
public:
|
||||
ApplicationLauncher launcher;
|
||||
DeviceUsedPortsGatherer portsGatherer;
|
||||
ApplicationLauncher fifoCreator;
|
||||
PortList portList;
|
||||
QString fifo;
|
||||
bool usesFifo = false;
|
||||
};
|
||||
setDisplayName("FifoGatherer");
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
using namespace Internal;
|
||||
|
||||
AbstractRemoteLinuxRunSupport::AbstractRemoteLinuxRunSupport(RunControl *runControl)
|
||||
: TargetRunner(runControl),
|
||||
d(new AbstractRemoteLinuxRunSupportPrivate)
|
||||
FifoGatherer::~FifoGatherer()
|
||||
{
|
||||
}
|
||||
|
||||
AbstractRemoteLinuxRunSupport::~AbstractRemoteLinuxRunSupport()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
ApplicationLauncher *AbstractRemoteLinuxRunSupport::applicationLauncher()
|
||||
{
|
||||
return &d->launcher;
|
||||
}
|
||||
|
||||
void AbstractRemoteLinuxRunSupport::setUsesFifo(bool on)
|
||||
{
|
||||
d->usesFifo = on;
|
||||
}
|
||||
|
||||
Port AbstractRemoteLinuxRunSupport::findPort() const
|
||||
{
|
||||
return d->portsGatherer.getNextFreePort(&d->portList);
|
||||
}
|
||||
|
||||
QString AbstractRemoteLinuxRunSupport::fifo() const
|
||||
{
|
||||
return d->fifo;
|
||||
}
|
||||
|
||||
void AbstractRemoteLinuxRunSupport::prepare()
|
||||
{
|
||||
if (d->usesFifo)
|
||||
createRemoteFifo();
|
||||
else
|
||||
startPortsGathering();
|
||||
}
|
||||
|
||||
void AbstractRemoteLinuxRunSupport::startPortsGathering()
|
||||
{
|
||||
appendMessage(tr("Checking available ports...") + '\n', NormalMessageFormat);
|
||||
connect(&d->portsGatherer, &DeviceUsedPortsGatherer::error, this, [&](const QString &msg) {
|
||||
reportFailure(msg);
|
||||
});
|
||||
connect(&d->portsGatherer, &DeviceUsedPortsGatherer::portListReady, this, [&] {
|
||||
d->portList = device()->freePorts();
|
||||
//appendMessage(tr("Found %1 free ports").arg(d->portList.count()), NormalMessageFormat);
|
||||
reportSuccess();
|
||||
});
|
||||
d->portsGatherer.start(device());
|
||||
}
|
||||
|
||||
void AbstractRemoteLinuxRunSupport::createRemoteFifo()
|
||||
void FifoGatherer::start()
|
||||
{
|
||||
appendMessage(tr("Creating remote socket...") + '\n', NormalMessageFormat);
|
||||
|
||||
@@ -120,77 +65,35 @@ void AbstractRemoteLinuxRunSupport::createRemoteFifo()
|
||||
QSharedPointer<QByteArray> output(new QByteArray);
|
||||
QSharedPointer<QByteArray> errors(new QByteArray);
|
||||
|
||||
connect(&d->fifoCreator, &ApplicationLauncher::finished,
|
||||
connect(&m_fifoCreator, &ApplicationLauncher::finished,
|
||||
this, [this, output, errors](bool success) {
|
||||
if (!success) {
|
||||
reportFailure(QString("Failed to create fifo: %1").arg(QLatin1String(*errors)));
|
||||
} else {
|
||||
d->fifo = QString::fromLatin1(*output);
|
||||
//appendMessage(tr("Created fifo").arg(d->fifo), NormalMessageFormat);
|
||||
reportSuccess();
|
||||
m_fifo = QString::fromLatin1(*output);
|
||||
appendMessage(tr("Created fifo: %1").arg(m_fifo), NormalMessageFormat);
|
||||
reportStarted();
|
||||
}
|
||||
});
|
||||
|
||||
connect(&d->fifoCreator, &ApplicationLauncher::remoteStdout,
|
||||
connect(&m_fifoCreator, &ApplicationLauncher::remoteStdout,
|
||||
this, [output](const QByteArray &data) {
|
||||
output->append(data);
|
||||
});
|
||||
|
||||
connect(&d->fifoCreator, &ApplicationLauncher::remoteStderr,
|
||||
this, [errors](const QByteArray &data) {
|
||||
errors->append(data);
|
||||
connect(&m_fifoCreator, &ApplicationLauncher::remoteStderr,
|
||||
this, [this, errors](const QByteArray &) {
|
||||
reportFailure();
|
||||
// errors->append(data);
|
||||
});
|
||||
|
||||
d->fifoCreator.start(r, device());
|
||||
m_fifoCreator.start(r, device());
|
||||
}
|
||||
|
||||
void AbstractRemoteLinuxRunSupport::start()
|
||||
void FifoGatherer::onFinished()
|
||||
{
|
||||
connect(&d->launcher, &ApplicationLauncher::remoteStderr,
|
||||
this, &AbstractRemoteLinuxRunSupport::handleRemoteErrorOutput);
|
||||
connect(&d->launcher, &ApplicationLauncher::remoteStdout,
|
||||
this, &AbstractRemoteLinuxRunSupport::handleRemoteOutput);
|
||||
connect(&d->launcher, &ApplicationLauncher::finished,
|
||||
this, &AbstractRemoteLinuxRunSupport::handleAppRunnerFinished);
|
||||
connect(&d->launcher, &ApplicationLauncher::reportProgress,
|
||||
this, &AbstractRemoteLinuxRunSupport::handleProgressReport);
|
||||
connect(&d->launcher, &ApplicationLauncher::reportError,
|
||||
this, &AbstractRemoteLinuxRunSupport::handleAppRunnerError);
|
||||
connect(&d->launcher, &ApplicationLauncher::remoteProcessStarted,
|
||||
this, &TargetRunner::reportSuccess);
|
||||
d->launcher.start(runControl()->runnable(), device());
|
||||
m_fifoCreator.stop();
|
||||
}
|
||||
|
||||
void AbstractRemoteLinuxRunSupport::onFinished()
|
||||
{
|
||||
d->launcher.disconnect(this);
|
||||
d->launcher.stop();
|
||||
d->portsGatherer.disconnect(this);
|
||||
}
|
||||
|
||||
void AbstractRemoteLinuxRunSupport::handleAppRunnerFinished(bool success)
|
||||
{
|
||||
success ? reportStopped() : reportFailure();
|
||||
}
|
||||
|
||||
void AbstractRemoteLinuxRunSupport::handleAppRunnerError(const QString &error)
|
||||
{
|
||||
reportFailure(error);
|
||||
}
|
||||
|
||||
void AbstractRemoteLinuxRunSupport::handleRemoteOutput(const QByteArray &output)
|
||||
{
|
||||
appendMessage(QString::fromUtf8(output), StdOutFormat);
|
||||
}
|
||||
|
||||
void AbstractRemoteLinuxRunSupport::handleRemoteErrorOutput(const QByteArray &output)
|
||||
{
|
||||
appendMessage(QString::fromUtf8(output), StdErrFormat);
|
||||
}
|
||||
|
||||
void AbstractRemoteLinuxRunSupport::handleProgressReport(const QString &progressOutput)
|
||||
{
|
||||
appendMessage(progressOutput + '\n', LogMessageFormat);
|
||||
}
|
||||
|
||||
} // namespace RemoteLinux
|
||||
|
@@ -27,46 +27,28 @@
|
||||
|
||||
#include "remotelinux_export.h"
|
||||
|
||||
#include <projectexplorer/devicesupport/idevice.h>
|
||||
#include <projectexplorer/runconfiguration.h>
|
||||
|
||||
#include <utils/port.h>
|
||||
|
||||
namespace RemoteLinux {
|
||||
|
||||
namespace Internal { class AbstractRemoteLinuxRunSupportPrivate; }
|
||||
|
||||
class REMOTELINUX_EXPORT AbstractRemoteLinuxRunSupport : public ProjectExplorer::TargetRunner
|
||||
class REMOTELINUX_EXPORT FifoGatherer : public ProjectExplorer::RunWorker
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AbstractRemoteLinuxRunSupport(ProjectExplorer::RunControl *runControl);
|
||||
~AbstractRemoteLinuxRunSupport();
|
||||
explicit FifoGatherer(ProjectExplorer::RunControl *runControl);
|
||||
~FifoGatherer();
|
||||
|
||||
ProjectExplorer::ApplicationLauncher *applicationLauncher();
|
||||
|
||||
void setUsesFifo(bool on);
|
||||
|
||||
Utils::Port findPort() const;
|
||||
QString fifo() const;
|
||||
QString fifo() const { return m_fifo; }
|
||||
|
||||
private:
|
||||
void prepare() override;
|
||||
void start() override;
|
||||
void onFinished() override;
|
||||
|
||||
void createRemoteFifo();
|
||||
void startPortsGathering();
|
||||
|
||||
void handleAppRunnerError(const QString &error);
|
||||
void handleRemoteOutput(const QByteArray &output);
|
||||
void handleRemoteErrorOutput(const QByteArray &output);
|
||||
void handleAppRunnerFinished(bool success);
|
||||
void handleProgressReport(const QString &progressOutput);
|
||||
void handleAdapterSetupDone();
|
||||
|
||||
Internal::AbstractRemoteLinuxRunSupportPrivate * const d;
|
||||
ProjectExplorer::ApplicationLauncher m_fifoCreator;
|
||||
QString m_fifo;
|
||||
};
|
||||
|
||||
} // namespace RemoteLinux
|
||||
|
@@ -1,210 +1,172 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
///****************************************************************************
|
||||
//**
|
||||
//** Copyright (C) 2016 The Qt Company Ltd.
|
||||
//** Contact: https://www.qt.io/licensing/
|
||||
//**
|
||||
//** This file is part of Qt Creator.
|
||||
//**
|
||||
//** Commercial License Usage
|
||||
//** Licensees holding valid commercial Qt licenses may use this file in
|
||||
//** accordance with the commercial license agreement provided with the
|
||||
//** Software or, alternatively, in accordance with the terms contained in
|
||||
//** a written agreement between you and The Qt Company. For licensing terms
|
||||
//** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
//** information use the contact form at https://www.qt.io/contact-us.
|
||||
//**
|
||||
//** GNU General Public License Usage
|
||||
//** Alternatively, this file may be used under the terms of the GNU
|
||||
//** General Public License version 3 as published by the Free Software
|
||||
//** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
//** included in the packaging of this file. Please review the following
|
||||
//** information to ensure the GNU General Public License requirements will
|
||||
//** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
//**
|
||||
//****************************************************************************/
|
||||
|
||||
#include "remotelinuxanalyzesupport.h"
|
||||
//#include "remotelinuxanalyzesupport.h"
|
||||
|
||||
#include "remotelinuxrunconfiguration.h"
|
||||
//#include "remotelinuxrunconfiguration.h"
|
||||
|
||||
#include <projectexplorer/buildconfiguration.h>
|
||||
#include <projectexplorer/project.h>
|
||||
#include <projectexplorer/target.h>
|
||||
#include <projectexplorer/toolchain.h>
|
||||
#include <projectexplorer/kitinformation.h>
|
||||
#include <projectexplorer/runnables.h>
|
||||
//#include <projectexplorer/buildconfiguration.h>
|
||||
//#include <projectexplorer/project.h>
|
||||
//#include <projectexplorer/target.h>
|
||||
//#include <projectexplorer/toolchain.h>
|
||||
//#include <projectexplorer/kitinformation.h>
|
||||
//#include <projectexplorer/runnables.h>
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/qtcprocess.h>
|
||||
#include <qmldebug/qmloutputparser.h>
|
||||
#include <qmldebug/qmldebugcommandlinearguments.h>
|
||||
//#include <utils/qtcassert.h>
|
||||
//#include <utils/qtcprocess.h>
|
||||
//#include <qmldebug/qmloutputparser.h>
|
||||
//#include <qmldebug/qmldebugcommandlinearguments.h>
|
||||
|
||||
#include <QPointer>
|
||||
//#include <QPointer>
|
||||
|
||||
using namespace QSsh;
|
||||
using namespace ProjectExplorer;
|
||||
using namespace Utils;
|
||||
//using namespace QSsh;
|
||||
//using namespace ProjectExplorer;
|
||||
//using namespace Utils;
|
||||
|
||||
namespace RemoteLinux {
|
||||
namespace Internal {
|
||||
//namespace RemoteLinux {
|
||||
//namespace Internal {
|
||||
|
||||
class RemoteLinuxAnalyzeSupportPrivate
|
||||
{
|
||||
public:
|
||||
RemoteLinuxAnalyzeSupportPrivate(RunControl *runControl)
|
||||
{
|
||||
if (runControl->runMode() == ProjectExplorer::Constants::PERFPROFILER_RUN_MODE) {
|
||||
usesFifo = true;
|
||||
RunConfiguration *runConfiguration = runControl->runConfiguration();
|
||||
QTC_ASSERT(runConfiguration, return);
|
||||
IRunConfigurationAspect *perfAspect =
|
||||
runConfiguration->extraAspect("Analyzer.Perf.Settings");
|
||||
QTC_ASSERT(perfAspect, return);
|
||||
perfRecordArguments =
|
||||
perfAspect->currentSettings()->property("perfRecordArguments").toStringList()
|
||||
.join(' ');
|
||||
}
|
||||
}
|
||||
//const char RemoteLinuxAnalyzeSupportWorkerId[] = "RemoteLinux.AnalyzeSupportWorker";
|
||||
|
||||
Utils::Port qmlPort;
|
||||
QString remoteFifo;
|
||||
QString perfRecordArguments;
|
||||
//class RemoteLinuxAnalyzeSupportPrivate
|
||||
//{
|
||||
//public:
|
||||
// RemoteLinuxAnalyzeSupportPrivate(RunControl *runControl)
|
||||
// {
|
||||
// bool isPerf = runControl->runMode() == ProjectExplorer::Constants::PERFPROFILER_RUN_MODE;
|
||||
// needFifo = isPerf;
|
||||
// if (needFifo) {
|
||||
// RunConfiguration *runConfiguration = runControl->runConfiguration();
|
||||
// QTC_ASSERT(runConfiguration, return);
|
||||
// IRunConfigurationAspect *perfAspect =
|
||||
// runConfiguration->extraAspect("Analyzer.Perf.Settings");
|
||||
// QTC_ASSERT(perfAspect, return);
|
||||
// perfRecordArguments =
|
||||
// perfAspect->currentSettings()->property("perfRecordArguments").toStringList()
|
||||
// .join(' ');
|
||||
// }
|
||||
// }
|
||||
|
||||
ApplicationLauncher outputGatherer;
|
||||
QmlDebug::QmlOutputParser outputParser;
|
||||
bool usesFifo = false;
|
||||
};
|
||||
// Utils::Port qmlPort;
|
||||
// QString remoteFifo;
|
||||
// QString perfRecordArguments;
|
||||
|
||||
} // namespace Internal
|
||||
// ApplicationLauncher outputGatherer;
|
||||
// QmlDebug::QmlOutputParser outputParser;
|
||||
// bool needFifo = false;
|
||||
// bool needPort = false;
|
||||
//};
|
||||
|
||||
using namespace Internal;
|
||||
//} // namespace Internal
|
||||
|
||||
RemoteLinuxAnalyzeSupport::RemoteLinuxAnalyzeSupport(RunControl *runControl)
|
||||
: ToolRunner(runControl),
|
||||
d(new RemoteLinuxAnalyzeSupportPrivate(runControl))
|
||||
{
|
||||
connect(&d->outputParser, &QmlDebug::QmlOutputParser::waitingForConnectionOnPort,
|
||||
this, &RemoteLinuxAnalyzeSupport::remoteIsRunning);
|
||||
targetRunner()->setUsesFifo(runControl->runMode() == ProjectExplorer::Constants::PERFPROFILER_RUN_MODE);
|
||||
}
|
||||
//using namespace Internal;
|
||||
|
||||
RemoteLinuxAnalyzeSupport::~RemoteLinuxAnalyzeSupport()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
//RemoteLinuxAnalyzeSupport::RemoteLinuxAnalyzeSupport(RunControl *runControl)
|
||||
// : ToolRunner(runControl),
|
||||
// d(new RemoteLinuxAnalyzeSupportPrivate(runControl))
|
||||
//{
|
||||
// setId(RemoteLinuxAnalyzeSupportWorkerId);
|
||||
|
||||
void RemoteLinuxAnalyzeSupport::showMessage(const QString &msg, Utils::OutputFormat format)
|
||||
{
|
||||
appendMessage(msg, format);
|
||||
d->outputParser.processOutput(msg);
|
||||
}
|
||||
// connect(&d->outputParser, &QmlDebug::QmlOutputParser::waitingForConnectionOnPort,
|
||||
// this, &RemoteLinuxAnalyzeSupport::remoteIsRunning);
|
||||
|
||||
void RemoteLinuxAnalyzeSupport::start()
|
||||
{
|
||||
const Core::Id runMode = runControl()->runMode();
|
||||
if (runMode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) {
|
||||
d->qmlPort = targetRunner()->findPort();
|
||||
if (!d->qmlPort.isValid()) {
|
||||
reportFailure(tr("Not enough free ports on device for profiling."));
|
||||
return;
|
||||
}
|
||||
} else if (runMode == ProjectExplorer::Constants::PERFPROFILER_RUN_MODE) {
|
||||
d->remoteFifo = targetRunner()->fifo();
|
||||
if (d->remoteFifo.isEmpty()) {
|
||||
reportFailure(tr("FIFO for profiling data could not be created."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
// if (d->needFifo)
|
||||
// addDependency(FifoCreatorWorkerId);
|
||||
// if (d->needPort)
|
||||
// addDependency(PortsGathererWorkerId);
|
||||
//}
|
||||
|
||||
ApplicationLauncher *runner = targetRunner()->applicationLauncher();
|
||||
connect(runner, &ApplicationLauncher::remoteStderr,
|
||||
this, &RemoteLinuxAnalyzeSupport::handleRemoteErrorOutput);
|
||||
connect(runner, &ApplicationLauncher::remoteStdout,
|
||||
this, &RemoteLinuxAnalyzeSupport::handleRemoteOutput);
|
||||
connect(runner, &ApplicationLauncher::remoteProcessStarted,
|
||||
this, &RemoteLinuxAnalyzeSupport::handleRemoteProcessStarted);
|
||||
connect(runner, &ApplicationLauncher::finished,
|
||||
this, &RemoteLinuxAnalyzeSupport::handleAppRunnerFinished);
|
||||
connect(runner, &ApplicationLauncher::reportProgress,
|
||||
this, &RemoteLinuxAnalyzeSupport::handleProgressReport);
|
||||
connect(runner, &ApplicationLauncher::reportError,
|
||||
this, &RemoteLinuxAnalyzeSupport::handleAppRunnerError);
|
||||
//RemoteLinuxAnalyzeSupport::~RemoteLinuxAnalyzeSupport()
|
||||
//{
|
||||
// delete d;
|
||||
//}
|
||||
|
||||
auto r = runControl()->runnable().as<StandardRunnable>();
|
||||
////void RemoteLinuxAnalyzeSupport::showMessage(const QString &msg, Utils::OutputFormat format)
|
||||
////{
|
||||
//// appendMessage(msg, format);
|
||||
//// d->outputParser.processOutput(msg);
|
||||
////}
|
||||
|
||||
if (runMode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) {
|
||||
if (!r.commandLineArguments.isEmpty())
|
||||
r.commandLineArguments.append(QLatin1Char(' '));
|
||||
r.commandLineArguments += QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlProfilerServices,
|
||||
d->qmlPort);
|
||||
} else if (runMode == ProjectExplorer::Constants::PERFPROFILER_RUN_MODE) {
|
||||
r.commandLineArguments = QLatin1String("-c 'perf record -o - ") + d->perfRecordArguments
|
||||
+ QLatin1String(" -- ") + r.executable + QLatin1String(" ")
|
||||
+ r.commandLineArguments + QLatin1String(" > ") + d->remoteFifo
|
||||
+ QLatin1String("'");
|
||||
r.executable = QLatin1String("sh");
|
||||
//void RemoteLinuxAnalyzeSupport::start()
|
||||
//{
|
||||
// if (d->needPort) {
|
||||
// RunWorker *worker = qobject_cast<PortsGatherer>();
|
||||
// QTC_ASSERT(worker, reportFailure(); return);
|
||||
// runControl()->worker(PortsGathererWorkerId)->result();
|
||||
// d->qmlPort = targetRunner()->findPort();
|
||||
// if (!d->qmlPort.isValid()) {
|
||||
// reportFailure(tr("Not enough free ports on device for profiling."));
|
||||
// return;
|
||||
// }
|
||||
// } else if (runMode == ProjectExplorer::Constants::PERFPROFILER_RUN_MODE) {
|
||||
// d->remoteFifo = targetRunner()->fifo();
|
||||
// if (d->remoteFifo.isEmpty()) {
|
||||
// reportFailure(tr("FIFO for profiling data could not be created."));
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
|
||||
connect(&d->outputGatherer, SIGNAL(remoteStdout(QByteArray)),
|
||||
runControl(), SIGNAL(analyzePerfOutput(QByteArray)));
|
||||
connect(&d->outputGatherer, SIGNAL(finished(bool)),
|
||||
runControl(), SIGNAL(perfFinished()));
|
||||
// ApplicationLauncher *runner = targetRunner()->applicationLauncher();
|
||||
|
||||
StandardRunnable outputRunner;
|
||||
outputRunner.executable = QLatin1String("sh");
|
||||
outputRunner.commandLineArguments =
|
||||
QString::fromLatin1("-c 'cat %1 && rm -r `dirname %1`'").arg(d->remoteFifo);
|
||||
d->outputGatherer.start(outputRunner, device());
|
||||
remoteIsRunning();
|
||||
}
|
||||
runner->start(r, device());
|
||||
}
|
||||
// auto r = runControl()->runnable().as<StandardRunnable>();
|
||||
|
||||
void RemoteLinuxAnalyzeSupport::handleAppRunnerError(const QString &error)
|
||||
{
|
||||
showMessage(error, Utils::ErrorMessageFormat);
|
||||
reportFailure(error);
|
||||
}
|
||||
// if (runMode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) {
|
||||
// if (!r.commandLineArguments.isEmpty())
|
||||
// r.commandLineArguments.append(QLatin1Char(' '));
|
||||
// r.commandLineArguments += QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlProfilerServices,
|
||||
// d->qmlPort);
|
||||
// } else if (runMode == ProjectExplorer::Constants::PERFPROFILER_RUN_MODE) {
|
||||
// r.commandLineArguments = QLatin1String("-c 'perf record -o - ") + d->perfRecordArguments
|
||||
// + QLatin1String(" -- ") + r.executable + QLatin1String(" ")
|
||||
// + r.commandLineArguments + QLatin1String(" > ") + d->remoteFifo
|
||||
// + QLatin1String("'");
|
||||
// r.executable = QLatin1String("sh");
|
||||
|
||||
void RemoteLinuxAnalyzeSupport::handleAppRunnerFinished(bool success)
|
||||
{
|
||||
// reset needs to be called first to ensure that the correct state is set.
|
||||
if (!success)
|
||||
showMessage(tr("Failure running remote process."), Utils::NormalMessageFormat);
|
||||
runControl()->notifyRemoteFinished();
|
||||
}
|
||||
// connect(&d->outputGatherer, SIGNAL(remoteStdout(QByteArray)),
|
||||
// runControl(), SIGNAL(analyzePerfOutput(QByteArray)));
|
||||
// connect(&d->outputGatherer, SIGNAL(finished(bool)),
|
||||
// runControl(), SIGNAL(perfFinished()));
|
||||
|
||||
void RemoteLinuxAnalyzeSupport::remoteIsRunning()
|
||||
{
|
||||
runControl()->notifyRemoteSetupDone(d->qmlPort);
|
||||
}
|
||||
// StandardRunnable outputRunner;
|
||||
// outputRunner.executable = QLatin1String("sh");
|
||||
// outputRunner.commandLineArguments =
|
||||
// QString::fromLatin1("-c 'cat %1 && rm -r `dirname %1`'").arg(d->remoteFifo);
|
||||
// d->outputGatherer.start(outputRunner, device());
|
||||
// remoteIsRunning();
|
||||
// }
|
||||
// runner->start(r, device());
|
||||
//}
|
||||
|
||||
AbstractRemoteLinuxRunSupport *RemoteLinuxAnalyzeSupport::targetRunner() const
|
||||
{
|
||||
return qobject_cast<AbstractRemoteLinuxRunSupport *>(runControl()->targetRunner());
|
||||
}
|
||||
//void RemoteLinuxAnalyzeSupport::remoteIsRunning()
|
||||
//{
|
||||
// runControl()->notifyRemoteSetupDone(d->qmlPort);
|
||||
//}
|
||||
|
||||
void RemoteLinuxAnalyzeSupport::handleRemoteOutput(const QByteArray &output)
|
||||
{
|
||||
showMessage(QString::fromUtf8(output), Utils::StdOutFormat);
|
||||
}
|
||||
//AbstractRemoteLinuxRunSupport *RemoteLinuxAnalyzeSupport::targetRunner() const
|
||||
//{
|
||||
// return qobject_cast<AbstractRemoteLinuxRunSupport *>(runControl()->targetRunner());
|
||||
//}
|
||||
|
||||
void RemoteLinuxAnalyzeSupport::handleRemoteErrorOutput(const QByteArray &output)
|
||||
{
|
||||
showMessage(QString::fromUtf8(output), Utils::StdErrFormat);
|
||||
}
|
||||
|
||||
void RemoteLinuxAnalyzeSupport::handleProgressReport(const QString &progressOutput)
|
||||
{
|
||||
showMessage(progressOutput + QLatin1Char('\n'), Utils::NormalMessageFormat);
|
||||
}
|
||||
|
||||
void RemoteLinuxAnalyzeSupport::handleAdapterSetupFailed(const QString &error)
|
||||
{
|
||||
showMessage(tr("Initial setup failed: %1").arg(error), Utils::NormalMessageFormat);
|
||||
}
|
||||
|
||||
void RemoteLinuxAnalyzeSupport::handleRemoteProcessStarted()
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace RemoteLinux
|
||||
//} // namespace RemoteLinux
|
||||
|
@@ -1,67 +1,54 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
///****************************************************************************
|
||||
//**
|
||||
//** Copyright (C) 2016 The Qt Company Ltd.
|
||||
//** Contact: https://www.qt.io/licensing/
|
||||
//**
|
||||
//** This file is part of Qt Creator.
|
||||
//**
|
||||
//** Commercial License Usage
|
||||
//** Licensees holding valid commercial Qt licenses may use this file in
|
||||
//** accordance with the commercial license agreement provided with the
|
||||
//** Software or, alternatively, in accordance with the terms contained in
|
||||
//** a written agreement between you and The Qt Company. For licensing terms
|
||||
//** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
//** information use the contact form at https://www.qt.io/contact-us.
|
||||
//**
|
||||
//** GNU General Public License Usage
|
||||
//** Alternatively, this file may be used under the terms of the GNU
|
||||
//** General Public License version 3 as published by the Free Software
|
||||
//** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
//** included in the packaging of this file. Please review the following
|
||||
//** information to ensure the GNU General Public License requirements will
|
||||
//** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
//**
|
||||
//****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
//#pragma once
|
||||
|
||||
#include "abstractremotelinuxrunsupport.h"
|
||||
//#include "abstractremotelinuxrunsupport.h"
|
||||
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
#include <projectexplorer/runconfiguration.h>
|
||||
//#include <projectexplorer/projectexplorerconstants.h>
|
||||
//#include <projectexplorer/runconfiguration.h>
|
||||
|
||||
#include <utils/outputformat.h>
|
||||
//#include <utils/outputformat.h>
|
||||
|
||||
namespace RemoteLinux {
|
||||
//namespace RemoteLinux {
|
||||
|
||||
namespace Internal { class RemoteLinuxAnalyzeSupportPrivate; }
|
||||
//namespace Internal { class RemoteLinuxAnalyzeSupportPrivate; }
|
||||
|
||||
class REMOTELINUX_EXPORT RemoteLinuxAnalyzeSupport : public ProjectExplorer::ToolRunner
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
RemoteLinuxAnalyzeSupport(ProjectExplorer::RunControl *runControl);
|
||||
~RemoteLinuxAnalyzeSupport() override;
|
||||
//class REMOTELINUX_EXPORT RemoteLinuxAnalyzeSupport : public ProjectExplorer::RunWorker
|
||||
//{
|
||||
// Q_OBJECT
|
||||
//public:
|
||||
// RemoteLinuxAnalyzeSupport(ProjectExplorer::RunControl *runControl);
|
||||
// ~RemoteLinuxAnalyzeSupport() override;
|
||||
|
||||
private:
|
||||
void start() override;
|
||||
void handleAdapterSetupFailed(const QString &error);
|
||||
//private:
|
||||
// void start() override;
|
||||
|
||||
void handleRemoteSetupRequested();
|
||||
void handleAppRunnerError(const QString &error);
|
||||
void handleRemoteOutput(const QByteArray &output);
|
||||
void handleRemoteErrorOutput(const QByteArray &output);
|
||||
void handleAppRunnerFinished(bool success);
|
||||
void handleProgressReport(const QString &progressOutput);
|
||||
// void remoteIsRunning();
|
||||
|
||||
void handleRemoteProcessStarted();
|
||||
// Internal::RemoteLinuxAnalyzeSupportPrivate * const d;
|
||||
//};
|
||||
|
||||
void remoteIsRunning();
|
||||
AbstractRemoteLinuxRunSupport *targetRunner() const;
|
||||
|
||||
void showMessage(const QString &, Utils::OutputFormat);
|
||||
|
||||
Internal::RemoteLinuxAnalyzeSupportPrivate * const d;
|
||||
};
|
||||
|
||||
} // namespace RemoteLinux
|
||||
//} // namespace RemoteLinux
|
||||
|
@@ -47,10 +47,35 @@ using namespace Utils;
|
||||
|
||||
namespace RemoteLinux {
|
||||
|
||||
LinuxDeviceDebugSupport::LinuxDeviceDebugSupport(RunControl *runControl, QString *errorMessage)
|
||||
LinuxDeviceDebugSupport::LinuxDeviceDebugSupport(RunControl *runControl)
|
||||
: DebuggerRunTool(runControl)
|
||||
{
|
||||
RunConfiguration *runConfig = runControl->runConfiguration();
|
||||
setDisplayName("DebugSupport");
|
||||
|
||||
auto portsGatherer = new GdbServerPortsGatherer(runControl);
|
||||
portsGatherer->setUseGdbServer(isCppDebugging());
|
||||
portsGatherer->setUseQmlServer(isQmlDebugging());
|
||||
|
||||
auto gdbServer = new GdbServerRunner(runControl);
|
||||
gdbServer->addDependency(portsGatherer);
|
||||
|
||||
addDependency(gdbServer);
|
||||
}
|
||||
|
||||
LinuxDeviceDebugSupport::~LinuxDeviceDebugSupport()
|
||||
{
|
||||
}
|
||||
|
||||
void LinuxDeviceDebugSupport::start()
|
||||
{
|
||||
auto portsGatherer = runControl()->worker<GdbServerPortsGatherer>();
|
||||
QTC_ASSERT(portsGatherer, reportFailure(); return);
|
||||
|
||||
const QString host = device()->sshParameters().host;
|
||||
const Port gdbServerPort = portsGatherer->gdbServerPort();
|
||||
const Port qmlServerPort = portsGatherer->qmlServerPort();
|
||||
|
||||
RunConfiguration *runConfig = runControl()->runConfiguration();
|
||||
|
||||
QString symbolFile;
|
||||
if (auto rlrc = qobject_cast<RemoteLinuxRunConfiguration *>(runConfig))
|
||||
@@ -58,7 +83,7 @@ LinuxDeviceDebugSupport::LinuxDeviceDebugSupport(RunControl *runControl, QString
|
||||
if (auto rlrc = qobject_cast<Internal::RemoteLinuxCustomRunConfiguration *>(runConfig))
|
||||
symbolFile = rlrc->localExecutableFilePath();
|
||||
if (symbolFile.isEmpty()) {
|
||||
*errorMessage = tr("Cannot debug: Local executable is not set.");
|
||||
// *errorMessage = tr("Cannot debug: Local executable is not set.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -68,8 +93,10 @@ LinuxDeviceDebugSupport::LinuxDeviceDebugSupport(RunControl *runControl, QString
|
||||
params.remoteSetupNeeded = false;
|
||||
|
||||
if (isQmlDebugging()) {
|
||||
params.qmlServer.host = device()->sshParameters().host;
|
||||
params.qmlServer.port = Utils::Port(); // port is selected later on
|
||||
params.qmlServer.host = host;
|
||||
params.qmlServer.port = qmlServerPort;
|
||||
params.inferior.commandLineArguments.replace("%qml_port%",
|
||||
QString::number(qmlServerPort.number()));
|
||||
}
|
||||
if (isCppDebugging()) {
|
||||
Runnable r = runnable();
|
||||
@@ -83,69 +110,14 @@ LinuxDeviceDebugSupport::LinuxDeviceDebugSupport(RunControl *runControl, QString
|
||||
params.inferior.commandLineArguments.prepend(
|
||||
QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices));
|
||||
}
|
||||
params.remoteChannel = device()->sshParameters().host + ":-1";
|
||||
|
||||
params.remoteChannel = QString("%1:%2").arg(host).arg(gdbServerPort.number());
|
||||
params.symbolFile = symbolFile;
|
||||
}
|
||||
|
||||
setStartParameters(params);
|
||||
}
|
||||
|
||||
LinuxDeviceDebugSupport::~LinuxDeviceDebugSupport()
|
||||
{
|
||||
}
|
||||
|
||||
void LinuxDeviceDebugSupport::prepare()
|
||||
{
|
||||
auto targetRunner = qobject_cast<AbstractRemoteLinuxRunSupport *>(runControl()->targetRunner());
|
||||
|
||||
if (isCppDebugging()) {
|
||||
m_gdbServerPort = targetRunner->findPort();
|
||||
if (!m_gdbServerPort.isValid()) {
|
||||
reportFailure(tr("Not enough free ports on device for C++ debugging."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (isQmlDebugging()) {
|
||||
m_qmlPort = targetRunner->findPort();
|
||||
if (!m_qmlPort.isValid()) {
|
||||
reportFailure(tr("Not enough free ports on device for QML debugging."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
runControl()->setRunnable(realRunnable());
|
||||
|
||||
RemoteSetupResult result;
|
||||
result.success = true;
|
||||
result.gdbServerPort = m_gdbServerPort;
|
||||
result.qmlServerPort = m_qmlPort;
|
||||
setRemoteParameters(result);
|
||||
|
||||
DebuggerRunTool::prepare();
|
||||
}
|
||||
|
||||
Runnable LinuxDeviceDebugSupport::realRunnable() const
|
||||
{
|
||||
StandardRunnable r = runControl()->runnable().as<StandardRunnable>();
|
||||
QStringList args = QtcProcess::splitArgs(r.commandLineArguments, OsTypeLinux);
|
||||
QString command;
|
||||
|
||||
if (isQmlDebugging())
|
||||
args.prepend(QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices, m_qmlPort));
|
||||
|
||||
if (isQmlDebugging() && !isCppDebugging()) {
|
||||
command = r.executable;
|
||||
} else {
|
||||
command = device()->debugServerPath();
|
||||
if (command.isEmpty())
|
||||
command = QLatin1String("gdbserver");
|
||||
args.clear();
|
||||
args.append(QString::fromLatin1("--multi"));
|
||||
args.append(QString::fromLatin1(":%1").arg(m_gdbServerPort.number()));
|
||||
}
|
||||
r.executable = command;
|
||||
r.commandLineArguments = QtcProcess::joinArgs(args, OsTypeLinux);
|
||||
return r;
|
||||
DebuggerRunTool::start();
|
||||
}
|
||||
|
||||
} // namespace RemoteLinux
|
||||
|
@@ -36,18 +36,11 @@ class REMOTELINUX_EXPORT LinuxDeviceDebugSupport : public Debugger::DebuggerRunT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
LinuxDeviceDebugSupport(ProjectExplorer::RunControl *runControl,
|
||||
QString *errorMessage = nullptr);
|
||||
LinuxDeviceDebugSupport(ProjectExplorer::RunControl *runControl);
|
||||
~LinuxDeviceDebugSupport() override;
|
||||
|
||||
protected:
|
||||
virtual ProjectExplorer::Runnable realRunnable() const;
|
||||
|
||||
private:
|
||||
void prepare() override;
|
||||
|
||||
Utils::Port m_gdbServerPort;
|
||||
Utils::Port m_qmlPort;
|
||||
void start() override;
|
||||
};
|
||||
|
||||
} // namespace RemoteLinux
|
||||
|
@@ -30,18 +30,12 @@
|
||||
#include "remotelinuxcustomrunconfiguration.h"
|
||||
#include "remotelinuxrunconfiguration.h"
|
||||
|
||||
#include <debugger/analyzer/analyzermanager.h>
|
||||
#include <debugger/analyzer/analyzerstartparameters.h>
|
||||
|
||||
#include <debugger/debuggerruncontrol.h>
|
||||
#include <debugger/debuggerrunconfigurationaspect.h>
|
||||
#include <debugger/debuggerstartparameters.h>
|
||||
|
||||
#include <projectexplorer/kitinformation.h>
|
||||
#include <projectexplorer/runnables.h>
|
||||
#include <projectexplorer/target.h>
|
||||
|
||||
|
||||
#include <utils/portlist.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
@@ -62,7 +56,8 @@ bool RemoteLinuxRunControlFactory::canRun(RunConfiguration *runConfiguration, Co
|
||||
&& mode != ProjectExplorer::Constants::DEBUG_RUN_MODE
|
||||
&& mode != ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN
|
||||
&& mode != ProjectExplorer::Constants::QML_PROFILER_RUN_MODE
|
||||
&& mode != ProjectExplorer::Constants::PERFPROFILER_RUN_MODE) {
|
||||
// && mode != ProjectExplorer::Constants::PERFPROFILER_RUN_MODE
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -73,34 +68,37 @@ bool RemoteLinuxRunControlFactory::canRun(RunConfiguration *runConfiguration, Co
|
||||
}
|
||||
|
||||
RunControl *RemoteLinuxRunControlFactory::create(RunConfiguration *runConfig, Core::Id mode,
|
||||
QString *errorMessage)
|
||||
QString *)
|
||||
{
|
||||
QTC_ASSERT(canRun(runConfig, mode), return 0);
|
||||
|
||||
if (mode == ProjectExplorer::Constants::NORMAL_RUN_MODE) {
|
||||
auto runControl = new RunControl(runConfig, mode);
|
||||
(void) new AbstractRemoteLinuxRunSupport(runControl);
|
||||
(void) new SimpleTargetRunner(runControl);
|
||||
return runControl;
|
||||
}
|
||||
|
||||
if (mode == ProjectExplorer::Constants::DEBUG_RUN_MODE
|
||||
|| mode == ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN) {
|
||||
auto runControl = new RunControl(runConfig, mode);
|
||||
(void) new AbstractRemoteLinuxRunSupport(runControl);
|
||||
(void) new LinuxDeviceDebugSupport(runControl, errorMessage);
|
||||
(void) new LinuxDeviceDebugSupport(runControl);
|
||||
return runControl;
|
||||
}
|
||||
|
||||
if (mode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE ||
|
||||
mode == ProjectExplorer::Constants::PERFPROFILER_RUN_MODE) {
|
||||
auto runControl = Debugger::createAnalyzerRunControl(runConfig, mode);
|
||||
AnalyzerConnection connection;
|
||||
connection.connParams =
|
||||
DeviceKitInformation::device(runConfig->target()->kit())->sshParameters();
|
||||
connection.analyzerHost = connection.connParams.host;
|
||||
runControl->setConnection(connection);
|
||||
(void) new AbstractRemoteLinuxRunSupport(runControl);
|
||||
(void) new RemoteLinuxAnalyzeSupport(runControl);
|
||||
if (mode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE
|
||||
// || mode == ProjectExplorer::Constants::PERFPROFILER_RUN_MODE
|
||||
) {
|
||||
auto runControl = new RunControl(runConfig, mode);
|
||||
runControl->createWorker(mode);
|
||||
// AnalyzerConnection connection;
|
||||
// connection.connParams =
|
||||
// DeviceKitInformation::device(runConfig->target()->kit())->sshParameters();
|
||||
// connection.analyzerHost = connection.connParams.host;
|
||||
// runControl->setConnection(connection);
|
||||
// (void) new SimpleTargetRunner(runControl);
|
||||
// (void) new PortsGatherer(runControl);
|
||||
// (void) new FifoGatherer(runControl);
|
||||
// (void) new RemoteLinuxAnalyzeSupport(runControl);
|
||||
return runControl;
|
||||
}
|
||||
|
||||
|
@@ -255,14 +255,11 @@ CallgrindTool::CallgrindTool(QObject *parent)
|
||||
QString toolTip = tr("Valgrind Function Profiler uses the "
|
||||
"Callgrind tool to record function calls when a program runs.");
|
||||
|
||||
auto rcc = [this](RunConfiguration *runConfiguration, Id mode) {
|
||||
auto runControl = new RunControl(runConfiguration, mode);
|
||||
(void) createRunTool(runControl);
|
||||
return runControl;
|
||||
};
|
||||
RunControl::registerWorkerCreator(CALLGRIND_RUN_MODE, [this](RunControl *runControl) {
|
||||
return createRunTool(runControl);
|
||||
});
|
||||
|
||||
if (!Utils::HostOsInfo::isWindowsHost()) {
|
||||
Debugger::registerAction(CALLGRIND_RUN_MODE, rcc);
|
||||
auto action = new QAction(tr("Valgrind Function Profiler"), this);
|
||||
action->setToolTip(toolTip);
|
||||
menu->addAction(ActionManager::registerAction(action, CallgrindLocalActionId),
|
||||
@@ -279,7 +276,6 @@ CallgrindTool::CallgrindTool(QObject *parent)
|
||||
});
|
||||
}
|
||||
|
||||
Debugger::registerAction(CALLGRIND_RUN_MODE, rcc);
|
||||
auto action = new QAction(tr("Valgrind Function Profiler (External Application)"), this);
|
||||
action->setToolTip(toolTip);
|
||||
menu->addAction(ActionManager::registerAction(action, CallgrindRemoteActionId),
|
||||
|
@@ -244,7 +244,7 @@ class MemcheckTool : public QObject
|
||||
public:
|
||||
MemcheckTool(QObject *parent);
|
||||
|
||||
RunControl *createRunControl(RunConfiguration *runConfiguration, Core::Id runMode);
|
||||
RunWorker *createRunWorker(RunControl *runControl);
|
||||
|
||||
private:
|
||||
void updateRunActions();
|
||||
@@ -395,8 +395,10 @@ MemcheckTool::MemcheckTool(QObject *parent)
|
||||
ActionContainer *menu = ActionManager::actionContainer(Debugger::Constants::M_DEBUG_ANALYZER);
|
||||
QString toolTip = tr("Valgrind Analyze Memory uses the Memcheck tool to find memory leaks.");
|
||||
|
||||
RunControl::registerWorkerCreator(MEMCHECK_RUN_MODE, std::bind(&MemcheckTool::createRunWorker, this, _1));
|
||||
RunControl::registerWorkerCreator(MEMCHECK_WITH_GDB_RUN_MODE, std::bind(&MemcheckTool::createRunWorker, this, _1));
|
||||
|
||||
if (!Utils::HostOsInfo::isWindowsHost()) {
|
||||
Debugger::registerAction(MEMCHECK_RUN_MODE, std::bind(&MemcheckTool::createRunControl, this, _1, _2));
|
||||
action = new QAction(this);
|
||||
action->setText(tr("Valgrind Memory Analyzer"));
|
||||
action->setToolTip(toolTip);
|
||||
@@ -414,7 +416,6 @@ MemcheckTool::MemcheckTool(QObject *parent)
|
||||
action->setEnabled(m_startAction->isEnabled());
|
||||
});
|
||||
|
||||
Debugger::registerAction(MEMCHECK_WITH_GDB_RUN_MODE, std::bind(&MemcheckTool::createRunControl, this, _1, _2));
|
||||
action = new QAction(this);
|
||||
action->setText(tr("Valgrind Memory Analyzer with GDB"));
|
||||
action->setToolTip(tr("Valgrind Analyze Memory with GDB uses the "
|
||||
@@ -435,7 +436,6 @@ MemcheckTool::MemcheckTool(QObject *parent)
|
||||
});
|
||||
}
|
||||
|
||||
Debugger::registerAction(MEMCHECK_RUN_MODE, std::bind(&MemcheckTool::createRunControl, this, _1, _2));
|
||||
action = new QAction(this);
|
||||
action->setText(tr("Valgrind Memory Analyzer (External Application)"));
|
||||
action->setToolTip(toolTip);
|
||||
@@ -452,8 +452,8 @@ MemcheckTool::MemcheckTool(QObject *parent)
|
||||
return;
|
||||
TaskHub::clearTasks(Debugger::Constants::ANALYZERTASK_ID);
|
||||
Debugger::selectPerspective(MemcheckPerspectiveId);
|
||||
RunControl *rc = createRunControl(runConfig, MEMCHECK_RUN_MODE);
|
||||
QTC_ASSERT(rc, return);
|
||||
RunControl *rc = new RunControl(runConfig, MEMCHECK_RUN_MODE);
|
||||
rc->createWorker(MEMCHECK_RUN_MODE);
|
||||
const auto runnable = dlg.runnable();
|
||||
rc->setRunnable(runnable);
|
||||
AnalyzerConnection connection;
|
||||
@@ -560,14 +560,14 @@ void MemcheckTool::maybeActiveRunConfigurationChanged()
|
||||
updateFromSettings();
|
||||
}
|
||||
|
||||
RunControl *MemcheckTool::createRunControl(RunConfiguration *runConfiguration, Core::Id runMode)
|
||||
RunWorker *MemcheckTool::createRunWorker(RunControl *runControl)
|
||||
{
|
||||
m_errorModel.setRelevantFrameFinder(makeFrameFinder(runConfiguration
|
||||
? runConfiguration->target()->project()->files(Project::AllFiles) : QStringList()));
|
||||
RunConfiguration *runConfig = runControl->runConfiguration();
|
||||
m_errorModel.setRelevantFrameFinder(makeFrameFinder(runConfig
|
||||
? runConfig->target()->project()->files(Project::AllFiles) : QStringList()));
|
||||
|
||||
auto runControl = new RunControl(runConfiguration, runMode);
|
||||
MemcheckToolRunner *runTool = 0;
|
||||
if (runMode == MEMCHECK_RUN_MODE)
|
||||
if (runControl->runMode() == MEMCHECK_RUN_MODE)
|
||||
runTool = new MemcheckToolRunner(runControl);
|
||||
else
|
||||
runTool = new MemcheckWithGdbToolRunner(runControl);
|
||||
@@ -583,7 +583,7 @@ RunControl *MemcheckTool::createRunControl(RunConfiguration *runConfiguration, C
|
||||
m_toolBusy = true;
|
||||
updateRunActions();
|
||||
|
||||
return runControl;
|
||||
return runTool;
|
||||
}
|
||||
|
||||
void MemcheckTool::engineStarting(const MemcheckToolRunner *runTool)
|
||||
@@ -739,7 +739,9 @@ public:
|
||||
RunControl *create(RunConfiguration *runConfiguration, Core::Id mode, QString *errorMessage) override
|
||||
{
|
||||
Q_UNUSED(errorMessage);
|
||||
return m_tool->createRunControl(runConfiguration, mode);
|
||||
auto runControl = new RunControl(runConfiguration, mode);
|
||||
runControl->createWorker(mode);
|
||||
return runControl;
|
||||
}
|
||||
|
||||
// Do not create an aspect, let the Callgrind tool create one and use that, too.
|
||||
|
@@ -54,7 +54,7 @@ namespace Valgrind {
|
||||
namespace Internal {
|
||||
|
||||
ValgrindToolRunner::ValgrindToolRunner(RunControl *runControl)
|
||||
: ToolRunner(runControl)
|
||||
: RunWorker(runControl)
|
||||
{
|
||||
runControl->setIcon(ProjectExplorer::Icons::ANALYZER_START_SMALL_TOOLBAR);
|
||||
runControl->setSupportsReRunning(false);
|
||||
@@ -102,7 +102,7 @@ void ValgrindToolRunner::start()
|
||||
return;
|
||||
}
|
||||
|
||||
reportSuccess();
|
||||
reportStarted();
|
||||
}
|
||||
|
||||
void ValgrindToolRunner::stop()
|
||||
@@ -160,7 +160,7 @@ void ValgrindToolRunner::runnerFinished()
|
||||
disconnect(runner(), &ValgrindRunner::finished,
|
||||
this, &ValgrindToolRunner::runnerFinished);
|
||||
|
||||
reportSuccess();
|
||||
reportStarted();
|
||||
}
|
||||
|
||||
void ValgrindToolRunner::receiveProcessOutput(const QString &output, OutputFormat format)
|
||||
|
@@ -37,7 +37,7 @@
|
||||
namespace Valgrind {
|
||||
namespace Internal {
|
||||
|
||||
class ValgrindToolRunner : public ProjectExplorer::ToolRunner
|
||||
class ValgrindToolRunner : public ProjectExplorer::RunWorker
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
@@ -49,7 +49,7 @@ namespace Internal {
|
||||
using namespace ProjectExplorer;
|
||||
|
||||
WinRtDebugSupport::WinRtDebugSupport(RunControl *runControl, WinRtRunnerHelper *runner)
|
||||
: ToolRunner(runControl)
|
||||
: RunWorker(runControl)
|
||||
, m_runner(runner)
|
||||
{
|
||||
connect(runControl, &RunControl::finished, this, &WinRtDebugSupport::finish);
|
||||
|
@@ -35,7 +35,7 @@ namespace Internal {
|
||||
class WinRtRunConfiguration;
|
||||
class WinRtRunnerHelper;
|
||||
|
||||
class WinRtDebugSupport : public ProjectExplorer::ToolRunner
|
||||
class WinRtDebugSupport : public ProjectExplorer::RunWorker
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
Reference in New Issue
Block a user