aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorck <[email protected]>2010-01-06 18:20:43 +0100
committerck <[email protected]>2010-01-06 18:20:43 +0100
commit138b12b5dc8e1b969dd81685f402b7f75c7a76dd (patch)
tree96beffaf85f78d28fc59936bc1a9a6f9d834bfb6 /src/plugins
parentcf010f764aec38559bf36aab69a2167ef9667c36 (diff)
Maemo: Move MaemoRunControl classes to their own files.
The maemorunconfiguration.cpp file contained (and still contains) too many different classes.
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.cpp746
-rw-r--r--src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.cpp661
-rw-r--r--src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.h195
-rw-r--r--src/plugins/qt4projectmanager/qt-maemo/qt-maemo.pri9
4 files changed, 863 insertions, 748 deletions
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.cpp
index b4f6dd6e547..a32a0ba30e7 100644
--- a/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.cpp
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.cpp
@@ -31,6 +31,7 @@
#include "maemodeviceconfigurations.h"
#include "maemomanager.h"
+#include "maemoruncontrol.h"
#include "maemosettingspage.h"
#include "maemosshthread.h"
#include "maemotoolchain.h"
@@ -38,10 +39,8 @@
#include "qt4project.h"
#include "qt4buildconfiguration.h"
-#include <coreplugin/progressmanager/progressmanager.h>
#include <coreplugin/icore.h>
#include <coreplugin/messagemanager.h>
-#include <debugger/debuggermanager.h>
#include <extensionsystem/pluginmanager.h>
#include <utils/pathchooser.h>
#include <utils/qtcassert.h>
@@ -50,12 +49,9 @@
#include <projectexplorer/session.h>
#include <QtCore/QDebug>
-#include <QtCore/QFuture>
#include <QtCore/QPair>
#include <QtCore/QProcess>
-#include <QtCore/QScopedPointer>
#include <QtCore/QSharedPointer>
-#include <QtCore/QStringBuilder>
#include <QtGui/QComboBox>
#include <QtGui/QCheckBox>
@@ -103,139 +99,6 @@ private:
MaemoRunConfiguration *m_runConfiguration;
};
-class AbstractMaemoRunControl : public ProjectExplorer::RunControl
-{
- Q_OBJECT
-
-public:
- AbstractMaemoRunControl(RunConfiguration *runConfig);
- virtual ~AbstractMaemoRunControl() {}
-
-protected:
- void startDeployment(bool forDebugging);
- void deploy();
- void stopDeployment();
- bool isDeploying() const;
- const QString executableOnHost() const;
- const QString executableOnTarget() const;
- const QString executableFileName() const;
- const QString port() const;
- const QString targetCmdLinePrefix() const;
- const QString remoteDir() const;
- const QStringList options() const;
-#ifndef USE_SSH_LIB
- void deploymentFinished(bool success);
- virtual bool setProcessEnvironment(QProcess &process);
-#endif // USE_SSH_LIB
-private slots:
-#ifndef USE_SSH_LIB
- void readStandardError();
- void readStandardOutput();
-#endif // USE_SSH_LIB
- void deployProcessFinished();
-#ifdef USE_SSH_LIB
- void handleFileCopied();
-#endif
-
-protected:
- ErrorDumper dumper;
- MaemoRunConfiguration *runConfig; // TODO this pointer can be invalid
- const MaemoDeviceConfig devConfig;
-
-private:
- virtual void handleDeploymentFinished(bool success)=0;
-
- QFutureInterface<void> m_progress;
-#ifdef USE_SSH_LIB
- QScopedPointer<MaemoSshDeployer> sshDeployer;
-#else
- QProcess deployProcess;
-#endif // USE_SSH_LIB
- struct Deployable
- {
- typedef void (MaemoRunConfiguration::*updateFunc)();
- Deployable(const QString &f, const QString &d, updateFunc u)
- : fileName(f), dir(d), updateTimestamp(u) {}
- QString fileName;
- QString dir;
- updateFunc updateTimestamp;
- };
- QList<Deployable> deployables;
-};
-
-class MaemoRunControl : public AbstractMaemoRunControl
-{
- Q_OBJECT
-public:
- MaemoRunControl(RunConfiguration *runConfiguration);
- ~MaemoRunControl();
- void start();
- void stop();
- bool isRunning() const;
-
-private slots:
- void executionFinished();
-#ifdef USE_SSH_LIB
- void handleRemoteOutput(const QString &output);
-#endif
-
-private:
- virtual void handleDeploymentFinished(bool success);
- void startExecution();
-
-#ifdef USE_SSH_LIB
- QScopedPointer<MaemoSshRunner> sshRunner;
- QScopedPointer<MaemoSshRunner> sshStopper;
-#else
- QProcess sshProcess;
- QProcess stopProcess;
-#endif // USE_SSH_LIB
- bool stoppedByUser;
-};
-
-class MaemoDebugRunControl : public AbstractMaemoRunControl
-{
- Q_OBJECT
-public:
- MaemoDebugRunControl(RunConfiguration *runConfiguration);
- ~MaemoDebugRunControl();
- void start();
- void stop();
- bool isRunning() const;
- Q_SLOT void debuggingFinished();
-
-signals:
- void stopRequested();
-
-private slots:
-#ifdef USE_SSH_LIB
- void gdbServerStarted(const QString &output);
-#else
- void gdbServerStarted();
-#endif // USE_SSH_LIB
-
- void debuggerOutput(const QString &output);
-
-private:
- virtual void handleDeploymentFinished(bool success);
-
- void startGdbServer();
- void gdbServerStartFailed(const QString &reason);
- void startDebugging();
-
-#ifdef USE_SSH_LIB
- QScopedPointer<MaemoSshRunner> sshRunner;
- QScopedPointer<MaemoSshRunner> sshStopper;
-#else
- QProcess gdbServer;
- QProcess stopProcess;
-#endif // USE_SSH_LIB
- const QString gdbServerPort;
- Debugger::DebuggerManager *debuggerManager;
- QSharedPointer<Debugger::DebuggerStartParameters> startParams;
- int inferiorPid;
-};
-
void ErrorDumper::printToStream(QProcess::ProcessError error)
{
QString reason;
@@ -1016,611 +879,4 @@ QWidget* MaemoRunControlFactory::configurationWidget(RunConfiguration *config)
// #pragma mark -- AbstractMaemoRunControl
-
-AbstractMaemoRunControl::AbstractMaemoRunControl(RunConfiguration *rc)
- : RunControl(rc)
- , runConfig(qobject_cast<MaemoRunConfiguration *>(rc))
- , devConfig(runConfig ? runConfig->deviceConfig() : MaemoDeviceConfig())
-{
-#ifndef USE_SSH_LIB
- setProcessEnvironment(deployProcess);
- connect(&deployProcess, SIGNAL(readyReadStandardError()), this,
- SLOT(readStandardError()));
- connect(&deployProcess, SIGNAL(readyReadStandardOutput()), this,
- SLOT(readStandardOutput()));
- connect(&deployProcess, SIGNAL(error(QProcess::ProcessError)), &dumper,
- SLOT(printToStream(QProcess::ProcessError)));
- connect(&deployProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this,
- SLOT(deployProcessFinished()));
-#endif // USE_SSH_LIB
-}
-
-void AbstractMaemoRunControl::startDeployment(bool forDebugging)
-{
- QTC_ASSERT(runConfig, return);
-
-#ifndef USE_SSH_LIB
- Core::ICore::instance()->progressManager()->addTask(m_progress.future(),
- tr("Deploying"), QLatin1String("Maemo.Deploy"));
-#endif // USE_SSH_LIB
- if (devConfig.isValid()) {
- deployables.clear();
- if (runConfig->currentlyNeedsDeployment()) {
- deployables.append(Deployable(executableFileName(),
- QFileInfo(executableOnHost()).canonicalPath(),
- &MaemoRunConfiguration::wasDeployed));
- }
- if (forDebugging && runConfig->debuggingHelpersNeedDeployment()) {
- const QFileInfo &info(runConfig->dumperLib());
- deployables.append(Deployable(info.fileName(), info.canonicalPath(),
- &MaemoRunConfiguration::debuggingHelpersDeployed));
- }
-
-#ifndef USE_SSH_LIB
- m_progress.setProgressRange(0, deployables.count());
- m_progress.setProgressValue(0);
- m_progress.reportStarted();
-#endif // USE_SSH_LIB
- deploy();
- } else {
-#ifdef USE_SSH_LIB
- handleDeploymentFinished(false);
-#else
- deploymentFinished(false);
-#endif // USE_SSH_LIB
- }
-}
-
-void AbstractMaemoRunControl::deploy()
-{
-#ifdef USE_SSH_LIB
- if (!deployables.isEmpty()) {
- QStringList files;
- QStringList targetDirs;
- foreach (const Deployable &deployable, deployables) {
- files << deployable.dir + QDir::separator() + deployable.fileName;
- targetDirs << remoteDir();
- }
- emit addToOutputWindow(this, tr("Files to deploy: %1.").arg(files.join(" ")));
- sshDeployer.reset(new MaemoSshDeployer(devConfig, files, targetDirs));
- connect(sshDeployer.data(), SIGNAL(finished()),
- this, SLOT(deployProcessFinished()));
- connect(sshDeployer.data(), SIGNAL(fileCopied(QString)),
- this, SLOT(handleFileCopied()));
- Core::ICore::instance()->progressManager()
- ->addTask(m_progress.future(), tr("Deploying"),
- QLatin1String("Maemo.Deploy"));
- m_progress.setProgressRange(0, deployables.count());
- m_progress.setProgressValue(0);
- m_progress.reportStarted();
- emit started();
- sshDeployer->start();
- } else {
- handleDeploymentFinished(true);
- }
-#else
- if (!deployables.isEmpty()) {
- const Deployable &deployable = deployables.first();
- emit addToOutputWindow(this, tr("File to deploy: %1.").arg(deployable.fileName));
-
- QStringList cmdArgs;
- cmdArgs << "-P" << port() << options() << deployable.fileName
- << (devConfig.uname + "@" + devConfig.host + ":" + remoteDir());
- deployProcess.setWorkingDirectory(deployable.dir);
-
- deployProcess.start(runConfig->scpCmd(), cmdArgs);
- if (!deployProcess.waitForStarted()) {
- emit error(this, tr("Could not start scp. Deployment failed."));
- deployProcess.kill();
- } else {
- emit started();
- }
- } else {
- deploymentFinished(true);
- }
-#endif // USE_SSH_LIB
-}
-
-#ifdef USE_SSH_LIB
-void AbstractMaemoRunControl::handleFileCopied()
-{
- Deployable deployable = deployables.takeFirst();
- (runConfig->*deployable.updateTimestamp)();
- m_progress.setProgressValue(m_progress.progressValue() + 1);
-}
-#endif // USE_SSH_LIB
-
-void AbstractMaemoRunControl::stopDeployment()
-{
-#ifdef USE_SSH_LIB
- sshDeployer->stop();
-#else
- deployProcess.kill();
-#endif // USE_SSH_LIB
-}
-
-bool AbstractMaemoRunControl::isDeploying() const
-{
-#ifdef USE_SSH_LIB
- return !sshDeployer.isNull() && sshDeployer->isRunning();
-#else
- return deployProcess.state() != QProcess::NotRunning;
-#endif // USE_SSH_LIB
-}
-
-void AbstractMaemoRunControl::deployProcessFinished()
-{
-#if USE_SSH_LIB
- const bool success = !sshDeployer->hasError();
- if (success) {
- emit addToOutputWindow(this, tr("Deployment finished."));
- } else {
- emit error(this, tr("Deployment failed: ") % sshDeployer->error());
- m_progress.reportCanceled();
- }
- m_progress.reportFinished();
- handleDeploymentFinished(success);
-#else
- bool success;
- if (deployProcess.exitCode() == 0) {
- emit addToOutputWindow(this, tr("Target deployed."));
- success = true;
- Deployable deployable = deployables.takeFirst();
- (runConfig->*deployable.updateTimestamp)();
- m_progress.setProgressValue(m_progress.progressValue() + 1);
- } else {
- emit error(this, tr("Deployment failed."));
- success = false;
- }
- if (deployables.isEmpty() || !success)
- deploymentFinished(success);
- else
- deploy();
-#endif // USE_SSH_LIB
-}
-
-#ifndef USE_SSH_LIB
-void AbstractMaemoRunControl::deploymentFinished(bool success)
-{
- m_progress.reportFinished();
- handleDeploymentFinished(success);
-}
-#endif // USE_SSH_LIB
-
-const QString AbstractMaemoRunControl::executableOnHost() const
-{
- return runConfig->executable();
-}
-
-const QString AbstractMaemoRunControl::port() const
-{
- return QString::number(devConfig.port);
-}
-
-const QString AbstractMaemoRunControl::executableFileName() const
-{
- return QFileInfo(executableOnHost()).fileName();
-}
-
-const QString AbstractMaemoRunControl::remoteDir() const
-{
- return devConfig.uname == QString::fromLocal8Bit("root")
- ? QString::fromLocal8Bit("/root")
- : QString::fromLocal8Bit("/home/") + devConfig.uname;
-}
-
-const QStringList AbstractMaemoRunControl::options() const
-{
- const bool usePassword
- = devConfig.authentication == MaemoDeviceConfig::Password;
- const QLatin1String opt("-o");
- QStringList optionList;
- if (!usePassword)
- optionList << QLatin1String("-i") << devConfig.keyFile;
- return optionList << opt
- << QString::fromLatin1("PasswordAuthentication=%1").
- arg(usePassword ? "yes" : "no") << opt
- << QString::fromLatin1("PubkeyAuthentication=%1").
- arg(usePassword ? "no" : "yes") << opt
- << QString::fromLatin1("ConnectTimeout=%1").arg(devConfig.timeout)
- << opt << QLatin1String("CheckHostIP=no")
- << opt << QLatin1String("StrictHostKeyChecking=no");
-}
-
-const QString AbstractMaemoRunControl::executableOnTarget() const
-{
- return QString::fromLocal8Bit("%1/%2").arg(remoteDir()).
- arg(executableFileName());
-}
-
-const QString AbstractMaemoRunControl::targetCmdLinePrefix() const
-{
- return QString::fromLocal8Bit("chmod u+x %1; source /etc/profile; ").
- arg(executableOnTarget());
-}
-
-#ifndef USE_SSH_LIB
-bool AbstractMaemoRunControl::setProcessEnvironment(QProcess &process)
-{
- QTC_ASSERT(runConfig, return false);
- Qt4BuildConfiguration *qt4bc = qobject_cast<Qt4BuildConfiguration*>
- (runConfig->project()->activeBuildConfiguration());
- QTC_ASSERT(qt4bc, return false);
- Environment env = Environment::systemEnvironment();
- qt4bc->toolChain()->addToEnvironment(env);
- process.setEnvironment(env.toStringList());
-
- return true;
-}
-
-void AbstractMaemoRunControl::readStandardError()
-{
- QProcess *process = static_cast<QProcess *>(sender());
- const QByteArray &data = process->readAllStandardError();
- emit addToOutputWindow(this, QString::fromLocal8Bit(data.constData(),
- data.length()));
-}
-
-void AbstractMaemoRunControl::readStandardOutput()
-{
- QProcess *process = static_cast<QProcess *>(sender());
- const QByteArray &data = process->readAllStandardOutput();
- emit addToOutputWindow(this, QString::fromLocal8Bit(data.constData(),
- data.length()));
-}
-#endif // USE_SSH_LIB
-
-// #pragma mark -- MaemoRunControl
-
-
-MaemoRunControl::MaemoRunControl(RunConfiguration *runConfiguration)
- : AbstractMaemoRunControl(runConfiguration)
-{
-#ifndef USE_SSH_LIB
- setProcessEnvironment(sshProcess);
- setProcessEnvironment(stopProcess);
-
- connect(&sshProcess, SIGNAL(readyReadStandardError()), this,
- SLOT(readStandardError()));
- connect(&sshProcess, SIGNAL(readyReadStandardOutput()), this,
- SLOT(readStandardOutput()));
- connect(&sshProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this,
- SLOT(executionFinished()));
- connect(&sshProcess, SIGNAL(error(QProcess::ProcessError)), &dumper,
- SLOT(printToStream(QProcess::ProcessError)));
-#endif // USE_SSH_LIB
-}
-
-MaemoRunControl::~MaemoRunControl()
-{
- stop();
-#ifndef USE_SSH_LIB
- stopProcess.waitForFinished(5000);
-#endif
-}
-
-void MaemoRunControl::start()
-{
- stoppedByUser = false;
- startDeployment(false);
-}
-
-void MaemoRunControl::handleDeploymentFinished(bool success)
-{
- if (success)
- startExecution();
- else
- emit finished();
-}
-
-void MaemoRunControl::startExecution()
-{
-#ifdef USE_SSH_LIB
- const QString remoteCall = QString::fromLocal8Bit("%1 %2 %3")
- .arg(targetCmdLinePrefix()).arg(executableOnTarget())
- .arg(runConfig->arguments().join(" "));
- sshRunner.reset(new MaemoSshRunner(devConfig, remoteCall));
- connect(sshRunner.data(), SIGNAL(remoteOutput(QString)),
- this, SLOT(handleRemoteOutput(QString)));
- connect(sshRunner.data(), SIGNAL(finished()),
- this, SLOT(executionFinished()));
- emit addToOutputWindow(this, tr("Starting remote application."));
- emit started();
- sshRunner->start();
-#else
- const QString remoteCall = QString::fromLocal8Bit("%1 %2 %3")
- .arg(targetCmdLinePrefix()).arg(executableOnTarget())
- .arg(runConfig->arguments().join(" "));
-
- QStringList cmdArgs;
- cmdArgs << "-n" << "-p" << port() << "-l" << devConfig.uname
- << options() << devConfig.host << remoteCall;
- sshProcess.start(runConfig->sshCmd(), cmdArgs);
-
- sshProcess.start(runConfig->sshCmd(), cmdArgs);
- emit addToOutputWindow(this, tr("Starting remote application."));
- if (sshProcess.waitForStarted()) {
- emit started();
- } else {
- emit error(this, tr("Could not start ssh!"));
- sshProcess.kill();
- }
-#endif // USE_SSH_LIB
-}
-
-void MaemoRunControl::executionFinished()
-{
- if (stoppedByUser)
- emit addToOutputWindow(this, tr("Remote process stopped by user."));
-#ifdef USE_SSH_LIB
- else if (sshRunner->hasError())
- emit addToOutputWindow(this, tr("Remote process exited with error: ")
- % sshRunner->error());
-#else
- else if (sshProcess.exitCode() != 0)
- emit addToOutputWindow(this, tr("Remote process exited with error."));
-#endif // USE_SSH_LIB
- else
- emit addToOutputWindow(this, tr("Remote process finished successfully."));
- emit finished();
-}
-
-void MaemoRunControl::stop()
-{
- if (!isRunning())
- return;
-
- stoppedByUser = true;
- if (isDeploying()) {
- stopDeployment();
- } else {
-#ifdef USE_SSH_LIB
- sshRunner->stop();
- const QString remoteCall = QString::fromLocal8Bit("pkill -x %1; "
- "sleep 1; pkill -x -9 %1").arg(executableFileName());
- sshStopper.reset(new MaemoSshRunner(devConfig, remoteCall));
- sshStopper->start();
-#else
- stopProcess.kill();
- QStringList cmdArgs;
- const QString remoteCall = QString::fromLocal8Bit("pkill -x %1; "
- "sleep 1; pkill -x -9 %1").arg(executableFileName());
- cmdArgs << "-n" << "-p" << port() << "-l" << devConfig.uname
- << options() << devConfig.host << remoteCall;
- stopProcess.start(runConfig->sshCmd(), cmdArgs);
-#endif // USE_SSH_LIB
- }
-}
-
-bool MaemoRunControl::isRunning() const
-{
- return isDeploying()
-#ifdef USE_SSH_LIB
- || (!sshRunner.isNull() && sshRunner->isRunning());
-#else
- || sshProcess.state() != QProcess::NotRunning;
-#endif // USE_SSH_LIB
-}
-
-#ifdef USE_SSH_LIB
-void MaemoRunControl::handleRemoteOutput(const QString &output)
-{
- emit addToOutputWindowInline(this, output);
-}
-
-#endif // USE_SSH_LIB
-
-// #pragma mark -- MaemoDebugRunControl
-
-
-MaemoDebugRunControl::MaemoDebugRunControl(RunConfiguration *runConfiguration)
- : AbstractMaemoRunControl(runConfiguration)
- , gdbServerPort("10000"), debuggerManager(0)
- , startParams(new Debugger::DebuggerStartParameters)
-{
-#ifndef USE_SSH_LIB
- setProcessEnvironment(gdbServer);
- setProcessEnvironment(stopProcess);
-#endif // USE_SSH_LIB
-
- debuggerManager = ExtensionSystem::PluginManager::instance()
- ->getObject<Debugger::DebuggerManager>();
-
- QTC_ASSERT(debuggerManager != 0, return);
- startParams->startMode = Debugger::StartRemote;
- startParams->executable = executableOnHost();
- startParams->remoteChannel = devConfig.host + ":" + gdbServerPort;
- startParams->remoteArchitecture = "arm";
- startParams->sysRoot = runConfig->sysRoot();
- startParams->toolChainType = ToolChain::GCC_MAEMO;
- startParams->debuggerCommand = runConfig->gdbCmd();
- startParams->dumperLibrary = runConfig->dumperLib();
- startParams->remoteDumperLib = QString::fromLocal8Bit("%1/%2")
- .arg(remoteDir()).arg(QFileInfo(runConfig->dumperLib()).fileName());
-
- connect(this, SIGNAL(stopRequested()), debuggerManager, SLOT(exitDebugger()));
- connect(debuggerManager, SIGNAL(debuggingFinished()), this,
- SLOT(debuggingFinished()), Qt::QueuedConnection);
- connect(debuggerManager, SIGNAL(applicationOutputAvailable(QString)),
- this, SLOT(debuggerOutput(QString)), Qt::QueuedConnection);
-}
-
-MaemoDebugRunControl::~MaemoDebugRunControl()
-{
- disconnect(SIGNAL(addToOutputWindow(RunControl*,QString)));
- disconnect(SIGNAL(addToOutputWindowInline(RunControl*,QString)));
- stop();
- debuggingFinished();
-}
-
-void MaemoDebugRunControl::start()
-{
- startDeployment(true);
-}
-
-void MaemoDebugRunControl::handleDeploymentFinished(bool success)
-{
- if (success) {
- startGdbServer();
- } else {
- emit finished();
- }
-}
-
-void MaemoDebugRunControl::startGdbServer()
-{
- const QString remoteCall(QString::fromLocal8Bit("%1 gdbserver :%2 %3 %4").
- arg(targetCmdLinePrefix()).arg(gdbServerPort). arg(executableOnTarget())
- .arg(runConfig->arguments().join(" ")));
- inferiorPid = -1;
-#ifdef USE_SSH_LIB
- sshRunner.reset(new MaemoSshRunner(devConfig, remoteCall));
- connect(sshRunner.data(), SIGNAL(remoteOutput(QString)),
- this, SLOT(gdbServerStarted(QString)));
- sshRunner->start();
-#else
- QStringList sshArgs;
- sshArgs << "-t" << "-n" << "-l" << devConfig.uname << "-p"
- << port() << options() << devConfig.host << remoteCall;
- disconnect(&gdbServer, SIGNAL(readyReadStandardError()), 0, 0);
- connect(&gdbServer, SIGNAL(readyReadStandardError()), this,
- SLOT(gdbServerStarted()));
- gdbServer.start(runConfig->sshCmd(), sshArgs);
-#endif // USE_SSH_LIB
-}
-
-void MaemoDebugRunControl::gdbServerStartFailed(const QString &reason)
-{
- emit addToOutputWindow(this, tr("Debugging failed: %1").arg(reason));
- emit stopRequested();
- emit finished();
-}
-
-#ifdef USE_SSH_LIB
-void MaemoDebugRunControl::gdbServerStarted(const QString &output)
-{
- qDebug("gdbserver's stderr output: %s", output.toLatin1().data());
- if (inferiorPid != -1)
- return;
- const QString searchString("pid = ");
- const int searchStringLength = searchString.length();
- int pidStartPos = output.indexOf(searchString);
- const int pidEndPos = output.indexOf("\n", pidStartPos + searchStringLength);
- if (pidStartPos == -1 || pidEndPos == -1) {
- gdbServerStartFailed(output);
- return;
- }
- pidStartPos += searchStringLength;
- QString pidString = output.mid(pidStartPos, pidEndPos - pidStartPos);
- qDebug("pidString = %s", pidString.toLatin1().data());
- bool ok;
- const int pid = pidString.toInt(&ok);
- if (!ok) {
- gdbServerStartFailed(tr("Debugging failed, could not parse gdb "
- "server pid!"));
- return;
- }
- inferiorPid = pid;
- qDebug("inferiorPid = %d", inferiorPid);
-
- disconnect(sshRunner.data(), SIGNAL(remoteOutput(QString)), 0, 0);
- startDebugging();
-}
-#else
-void MaemoDebugRunControl::gdbServerStarted()
-{
- const QByteArray output = gdbServer.readAllStandardError();
- qDebug("gdbserver's stderr output: %s", output.data());
-
- const QByteArray searchString("pid = ");
- const int searchStringLength = searchString.length();
-
- int pidStartPos = output.indexOf(searchString);
- const int pidEndPos = output.indexOf("\n", pidStartPos + searchStringLength);
- if (pidStartPos == -1 || pidEndPos == -1) {
- gdbServerStartFailed(output.data());
- return;
- }
-
- pidStartPos += searchStringLength;
- QByteArray pidString = output.mid(pidStartPos, pidEndPos - pidStartPos);
- qDebug("pidString = %s", pidString.data());
-
- bool ok;
- const int pid = pidString.toInt(&ok);
- if (!ok) {
- gdbServerStartFailed(tr("Debugging failed, could not parse gdb "
- "server pid!"));
- return;
- }
-
- inferiorPid = pid;
- qDebug("inferiorPid = %d", inferiorPid);
-
- disconnect(&gdbServer, SIGNAL(readyReadStandardError()), 0, 0);
- connect(&gdbServer, SIGNAL(readyReadStandardError()), this,
- SLOT(readStandardError()));
- startDebugging();
-}
-#endif // USE_SSH_LIB
-
-void MaemoDebugRunControl::startDebugging()
-{
- debuggerManager->startNewDebugger(startParams);
-}
-
-void MaemoDebugRunControl::stop()
-{
- if (!isRunning())
- return;
- emit addToOutputWindow(this, tr("Stopping debugging operation ..."));
- if (isDeploying()) {
- stopDeployment();
- } else {
- emit stopRequested();
- }
-}
-
-bool MaemoDebugRunControl::isRunning() const
-{
- return isDeploying()
-#ifdef USE_SSH_LIB
- || (!sshRunner.isNull() && sshRunner->isRunning())
-#else
- || gdbServer.state() != QProcess::NotRunning
-#endif // USE_SSH_LIB
- || debuggerManager->state() != Debugger::DebuggerNotReady;
-}
-
-void MaemoDebugRunControl::debuggingFinished()
-{
-#ifdef USE_SSH_LIB
- if (!sshRunner.isNull() && sshRunner->isRunning()) {
- sshRunner->stop();
- const QString remoteCall = QString::fromLocal8Bit("kill %1; sleep 1; "
- "kill -9 %1; pkill -x -9 gdbserver").arg(inferiorPid);
- sshStopper.reset(new MaemoSshRunner(devConfig, remoteCall));
- sshStopper->start();
- }
-#else
- if (gdbServer.state() != QProcess::NotRunning) {
- stopProcess.kill();
- const QString remoteCall = QString::fromLocal8Bit("kill %1; sleep 1; "
- "kill -9 %1; pkill -x -9 gdbserver").arg(inferiorPid);
- QStringList sshArgs;
- sshArgs << "-n" << "-l" << devConfig.uname << "-p" << port()
- << options() << devConfig.host << remoteCall;
- stopProcess.start(runConfig->sshCmd(), sshArgs);
- }
- qDebug("ssh return code is %d", gdbServer.exitCode());
-#endif // USE_SSH_LIB
- emit addToOutputWindow(this, tr("Debugging finished."));
- emit finished();
-}
-
-void MaemoDebugRunControl::debuggerOutput(const QString &output)
-{
- emit addToOutputWindowInline(this, output);
-}
-
#include "maemorunconfiguration.moc"
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.cpp
new file mode 100644
index 00000000000..f5a379744b0
--- /dev/null
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.cpp
@@ -0,0 +1,661 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation ([email protected])
+**
+** This file is part of the Qt Creator.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at [email protected].
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "maemoruncontrol.h"
+
+#include "maemorunconfiguration.h"
+
+#ifndef USE_SSH_LIB
+#include "qt4buildconfiguration.h"
+#include "qt4project.h"
+#endif // USE_SSH_LIB
+
+#include <coreplugin/icore.h>
+#include <coreplugin/progressmanager/progressmanager.h>
+#include <extensionsystem/pluginmanager.h>
+#include <debugger/debuggermanager.h>
+#include <utils/qtcassert.h>
+
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtCore/QFuture>
+#include <QtCore/QStringBuilder>
+
+namespace Qt4ProjectManager {
+namespace Internal {
+
+AbstractMaemoRunControl::AbstractMaemoRunControl(RunConfiguration *rc)
+ : RunControl(rc)
+ , runConfig(qobject_cast<MaemoRunConfiguration *>(rc))
+ , devConfig(runConfig ? runConfig->deviceConfig() : MaemoDeviceConfig())
+{
+#ifndef USE_SSH_LIB
+ setProcessEnvironment(deployProcess);
+ connect(&deployProcess, SIGNAL(readyReadStandardError()), this,
+ SLOT(readStandardError()));
+ connect(&deployProcess, SIGNAL(readyReadStandardOutput()), this,
+ SLOT(readStandardOutput()));
+ connect(&deployProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this,
+ SLOT(deployProcessFinished()));
+#endif // USE_SSH_LIB
+}
+
+void AbstractMaemoRunControl::startDeployment(bool forDebugging)
+{
+ QTC_ASSERT(runConfig, return);
+
+#ifndef USE_SSH_LIB
+ Core::ICore::instance()->progressManager()->addTask(m_progress.future(),
+ tr("Deploying"), QLatin1String("Maemo.Deploy"));
+#endif // USE_SSH_LIB
+ if (devConfig.isValid()) {
+ deployables.clear();
+ if (runConfig->currentlyNeedsDeployment()) {
+ deployables.append(Deployable(executableFileName(),
+ QFileInfo(executableOnHost()).canonicalPath(),
+ &MaemoRunConfiguration::wasDeployed));
+ }
+ if (forDebugging && runConfig->debuggingHelpersNeedDeployment()) {
+ const QFileInfo &info(runConfig->dumperLib());
+ deployables.append(Deployable(info.fileName(), info.canonicalPath(),
+ &MaemoRunConfiguration::debuggingHelpersDeployed));
+ }
+
+#ifndef USE_SSH_LIB
+ m_progress.setProgressRange(0, deployables.count());
+ m_progress.setProgressValue(0);
+ m_progress.reportStarted();
+#endif // USE_SSH_LIB
+ deploy();
+ } else {
+#ifdef USE_SSH_LIB
+ handleDeploymentFinished(false);
+#else
+ deploymentFinished(false);
+#endif // USE_SSH_LIB
+ }
+}
+
+void AbstractMaemoRunControl::deploy()
+{
+#ifdef USE_SSH_LIB
+ if (!deployables.isEmpty()) {
+ QStringList files;
+ QStringList targetDirs;
+ foreach (const Deployable &deployable, deployables) {
+ files << deployable.dir + QDir::separator() + deployable.fileName;
+ targetDirs << remoteDir();
+ }
+ emit addToOutputWindow(this, tr("Files to deploy: %1.").arg(files.join(" ")));
+ sshDeployer.reset(new MaemoSshDeployer(devConfig, files, targetDirs));
+ connect(sshDeployer.data(), SIGNAL(finished()),
+ this, SLOT(deployProcessFinished()));
+ connect(sshDeployer.data(), SIGNAL(fileCopied(QString)),
+ this, SLOT(handleFileCopied()));
+ Core::ICore::instance()->progressManager()
+ ->addTask(m_progress.future(), tr("Deploying"),
+ QLatin1String("Maemo.Deploy"));
+ m_progress.setProgressRange(0, deployables.count());
+ m_progress.setProgressValue(0);
+ m_progress.reportStarted();
+ emit started();
+ sshDeployer->start();
+ } else {
+ handleDeploymentFinished(true);
+ }
+#else
+ if (!deployables.isEmpty()) {
+ const Deployable &deployable = deployables.first();
+ emit addToOutputWindow(this, tr("File to deploy: %1.").arg(deployable.fileName));
+
+ QStringList cmdArgs;
+ cmdArgs << "-P" << port() << options() << deployable.fileName
+ << (devConfig.uname + "@" + devConfig.host + ":" + remoteDir());
+ deployProcess.setWorkingDirectory(deployable.dir);
+
+ deployProcess.start(runConfig->scpCmd(), cmdArgs);
+ if (!deployProcess.waitForStarted()) {
+ emit error(this, tr("Could not start scp. Deployment failed."));
+ deployProcess.kill();
+ } else {
+ emit started();
+ }
+ } else {
+ deploymentFinished(true);
+ }
+#endif // USE_SSH_LIB
+}
+
+#ifdef USE_SSH_LIB
+void AbstractMaemoRunControl::handleFileCopied()
+{
+ Deployable deployable = deployables.takeFirst();
+ (runConfig->*deployable.updateTimestamp)();
+ m_progress.setProgressValue(m_progress.progressValue() + 1);
+}
+#endif // USE_SSH_LIB
+
+void AbstractMaemoRunControl::stopDeployment()
+{
+#ifdef USE_SSH_LIB
+ sshDeployer->stop();
+#else
+ deployProcess.kill();
+#endif // USE_SSH_LIB
+}
+
+bool AbstractMaemoRunControl::isDeploying() const
+{
+#ifdef USE_SSH_LIB
+ return !sshDeployer.isNull() && sshDeployer->isRunning();
+#else
+ return deployProcess.state() != QProcess::NotRunning;
+#endif // USE_SSH_LIB
+}
+
+void AbstractMaemoRunControl::deployProcessFinished()
+{
+#if USE_SSH_LIB
+ const bool success = !sshDeployer->hasError();
+ if (success) {
+ emit addToOutputWindow(this, tr("Deployment finished."));
+ } else {
+ emit error(this, tr("Deployment failed: ") % sshDeployer->error());
+ m_progress.reportCanceled();
+ }
+ m_progress.reportFinished();
+ handleDeploymentFinished(success);
+#else
+ bool success;
+ if (deployProcess.exitCode() == 0) {
+ emit addToOutputWindow(this, tr("Target deployed."));
+ success = true;
+ Deployable deployable = deployables.takeFirst();
+ (runConfig->*deployable.updateTimestamp)();
+ m_progress.setProgressValue(m_progress.progressValue() + 1);
+ } else {
+ emit error(this, tr("Deployment failed."));
+ success = false;
+ }
+ if (deployables.isEmpty() || !success)
+ deploymentFinished(success);
+ else
+ deploy();
+#endif // USE_SSH_LIB
+}
+
+#ifndef USE_SSH_LIB
+void AbstractMaemoRunControl::deploymentFinished(bool success)
+{
+ m_progress.reportFinished();
+ handleDeploymentFinished(success);
+}
+#endif // USE_SSH_LIB
+
+const QString AbstractMaemoRunControl::executableOnHost() const
+{
+ return runConfig->executable();
+}
+
+const QString AbstractMaemoRunControl::port() const
+{
+ return QString::number(devConfig.port);
+}
+
+const QString AbstractMaemoRunControl::executableFileName() const
+{
+ return QFileInfo(executableOnHost()).fileName();
+}
+
+const QString AbstractMaemoRunControl::remoteDir() const
+{
+ return devConfig.uname == QString::fromLocal8Bit("root")
+ ? QString::fromLocal8Bit("/root")
+ : QString::fromLocal8Bit("/home/") + devConfig.uname;
+}
+
+const QStringList AbstractMaemoRunControl::options() const
+{
+ const bool usePassword
+ = devConfig.authentication == MaemoDeviceConfig::Password;
+ const QLatin1String opt("-o");
+ QStringList optionList;
+ if (!usePassword)
+ optionList << QLatin1String("-i") << devConfig.keyFile;
+ return optionList << opt
+ << QString::fromLatin1("PasswordAuthentication=%1").
+ arg(usePassword ? "yes" : "no") << opt
+ << QString::fromLatin1("PubkeyAuthentication=%1").
+ arg(usePassword ? "no" : "yes") << opt
+ << QString::fromLatin1("ConnectTimeout=%1").arg(devConfig.timeout)
+ << opt << QLatin1String("CheckHostIP=no")
+ << opt << QLatin1String("StrictHostKeyChecking=no");
+}
+
+const QString AbstractMaemoRunControl::executableOnTarget() const
+{
+ return QString::fromLocal8Bit("%1/%2").arg(remoteDir()).
+ arg(executableFileName());
+}
+
+const QString AbstractMaemoRunControl::targetCmdLinePrefix() const
+{
+ return QString::fromLocal8Bit("chmod u+x %1; source /etc/profile; ").
+ arg(executableOnTarget());
+}
+
+#ifndef USE_SSH_LIB
+bool AbstractMaemoRunControl::setProcessEnvironment(QProcess &process)
+{
+ QTC_ASSERT(runConfig, return false);
+ Qt4BuildConfiguration *qt4bc = qobject_cast<Qt4BuildConfiguration*>
+ (runConfig->project()->activeBuildConfiguration());
+ QTC_ASSERT(qt4bc, return false);
+ Environment env = Environment::systemEnvironment();
+ qt4bc->toolChain()->addToEnvironment(env);
+ process.setEnvironment(env.toStringList());
+
+ return true;
+}
+
+void AbstractMaemoRunControl::readStandardError()
+{
+ QProcess *process = static_cast<QProcess *>(sender());
+ const QByteArray &data = process->readAllStandardError();
+ emit addToOutputWindow(this, QString::fromLocal8Bit(data.constData(),
+ data.length()));
+}
+
+void AbstractMaemoRunControl::readStandardOutput()
+{
+ QProcess *process = static_cast<QProcess *>(sender());
+ const QByteArray &data = process->readAllStandardOutput();
+ emit addToOutputWindow(this, QString::fromLocal8Bit(data.constData(),
+ data.length()));
+}
+#endif // USE_SSH_LIB
+
+// #pragma mark -- MaemoRunControl
+
+
+MaemoRunControl::MaemoRunControl(RunConfiguration *runConfiguration)
+ : AbstractMaemoRunControl(runConfiguration)
+{
+#ifndef USE_SSH_LIB
+ setProcessEnvironment(sshProcess);
+ setProcessEnvironment(stopProcess);
+
+ connect(&sshProcess, SIGNAL(readyReadStandardError()), this,
+ SLOT(readStandardError()));
+ connect(&sshProcess, SIGNAL(readyReadStandardOutput()), this,
+ SLOT(readStandardOutput()));
+ connect(&sshProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this,
+ SLOT(executionFinished()));
+#endif // USE_SSH_LIB
+}
+
+MaemoRunControl::~MaemoRunControl()
+{
+ stop();
+#ifndef USE_SSH_LIB
+ stopProcess.waitForFinished(5000);
+#endif
+}
+
+void MaemoRunControl::start()
+{
+ stoppedByUser = false;
+ startDeployment(false);
+}
+
+void MaemoRunControl::handleDeploymentFinished(bool success)
+{
+ if (success)
+ startExecution();
+ else
+ emit finished();
+}
+
+void MaemoRunControl::startExecution()
+{
+#ifdef USE_SSH_LIB
+ const QString remoteCall = QString::fromLocal8Bit("%1 %2 %3")
+ .arg(targetCmdLinePrefix()).arg(executableOnTarget())
+ .arg(runConfig->arguments().join(" "));
+ sshRunner.reset(new MaemoSshRunner(devConfig, remoteCall));
+ connect(sshRunner.data(), SIGNAL(remoteOutput(QString)),
+ this, SLOT(handleRemoteOutput(QString)));
+ connect(sshRunner.data(), SIGNAL(finished()),
+ this, SLOT(executionFinished()));
+ emit addToOutputWindow(this, tr("Starting remote application."));
+ emit started();
+ sshRunner->start();
+#else
+ const QString remoteCall = QString::fromLocal8Bit("%1 %2 %3")
+ .arg(targetCmdLinePrefix()).arg(executableOnTarget())
+ .arg(runConfig->arguments().join(" "));
+
+ QStringList cmdArgs;
+ cmdArgs << "-n" << "-p" << port() << "-l" << devConfig.uname
+ << options() << devConfig.host << remoteCall;
+ sshProcess.start(runConfig->sshCmd(), cmdArgs);
+
+ sshProcess.start(runConfig->sshCmd(), cmdArgs);
+ emit addToOutputWindow(this, tr("Starting remote application."));
+ if (sshProcess.waitForStarted()) {
+ emit started();
+ } else {
+ emit error(this, tr("Could not start ssh!"));
+ sshProcess.kill();
+ }
+#endif // USE_SSH_LIB
+}
+
+void MaemoRunControl::executionFinished()
+{
+ if (stoppedByUser)
+ emit addToOutputWindow(this, tr("Remote process stopped by user."));
+#ifdef USE_SSH_LIB
+ else if (sshRunner->hasError())
+ emit addToOutputWindow(this, tr("Remote process exited with error: ")
+ % sshRunner->error());
+#else
+ else if (sshProcess.exitCode() != 0)
+ emit addToOutputWindow(this, tr("Remote process exited with error."));
+#endif // USE_SSH_LIB
+ else
+ emit addToOutputWindow(this, tr("Remote process finished successfully."));
+ emit finished();
+}
+
+void MaemoRunControl::stop()
+{
+ if (!isRunning())
+ return;
+
+ stoppedByUser = true;
+ if (isDeploying()) {
+ stopDeployment();
+ } else {
+#ifdef USE_SSH_LIB
+ sshRunner->stop();
+ const QString remoteCall = QString::fromLocal8Bit("pkill -x %1; "
+ "sleep 1; pkill -x -9 %1").arg(executableFileName());
+ sshStopper.reset(new MaemoSshRunner(devConfig, remoteCall));
+ sshStopper->start();
+#else
+ stopProcess.kill();
+ QStringList cmdArgs;
+ const QString remoteCall = QString::fromLocal8Bit("pkill -x %1; "
+ "sleep 1; pkill -x -9 %1").arg(executableFileName());
+ cmdArgs << "-n" << "-p" << port() << "-l" << devConfig.uname
+ << options() << devConfig.host << remoteCall;
+ stopProcess.start(runConfig->sshCmd(), cmdArgs);
+#endif // USE_SSH_LIB
+ }
+}
+
+bool MaemoRunControl::isRunning() const
+{
+ return isDeploying()
+#ifdef USE_SSH_LIB
+ || (!sshRunner.isNull() && sshRunner->isRunning());
+#else
+ || sshProcess.state() != QProcess::NotRunning;
+#endif // USE_SSH_LIB
+}
+
+#ifdef USE_SSH_LIB
+void MaemoRunControl::handleRemoteOutput(const QString &output)
+{
+ emit addToOutputWindowInline(this, output);
+}
+
+#endif // USE_SSH_LIB
+
+// #pragma mark -- MaemoDebugRunControl
+
+
+MaemoDebugRunControl::MaemoDebugRunControl(RunConfiguration *runConfiguration)
+ : AbstractMaemoRunControl(runConfiguration)
+ , gdbServerPort("10000"), debuggerManager(0)
+ , startParams(new Debugger::DebuggerStartParameters)
+{
+#ifndef USE_SSH_LIB
+ setProcessEnvironment(gdbServer);
+ setProcessEnvironment(stopProcess);
+#endif // USE_SSH_LIB
+
+ debuggerManager = ExtensionSystem::PluginManager::instance()
+ ->getObject<Debugger::DebuggerManager>();
+
+ QTC_ASSERT(debuggerManager != 0, return);
+ startParams->startMode = Debugger::StartRemote;
+ startParams->executable = executableOnHost();
+ startParams->remoteChannel = devConfig.host + ":" + gdbServerPort;
+ startParams->remoteArchitecture = "arm";
+ startParams->sysRoot = runConfig->sysRoot();
+ startParams->toolChainType = ToolChain::GCC_MAEMO;
+ startParams->debuggerCommand = runConfig->gdbCmd();
+ startParams->dumperLibrary = runConfig->dumperLib();
+ startParams->remoteDumperLib = QString::fromLocal8Bit("%1/%2")
+ .arg(remoteDir()).arg(QFileInfo(runConfig->dumperLib()).fileName());
+
+ connect(this, SIGNAL(stopRequested()), debuggerManager, SLOT(exitDebugger()));
+ connect(debuggerManager, SIGNAL(debuggingFinished()), this,
+ SLOT(debuggingFinished()), Qt::QueuedConnection);
+ connect(debuggerManager, SIGNAL(applicationOutputAvailable(QString)),
+ this, SLOT(debuggerOutput(QString)), Qt::QueuedConnection);
+}
+
+MaemoDebugRunControl::~MaemoDebugRunControl()
+{
+ disconnect(SIGNAL(addToOutputWindow(RunControl*,QString)));
+ disconnect(SIGNAL(addToOutputWindowInline(RunControl*,QString)));
+ stop();
+ debuggingFinished();
+}
+
+void MaemoDebugRunControl::start()
+{
+ startDeployment(true);
+}
+
+void MaemoDebugRunControl::handleDeploymentFinished(bool success)
+{
+ if (success) {
+ startGdbServer();
+ } else {
+ emit finished();
+ }
+}
+
+void MaemoDebugRunControl::startGdbServer()
+{
+ const QString remoteCall(QString::fromLocal8Bit("%1 gdbserver :%2 %3 %4").
+ arg(targetCmdLinePrefix()).arg(gdbServerPort). arg(executableOnTarget())
+ .arg(runConfig->arguments().join(" ")));
+ inferiorPid = -1;
+#ifdef USE_SSH_LIB
+ sshRunner.reset(new MaemoSshRunner(devConfig, remoteCall));
+ connect(sshRunner.data(), SIGNAL(remoteOutput(QString)),
+ this, SLOT(gdbServerStarted(QString)));
+ sshRunner->start();
+#else
+ QStringList sshArgs;
+ sshArgs << "-t" << "-n" << "-l" << devConfig.uname << "-p"
+ << port() << options() << devConfig.host << remoteCall;
+ disconnect(&gdbServer, SIGNAL(readyReadStandardError()), 0, 0);
+ connect(&gdbServer, SIGNAL(readyReadStandardError()), this,
+ SLOT(gdbServerStarted()));
+ gdbServer.start(runConfig->sshCmd(), sshArgs);
+#endif // USE_SSH_LIB
+}
+
+void MaemoDebugRunControl::gdbServerStartFailed(const QString &reason)
+{
+ emit addToOutputWindow(this, tr("Debugging failed: %1").arg(reason));
+ emit stopRequested();
+ emit finished();
+}
+
+#ifdef USE_SSH_LIB
+void MaemoDebugRunControl::gdbServerStarted(const QString &output)
+{
+ qDebug("gdbserver's stderr output: %s", output.toLatin1().data());
+ if (inferiorPid != -1)
+ return;
+ const QString searchString("pid = ");
+ const int searchStringLength = searchString.length();
+ int pidStartPos = output.indexOf(searchString);
+ const int pidEndPos = output.indexOf("\n", pidStartPos + searchStringLength);
+ if (pidStartPos == -1 || pidEndPos == -1) {
+ gdbServerStartFailed(output);
+ return;
+ }
+ pidStartPos += searchStringLength;
+ QString pidString = output.mid(pidStartPos, pidEndPos - pidStartPos);
+ qDebug("pidString = %s", pidString.toLatin1().data());
+ bool ok;
+ const int pid = pidString.toInt(&ok);
+ if (!ok) {
+ gdbServerStartFailed(tr("Debugging failed, could not parse gdb "
+ "server pid!"));
+ return;
+ }
+ inferiorPid = pid;
+ qDebug("inferiorPid = %d", inferiorPid);
+
+ disconnect(sshRunner.data(), SIGNAL(remoteOutput(QString)), 0, 0);
+ startDebugging();
+}
+#else
+void MaemoDebugRunControl::gdbServerStarted()
+{
+ const QByteArray output = gdbServer.readAllStandardError();
+ qDebug("gdbserver's stderr output: %s", output.data());
+
+ const QByteArray searchString("pid = ");
+ const int searchStringLength = searchString.length();
+
+ int pidStartPos = output.indexOf(searchString);
+ const int pidEndPos = output.indexOf("\n", pidStartPos + searchStringLength);
+ if (pidStartPos == -1 || pidEndPos == -1) {
+ gdbServerStartFailed(output.data());
+ return;
+ }
+
+ pidStartPos += searchStringLength;
+ QByteArray pidString = output.mid(pidStartPos, pidEndPos - pidStartPos);
+ qDebug("pidString = %s", pidString.data());
+
+ bool ok;
+ const int pid = pidString.toInt(&ok);
+ if (!ok) {
+ gdbServerStartFailed(tr("Debugging failed, could not parse gdb "
+ "server pid!"));
+ return;
+ }
+
+ inferiorPid = pid;
+ qDebug("inferiorPid = %d", inferiorPid);
+
+ disconnect(&gdbServer, SIGNAL(readyReadStandardError()), 0, 0);
+ connect(&gdbServer, SIGNAL(readyReadStandardError()), this,
+ SLOT(readStandardError()));
+ startDebugging();
+}
+#endif // USE_SSH_LIB
+
+void MaemoDebugRunControl::startDebugging()
+{
+ debuggerManager->startNewDebugger(startParams);
+}
+
+void MaemoDebugRunControl::stop()
+{
+ if (!isRunning())
+ return;
+ emit addToOutputWindow(this, tr("Stopping debugging operation ..."));
+ if (isDeploying()) {
+ stopDeployment();
+ } else {
+ emit stopRequested();
+ }
+}
+
+bool MaemoDebugRunControl::isRunning() const
+{
+ return isDeploying()
+#ifdef USE_SSH_LIB
+ || (!sshRunner.isNull() && sshRunner->isRunning())
+#else
+ || gdbServer.state() != QProcess::NotRunning
+#endif // USE_SSH_LIB
+ || debuggerManager->state() != Debugger::DebuggerNotReady;
+}
+
+void MaemoDebugRunControl::debuggingFinished()
+{
+#ifdef USE_SSH_LIB
+ if (!sshRunner.isNull() && sshRunner->isRunning()) {
+ sshRunner->stop();
+ const QString remoteCall = QString::fromLocal8Bit("kill %1; sleep 1; "
+ "kill -9 %1; pkill -x -9 gdbserver").arg(inferiorPid);
+ sshStopper.reset(new MaemoSshRunner(devConfig, remoteCall));
+ sshStopper->start();
+ }
+#else
+ if (gdbServer.state() != QProcess::NotRunning) {
+ stopProcess.kill();
+ const QString remoteCall = QString::fromLocal8Bit("kill %1; sleep 1; "
+ "kill -9 %1; pkill -x -9 gdbserver").arg(inferiorPid);
+ QStringList sshArgs;
+ sshArgs << "-n" << "-l" << devConfig.uname << "-p" << port()
+ << options() << devConfig.host << remoteCall;
+ stopProcess.start(runConfig->sshCmd(), sshArgs);
+ }
+ qDebug("ssh return code is %d", gdbServer.exitCode());
+#endif // USE_SSH_LIB
+ emit addToOutputWindow(this, tr("Debugging finished."));
+ emit finished();
+}
+
+void MaemoDebugRunControl::debuggerOutput(const QString &output)
+{
+ emit addToOutputWindowInline(this, output);
+}
+
+} // namespace Internal
+} // namespace Qt4ProjectManager
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.h b/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.h
new file mode 100644
index 00000000000..b33cc849a69
--- /dev/null
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.h
@@ -0,0 +1,195 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation ([email protected])
+**
+** This file is part of the Qt Creator.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at [email protected].
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MAEMORUNCONTROL_H
+#define MAEMORUNCONTROL_H
+
+#include "maemodeviceconfigurations.h"
+#include "maemosshthread.h"
+
+#include <projectexplorer/runconfiguration.h>
+
+#include <QtCore/QFutureInterface>
+#ifndef USE_SSH_LIB
+#include <QtCore/QProcess>
+#endif
+#include <QtCore/QScopedPointer>
+#include <QtCore/QString>
+
+namespace Debugger {
+ class DebuggerManager;
+ class DebuggerStartParameters;
+} // namespace Debugger
+
+namespace Qt4ProjectManager {
+namespace Internal {
+
+class MaemoRunConfiguration;
+
+class AbstractMaemoRunControl : public ProjectExplorer::RunControl
+{
+ Q_OBJECT
+
+public:
+ AbstractMaemoRunControl(ProjectExplorer::RunConfiguration *runConfig);
+ virtual ~AbstractMaemoRunControl() {}
+
+protected:
+ void startDeployment(bool forDebugging);
+ void deploy();
+ void stopDeployment();
+ bool isDeploying() const;
+ const QString executableOnHost() const;
+ const QString executableOnTarget() const;
+ const QString executableFileName() const;
+ const QString port() const;
+ const QString targetCmdLinePrefix() const;
+ const QString remoteDir() const;
+ const QStringList options() const;
+#ifndef USE_SSH_LIB
+ void deploymentFinished(bool success);
+ virtual bool setProcessEnvironment(QProcess &process);
+#endif // USE_SSH_LIB
+private slots:
+#ifndef USE_SSH_LIB
+ void readStandardError();
+ void readStandardOutput();
+#endif // USE_SSH_LIB
+ void deployProcessFinished();
+#ifdef USE_SSH_LIB
+ void handleFileCopied();
+#endif
+
+protected:
+ MaemoRunConfiguration *runConfig; // TODO this pointer can be invalid
+ const MaemoDeviceConfig devConfig;
+
+private:
+ virtual void handleDeploymentFinished(bool success)=0;
+
+ QFutureInterface<void> m_progress;
+#ifdef USE_SSH_LIB
+ QScopedPointer<MaemoSshDeployer> sshDeployer;
+#else
+ QProcess deployProcess;
+#endif // USE_SSH_LIB
+ struct Deployable
+ {
+ typedef void (MaemoRunConfiguration::*updateFunc)();
+ Deployable(const QString &f, const QString &d, updateFunc u)
+ : fileName(f), dir(d), updateTimestamp(u) {}
+ QString fileName;
+ QString dir;
+ updateFunc updateTimestamp;
+ };
+ QList<Deployable> deployables;
+};
+
+class MaemoRunControl : public AbstractMaemoRunControl
+{
+ Q_OBJECT
+public:
+ MaemoRunControl(ProjectExplorer::RunConfiguration *runConfiguration);
+ ~MaemoRunControl();
+ void start();
+ void stop();
+ bool isRunning() const;
+
+private slots:
+ void executionFinished();
+#ifdef USE_SSH_LIB
+ void handleRemoteOutput(const QString &output);
+#endif
+
+private:
+ virtual void handleDeploymentFinished(bool success);
+ void startExecution();
+
+#ifdef USE_SSH_LIB
+ QScopedPointer<MaemoSshRunner> sshRunner;
+ QScopedPointer<MaemoSshRunner> sshStopper;
+#else
+ QProcess sshProcess;
+ QProcess stopProcess;
+#endif // USE_SSH_LIB
+ bool stoppedByUser;
+};
+
+class MaemoDebugRunControl : public AbstractMaemoRunControl
+{
+ Q_OBJECT
+public:
+ MaemoDebugRunControl(ProjectExplorer::RunConfiguration *runConfiguration);
+ ~MaemoDebugRunControl();
+ void start();
+ void stop();
+ bool isRunning() const;
+ Q_SLOT void debuggingFinished();
+
+signals:
+ void stopRequested();
+
+private slots:
+#ifdef USE_SSH_LIB
+ void gdbServerStarted(const QString &output);
+#else
+ void gdbServerStarted();
+#endif // USE_SSH_LIB
+
+ void debuggerOutput(const QString &output);
+
+private:
+ virtual void handleDeploymentFinished(bool success);
+
+ void startGdbServer();
+ void gdbServerStartFailed(const QString &reason);
+ void startDebugging();
+
+#ifdef USE_SSH_LIB
+ QScopedPointer<MaemoSshRunner> sshRunner;
+ QScopedPointer<MaemoSshRunner> sshStopper;
+#else
+ QProcess gdbServer;
+ QProcess stopProcess;
+#endif // USE_SSH_LIB
+ const QString gdbServerPort;
+ Debugger::DebuggerManager *debuggerManager;
+ QSharedPointer<Debugger::DebuggerStartParameters> startParams;
+ int inferiorPid;
+};
+
+} // namespace Internal
+} // namespace Qt4ProjectManager
+
+#endif // MAEMORUNCONTROL_H
diff --git a/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.pri b/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.pri
index 49eda97133b..b442f41cbf1 100644
--- a/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.pri
+++ b/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.pri
@@ -3,21 +3,24 @@ SUPPORT_QT_MAEMO = $$(QTCREATOR_WITH_MAEMO)
message("Adding experimental support for Qt/Maemo applications.")
DEFINES += QTCREATOR_WITH_MAEMO
# DEFINES += USE_SSH_LIB
-# LIBS += -L/opt/ne7ssh/lib/ -lnet7ssh
+# LIBS += -L/opt/ne7sshModified/lib/ \
+# -lnet7ssh
HEADERS += $$PWD/maemorunconfiguration.h \
$$PWD/maemomanager.h \
$$PWD/maemotoolchain.h \
$$PWD/maemodeviceconfigurations.h \
$$PWD/maemosettingspage.h \
$$PWD/maemosshconnection.h \
- $$PWD/maemosshthread.h
+ $$PWD/maemosshthread.h \
+ $$PWD/maemoruncontrol.h
SOURCES += $$PWD/maemorunconfiguration.cpp \
$$PWD/maemomanager.cpp \
$$PWD/maemotoolchain.cpp \
$$PWD/maemodeviceconfigurations.cpp \
$$PWD/maemosettingspage.cpp \
$$PWD/maemosshconnection.cpp \
- $$PWD/maemosshthread.cpp
+ $$PWD/maemosshthread.cpp \
+ $$PWD/maemoruncontrol.cpp
FORMS += $$PWD/maemosettingswidget.ui
RESOURCES += $$PWD/qt-maemo.qrc
}