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