forked from qt-creator/qt-creator
WinRT: Enable debugging for local packages.
Change-Id: Ic04f1a471f951caf7a79c69cceecb0ebd5d09919 Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
@@ -2699,8 +2699,7 @@ void CdbEngine::parseOutputLine(QByteArray line)
|
|||||||
m_autoBreakPointCorrection = major > 6 || (major == 6 && minor >= 2 && minor < 10);
|
m_autoBreakPointCorrection = major > 6 || (major == 6 && minor >= 2 && minor < 10);
|
||||||
showMessage(QString::fromLocal8Bit(line), LogMisc);
|
showMessage(QString::fromLocal8Bit(line), LogMisc);
|
||||||
showMessage(QString::fromLatin1("Using ")
|
showMessage(QString::fromLatin1("Using ")
|
||||||
+ m_autoBreakPointCorrection ? QLatin1String("CDB ")
|
+ QLatin1String(m_autoBreakPointCorrection ? "CDB " : "codemodel ")
|
||||||
: QLatin1String("codemodel ")
|
|
||||||
+ QString::fromLatin1("based breakpoint correction."), LogMisc);
|
+ QString::fromLatin1("based breakpoint correction."), LogMisc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,18 +135,6 @@ int breakPointIdToCdbId(const BreakpointModelId &id)
|
|||||||
return cdbBreakPointStartId + id.majorPart() * cdbBreakPointIdMinorPart + id.minorPart();
|
return cdbBreakPointStartId + id.majorPart() * cdbBreakPointIdMinorPart + id.minorPart();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ModelId>
|
|
||||||
inline ModelId cdbIdToBreakpointId(const GdbMi &data)
|
|
||||||
{
|
|
||||||
if (data.isValid()) { // Might not be valid if there is not id
|
|
||||||
bool ok;
|
|
||||||
const int id = data.data().toInt(&ok);
|
|
||||||
if (ok)
|
|
||||||
return cdbIdToBreakpointId<ModelId>(id);
|
|
||||||
}
|
|
||||||
return ModelId();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class ModelId>
|
template <class ModelId>
|
||||||
inline ModelId cdbIdToBreakpointId(const int &id)
|
inline ModelId cdbIdToBreakpointId(const int &id)
|
||||||
{
|
{
|
||||||
@@ -161,6 +149,18 @@ inline ModelId cdbIdToBreakpointId(const int &id)
|
|||||||
return ModelId();
|
return ModelId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class ModelId>
|
||||||
|
inline ModelId cdbIdToBreakpointId(const GdbMi &data)
|
||||||
|
{
|
||||||
|
if (data.isValid()) { // Might not be valid if there is not id
|
||||||
|
bool ok;
|
||||||
|
const int id = data.data().toInt(&ok);
|
||||||
|
if (ok)
|
||||||
|
return cdbIdToBreakpointId<ModelId>(id);
|
||||||
|
}
|
||||||
|
return ModelId();
|
||||||
|
}
|
||||||
|
|
||||||
BreakpointModelId cdbIdToBreakpointModelId(const GdbMi &id)
|
BreakpointModelId cdbIdToBreakpointModelId(const GdbMi &id)
|
||||||
{
|
{
|
||||||
return cdbIdToBreakpointId<BreakpointModelId>(id);
|
return cdbIdToBreakpointId<BreakpointModelId>(id);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ include(../../qtcreatorplugin.pri)
|
|||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
winrtconstants.h \
|
winrtconstants.h \
|
||||||
|
winrtdebugsupport.h \
|
||||||
winrtdeployconfiguration.h \
|
winrtdeployconfiguration.h \
|
||||||
winrtdevice.h \
|
winrtdevice.h \
|
||||||
winrtdevicefactory.h \
|
winrtdevicefactory.h \
|
||||||
@@ -14,9 +15,11 @@ HEADERS += \
|
|||||||
winrtrunconfiguration.h \
|
winrtrunconfiguration.h \
|
||||||
winrtrunconfigurationwidget.h \
|
winrtrunconfigurationwidget.h \
|
||||||
winrtruncontrol.h \
|
winrtruncontrol.h \
|
||||||
winrtrunfactories.h
|
winrtrunfactories.h \
|
||||||
|
winrtrunnerhelper.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
winrtdebugsupport.cpp \
|
||||||
winrtdeployconfiguration.cpp \
|
winrtdeployconfiguration.cpp \
|
||||||
winrtdevice.cpp \
|
winrtdevice.cpp \
|
||||||
winrtdevicefactory.cpp \
|
winrtdevicefactory.cpp \
|
||||||
@@ -29,7 +32,8 @@ SOURCES += \
|
|||||||
winrtrunconfiguration.cpp \
|
winrtrunconfiguration.cpp \
|
||||||
winrtrunconfigurationwidget.cpp \
|
winrtrunconfigurationwidget.cpp \
|
||||||
winrtruncontrol.cpp \
|
winrtruncontrol.cpp \
|
||||||
winrtrunfactories.cpp
|
winrtrunfactories.cpp \
|
||||||
|
winrtrunnerhelper.cpp
|
||||||
|
|
||||||
DEFINES += WINRT_LIBRARY
|
DEFINES += WINRT_LIBRARY
|
||||||
|
|
||||||
|
|||||||
@@ -7,12 +7,15 @@ QtcPlugin {
|
|||||||
minimumQtVersion: "5.0"
|
minimumQtVersion: "5.0"
|
||||||
|
|
||||||
Depends { name: "Core" }
|
Depends { name: "Core" }
|
||||||
|
Depends { name: "Debugger" }
|
||||||
Depends { name: "ProjectExplorer" }
|
Depends { name: "ProjectExplorer" }
|
||||||
Depends { name: "QtSupport" }
|
Depends { name: "QtSupport" }
|
||||||
Depends { name: "Qt.gui" }
|
Depends { name: "Qt.gui" }
|
||||||
|
|
||||||
files: [
|
files: [
|
||||||
"winrtconstants.h",
|
"winrtconstants.h",
|
||||||
|
"winrtdebugsupport.cpp",
|
||||||
|
"winrtdebugsupport.h",
|
||||||
"winrtdeployconfiguration.cpp",
|
"winrtdeployconfiguration.cpp",
|
||||||
"winrtdeployconfiguration.h",
|
"winrtdeployconfiguration.h",
|
||||||
"winrtdevice.cpp",
|
"winrtdevice.cpp",
|
||||||
@@ -40,6 +43,8 @@ QtcPlugin {
|
|||||||
"winrtruncontrol.cpp",
|
"winrtruncontrol.cpp",
|
||||||
"winrtruncontrol.h",
|
"winrtruncontrol.h",
|
||||||
"winrtrunfactories.cpp",
|
"winrtrunfactories.cpp",
|
||||||
"winrtrunfactories.h"
|
"winrtrunfactories.h",
|
||||||
|
"winrtrunnerhelper.cpp",
|
||||||
|
"winrtrunnerhelper.h"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
QTC_PLUGIN_NAME = WinRt
|
QTC_PLUGIN_NAME = WinRt
|
||||||
QTC_PLUGIN_DEPENDS += \
|
QTC_PLUGIN_DEPENDS += \
|
||||||
coreplugin \
|
coreplugin \
|
||||||
|
debugger \
|
||||||
projectexplorer \
|
projectexplorer \
|
||||||
qtsupport
|
qtsupport
|
||||||
|
|||||||
141
src/plugins/winrt/winrtdebugsupport.cpp
Normal file
141
src/plugins/winrt/winrtdebugsupport.cpp
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** 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 Digia. For licensing terms and
|
||||||
|
** conditions see http://qt.digia.com/licensing. For further information
|
||||||
|
** use the contact form at http://qt.digia.com/contact-us.
|
||||||
|
**
|
||||||
|
** 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, Digia gives you certain additional
|
||||||
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "winrtdebugsupport.h"
|
||||||
|
#include "winrtrunconfiguration.h"
|
||||||
|
#include "winrtrunnerhelper.h"
|
||||||
|
|
||||||
|
#include <debugger/debuggerengine.h>
|
||||||
|
#include <debugger/debuggerkitinformation.h>
|
||||||
|
#include <debugger/debuggerplugin.h>
|
||||||
|
#include <debugger/debuggerrunner.h>
|
||||||
|
#include <debugger/debuggerstartparameters.h>
|
||||||
|
#include <projectexplorer/target.h>
|
||||||
|
#include <projectexplorer/toolchain.h>
|
||||||
|
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QLocalServer>
|
||||||
|
#include <QLocalSocket>
|
||||||
|
|
||||||
|
#include <utils/qtcprocess.h>
|
||||||
|
|
||||||
|
namespace WinRt {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
using namespace ProjectExplorer;
|
||||||
|
|
||||||
|
WinRtDebugSupport::WinRtDebugSupport(RunControl *runControl, WinRtRunnerHelper *runner)
|
||||||
|
: QObject(runControl)
|
||||||
|
, m_debugRunControl(runControl)
|
||||||
|
, m_runner(runner)
|
||||||
|
{
|
||||||
|
connect(m_debugRunControl, SIGNAL(finished()), this, SLOT(finish()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void WinRtDebugSupport::finish()
|
||||||
|
{
|
||||||
|
m_runner->stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
RunControl *WinRtDebugSupport::createDebugRunControl(WinRtRunConfiguration *runConfig,
|
||||||
|
RunMode mode,
|
||||||
|
QString *errorMessage)
|
||||||
|
{
|
||||||
|
// FIXME: This is just working for local debugging;
|
||||||
|
using namespace Debugger;
|
||||||
|
DebuggerStartParameters params;
|
||||||
|
params.startMode = AttachExternal;
|
||||||
|
params.languages |= CppLanguage;
|
||||||
|
params.breakOnMain = mode == DebugRunModeWithBreakOnMain;
|
||||||
|
// The first Thread needs to be resumed manually.
|
||||||
|
params.commandsAfterConnect = "~0 m";
|
||||||
|
Kit *kit = runConfig->target()->kit();
|
||||||
|
params.debuggerCommand = DebuggerKitInformation::debuggerCommand(kit).toString();
|
||||||
|
if (ToolChain *tc = ToolChainKitInformation::toolChain(kit))
|
||||||
|
params.toolChainAbi = tc->targetAbi();
|
||||||
|
|
||||||
|
QFileInfo debuggerHelper(QCoreApplication::applicationDirPath()
|
||||||
|
+ QLatin1String("/winrtdebughelper.exe"));
|
||||||
|
if (!debuggerHelper.isExecutable()) {
|
||||||
|
*errorMessage = tr("The WinRT debugging helper is missing from your Qt Creator "
|
||||||
|
"installation. It was assumed to be located at").arg(
|
||||||
|
debuggerHelper.absoluteFilePath());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
WinRtRunnerHelper *runner = new WinRtRunnerHelper(runConfig, errorMessage);
|
||||||
|
if (!errorMessage->isEmpty())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
runner->debug(debuggerHelper.absoluteFilePath());
|
||||||
|
if (!runner->waitForStarted()) {
|
||||||
|
*errorMessage = tr("Cannot start the WinRT Runner Tool.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QLocalServer server;
|
||||||
|
server.listen(QLatin1String("QtCreatorWinRtDebugPIDPipe"));
|
||||||
|
if (!server.waitForNewConnection(10000)) {
|
||||||
|
*errorMessage = tr("Cannot establish connection to the WinRT debugging helper.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (server.hasPendingConnections()) {
|
||||||
|
QLocalSocket *connection = server.nextPendingConnection();
|
||||||
|
if (connection->waitForReadyRead(1000)) {
|
||||||
|
const QByteArray &output = connection->readAll();
|
||||||
|
QList<QByteArray> arg = output.split(':');
|
||||||
|
if (arg.first() == "PID") {
|
||||||
|
bool ok =false;
|
||||||
|
params.attachPID = arg.last().toInt(&ok);
|
||||||
|
if (!ok) {
|
||||||
|
*errorMessage = tr("Cannot extract the PID from the WinRT debugging helper. "
|
||||||
|
"(output: %1)").arg(QString::fromLocal8Bit(output));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
server.close();
|
||||||
|
Debugger::DebuggerRunControl *debugRunControl
|
||||||
|
= DebuggerPlugin::createDebugger(params, runConfig, errorMessage);
|
||||||
|
runner->setRunControl(debugRunControl);
|
||||||
|
new WinRtDebugSupport(debugRunControl, runner);
|
||||||
|
return debugRunControl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
server.close();
|
||||||
|
|
||||||
|
*errorMessage = tr("Cannot create an appropriate run control for "
|
||||||
|
"the current run configuration.");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace WinRt
|
||||||
65
src/plugins/winrt/winrtdebugsupport.h
Normal file
65
src/plugins/winrt/winrtdebugsupport.h
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** 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 Digia. For licensing terms and
|
||||||
|
** conditions see http://qt.digia.com/licensing. For further information
|
||||||
|
** use the contact form at http://qt.digia.com/contact-us.
|
||||||
|
**
|
||||||
|
** 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, Digia gives you certain additional
|
||||||
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef WINRT_INTERNAL_WINRTDEBUGSUPPORT_H
|
||||||
|
#define WINRT_INTERNAL_WINRTDEBUGSUPPORT_H
|
||||||
|
|
||||||
|
#include <projectexplorer/runconfiguration.h>
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
namespace WinRt {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
class WinRtRunConfiguration;
|
||||||
|
class WinRtRunnerHelper;
|
||||||
|
|
||||||
|
class WinRtDebugSupport : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
static ProjectExplorer::RunControl *createDebugRunControl(WinRtRunConfiguration *runConfig,
|
||||||
|
ProjectExplorer::RunMode mode,
|
||||||
|
QString *errorMessage);
|
||||||
|
|
||||||
|
private:
|
||||||
|
WinRtDebugSupport(ProjectExplorer::RunControl *runControl, WinRtRunnerHelper *runner);
|
||||||
|
|
||||||
|
ProjectExplorer::RunControl *m_debugRunControl;
|
||||||
|
WinRtRunnerHelper *m_runner;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void finish();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace WinRt
|
||||||
|
|
||||||
|
#endif // WINRT_INTERNAL_WINRTDEBUGSUPPORT_H
|
||||||
@@ -30,6 +30,7 @@
|
|||||||
#include "winrtdevice.h"
|
#include "winrtdevice.h"
|
||||||
#include "winrtconstants.h"
|
#include "winrtconstants.h"
|
||||||
|
|
||||||
|
#include <projectexplorer/devicesupport/desktopprocesssignaloperation.h>
|
||||||
#include <projectexplorer/devicesupport/devicemanager.h>
|
#include <projectexplorer/devicesupport/devicemanager.h>
|
||||||
#include <projectexplorer/devicesupport/deviceprocesslist.h>
|
#include <projectexplorer/devicesupport/deviceprocesslist.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
@@ -84,9 +85,16 @@ void WinRtDevice::executeAction(Core::Id actionId, QWidget *parent)
|
|||||||
Q_UNUSED(parent);
|
Q_UNUSED(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
ProjectExplorer::DeviceProcessSignalOperation::Ptr WinRtDevice::signalOperation() const
|
DeviceProcessSignalOperation::Ptr WinRtDevice::signalOperation() const
|
||||||
{
|
{
|
||||||
return DeviceProcessSignalOperation::Ptr();
|
class WinRtDesktopSignalOperation : public ProjectExplorer::DesktopProcessSignalOperation
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WinRtDesktopSignalOperation() {}
|
||||||
|
~WinRtDesktopSignalOperation() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
return DeviceProcessSignalOperation::Ptr(new WinRtDesktopSignalOperation());
|
||||||
}
|
}
|
||||||
|
|
||||||
void WinRtDevice::fromMap(const QVariantMap &map)
|
void WinRtDevice::fromMap(const QVariantMap &map)
|
||||||
|
|||||||
@@ -28,9 +28,10 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "winrtruncontrol.h"
|
#include "winrtruncontrol.h"
|
||||||
#include "winrtrunconfiguration.h"
|
|
||||||
#include "winrtconstants.h"
|
|
||||||
#include "winrtdevice.h"
|
#include "winrtdevice.h"
|
||||||
|
#include "winrtrunconfiguration.h"
|
||||||
|
#include "winrtrunnerhelper.h"
|
||||||
|
|
||||||
#include <coreplugin/idocument.h>
|
#include <coreplugin/idocument.h>
|
||||||
#include <extensionsystem/pluginmanager.h>
|
#include <extensionsystem/pluginmanager.h>
|
||||||
@@ -41,7 +42,8 @@
|
|||||||
#include <projectexplorer/kitinformation.h>
|
#include <projectexplorer/kitinformation.h>
|
||||||
#include <qtsupport/qtkitinformation.h>
|
#include <qtsupport/qtkitinformation.h>
|
||||||
|
|
||||||
using ProjectExplorer::BuildConfiguration;
|
#include <QTimer>
|
||||||
|
|
||||||
using ProjectExplorer::DeviceKitInformation;
|
using ProjectExplorer::DeviceKitInformation;
|
||||||
using ProjectExplorer::IDevice;
|
using ProjectExplorer::IDevice;
|
||||||
using ProjectExplorer::RunControl;
|
using ProjectExplorer::RunControl;
|
||||||
@@ -54,39 +56,10 @@ namespace Internal {
|
|||||||
|
|
||||||
WinRtRunControl::WinRtRunControl(WinRtRunConfiguration *runConfiguration, RunMode mode)
|
WinRtRunControl::WinRtRunControl(WinRtRunConfiguration *runConfiguration, RunMode mode)
|
||||||
: RunControl(runConfiguration, mode)
|
: RunControl(runConfiguration, mode)
|
||||||
|
, m_runConfiguration(runConfiguration)
|
||||||
, m_state(StoppedState)
|
, m_state(StoppedState)
|
||||||
, m_process(0)
|
, m_runner(0)
|
||||||
{
|
{
|
||||||
Target *target = runConfiguration->target();
|
|
||||||
IDevice::ConstPtr device = DeviceKitInformation::device(target->kit());
|
|
||||||
m_device = device.dynamicCast<const WinRtDevice>();
|
|
||||||
|
|
||||||
const QtSupport::BaseQtVersion *qt = QtSupport::QtKitInformation::qtVersion(target->kit());
|
|
||||||
if (!qt) {
|
|
||||||
appendMessage(tr("The current kit has no Qt version."),
|
|
||||||
Utils::ErrorMessageFormat);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_isWinPhone = (qt->type() == QLatin1String(Constants::WINRT_WINPHONEQT));
|
|
||||||
m_runnerFilePath = qt->binPath().toString() + QStringLiteral("/winrtrunner.exe");
|
|
||||||
if (!QFile::exists(m_runnerFilePath)) {
|
|
||||||
appendMessage(tr("Cannot find winrtrunner.exe in \"%1\".").arg(
|
|
||||||
QDir::toNativeSeparators(qt->binPath().toString())),
|
|
||||||
Utils::ErrorMessageFormat);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Utils::FileName proFile = Utils::FileName::fromString(
|
|
||||||
target->project()->document()->filePath());
|
|
||||||
m_executableFilePath = target->applicationTargets().targetForProject(proFile).toString()
|
|
||||||
+ QStringLiteral(".exe"); // ### we should not need to append ".exe" here.
|
|
||||||
|
|
||||||
m_arguments = runConfiguration->arguments();
|
|
||||||
m_uninstallAfterStop = runConfiguration->uninstallAfterStop();
|
|
||||||
|
|
||||||
if (BuildConfiguration *bc = target->activeBuildConfiguration())
|
|
||||||
m_environment = bc->environment();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WinRtRunControl::start()
|
void WinRtRunControl::start()
|
||||||
@@ -99,13 +72,10 @@ void WinRtRunControl::start()
|
|||||||
|
|
||||||
RunControl::StopResult WinRtRunControl::stop()
|
RunControl::StopResult WinRtRunControl::stop()
|
||||||
{
|
{
|
||||||
if (m_state != StartedState) {
|
if (m_state == StoppedState)
|
||||||
m_state = StoppedState;
|
|
||||||
return StoppedSynchronously;
|
return StoppedSynchronously;
|
||||||
}
|
|
||||||
|
|
||||||
QTC_ASSERT(m_process, return StoppedSynchronously);
|
m_runner->stop();
|
||||||
m_process->interrupt();
|
|
||||||
return AsynchronousStop;
|
return AsynchronousStop;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,84 +96,31 @@ void WinRtRunControl::onProcessStarted()
|
|||||||
emit started();
|
emit started();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WinRtRunControl::onProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
void WinRtRunControl::onProcessFinished()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_process, return);
|
|
||||||
QTC_CHECK(m_state == StartedState);
|
QTC_CHECK(m_state == StartedState);
|
||||||
|
onProcessError();
|
||||||
if (exitStatus == QProcess::CrashExit) {
|
|
||||||
appendMessage(tr("winrtrunner crashed.") + QLatin1Char('\n'), Utils::ErrorMessageFormat);
|
|
||||||
} else if (exitCode != 0) {
|
|
||||||
appendMessage(tr("winrtrunner returned with exit code %1.").arg(exitCode)
|
|
||||||
+ QLatin1Char('\n'), Utils::ErrorMessageFormat);
|
|
||||||
} else {
|
|
||||||
appendMessage(tr("winrtrunner finished successfully.")
|
|
||||||
+ QLatin1Char('\n'), Utils::NormalMessageFormat);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_process->disconnect();
|
|
||||||
m_process->deleteLater();
|
|
||||||
m_process = 0;
|
|
||||||
m_state = StoppedState;
|
|
||||||
emit finished();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WinRtRunControl::onProcessError()
|
void WinRtRunControl::onProcessError()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_process, return);
|
QTC_ASSERT(m_runner, return);
|
||||||
appendMessage(tr("Error while executing winrtrunner: %1\n").arg(m_process->errorString()),
|
m_runner->disconnect();
|
||||||
Utils::ErrorMessageFormat);
|
m_runner->deleteLater();
|
||||||
m_process->disconnect();
|
m_runner = 0;
|
||||||
m_process->deleteLater();
|
|
||||||
m_process = 0;
|
|
||||||
m_state = StoppedState;
|
m_state = StoppedState;
|
||||||
emit finished();
|
emit finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WinRtRunControl::onProcessReadyReadStdOut()
|
|
||||||
{
|
|
||||||
QTC_ASSERT(m_process, return);
|
|
||||||
appendMessage(QString::fromLocal8Bit(m_process->readAllStandardOutput()), Utils::StdOutFormat);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WinRtRunControl::onProcessReadyReadStdErr()
|
|
||||||
{
|
|
||||||
QTC_ASSERT(m_process, return);
|
|
||||||
appendMessage(QString::fromLocal8Bit(m_process->readAllStandardError()), Utils::StdErrFormat);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WinRtRunControl::startWinRtRunner()
|
bool WinRtRunControl::startWinRtRunner()
|
||||||
{
|
{
|
||||||
QString runnerArgs;
|
QTC_ASSERT(!m_runner, return false);
|
||||||
QtcProcess::addArg(&runnerArgs, QStringLiteral("--profile"));
|
m_runner = new WinRtRunnerHelper(this);
|
||||||
QtcProcess::addArg(&runnerArgs, m_isWinPhone ? QStringLiteral("xap") : QStringLiteral("appx"));
|
connect(m_runner, SIGNAL(started()), SLOT(onProcessStarted()));
|
||||||
if (m_device) {
|
connect(m_runner, SIGNAL(finished(int,QProcess::ExitStatus)), SLOT(onProcessFinished()));
|
||||||
QtcProcess::addArg(&runnerArgs, QStringLiteral("--device"));
|
connect(m_runner, SIGNAL(error(QProcess::ProcessError)), SLOT(onProcessError()));
|
||||||
QtcProcess::addArg(&runnerArgs, QString::number(m_device->deviceId()));
|
|
||||||
}
|
|
||||||
QtcProcess::addArgs(&runnerArgs, QStringLiteral("--install --start --stop --wait 0"));
|
|
||||||
QtcProcess::addArg(&runnerArgs, m_executableFilePath);
|
|
||||||
if (!m_arguments.isEmpty())
|
|
||||||
QtcProcess::addArgs(&runnerArgs, m_arguments);
|
|
||||||
|
|
||||||
appendMessage(QStringLiteral("winrtrunner ") + runnerArgs + QLatin1Char('\n'),
|
|
||||||
Utils::NormalMessageFormat);
|
|
||||||
|
|
||||||
QTC_ASSERT(!m_process, m_process->deleteLater());
|
|
||||||
m_process = new QtcProcess(this);
|
|
||||||
connect(m_process, SIGNAL(started()), SLOT(onProcessStarted()));
|
|
||||||
connect(m_process, SIGNAL(finished(int,QProcess::ExitStatus)),
|
|
||||||
SLOT(onProcessFinished(int,QProcess::ExitStatus)));
|
|
||||||
connect(m_process, SIGNAL(error(QProcess::ProcessError)), SLOT(onProcessError()));
|
|
||||||
connect(m_process, SIGNAL(readyReadStandardOutput()), SLOT(onProcessReadyReadStdOut()));
|
|
||||||
connect(m_process, SIGNAL(readyReadStandardError()), SLOT(onProcessReadyReadStdErr()));
|
|
||||||
|
|
||||||
m_state = StartingState;
|
m_state = StartingState;
|
||||||
m_process->setUseCtrlCStub(true);
|
m_runner->start();
|
||||||
m_process->setCommand(m_runnerFilePath, runnerArgs);
|
|
||||||
m_process->setEnvironment(m_environment);
|
|
||||||
m_process->setWorkingDirectory(QFileInfo(m_executableFilePath).absolutePath());
|
|
||||||
m_process->start();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ namespace WinRt {
|
|||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
class WinRtRunConfiguration;
|
class WinRtRunConfiguration;
|
||||||
|
class WinRtRunnerHelper;
|
||||||
|
|
||||||
class WinRtRunControl : public ProjectExplorer::RunControl
|
class WinRtRunControl : public ProjectExplorer::RunControl
|
||||||
{
|
{
|
||||||
@@ -61,24 +62,17 @@ public:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onProcessStarted();
|
void onProcessStarted();
|
||||||
void onProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
void onProcessFinished();
|
||||||
void onProcessError();
|
void onProcessError();
|
||||||
void onProcessReadyReadStdOut();
|
|
||||||
void onProcessReadyReadStdErr();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum State { StartingState, StartedState, StoppedState };
|
enum State { StartingState, StartedState, StoppedState };
|
||||||
bool startWinRtRunner();
|
bool startWinRtRunner();
|
||||||
|
|
||||||
|
WinRtRunConfiguration *m_runConfiguration;
|
||||||
State m_state;
|
State m_state;
|
||||||
WinRtDevice::ConstPtr m_device;
|
|
||||||
QString m_runnerFilePath;
|
|
||||||
QString m_executableFilePath;
|
|
||||||
QString m_arguments;
|
|
||||||
bool m_uninstallAfterStop;
|
|
||||||
bool m_isWinPhone;
|
|
||||||
Utils::QtcProcess *m_process;
|
Utils::QtcProcess *m_process;
|
||||||
Utils::Environment m_environment;
|
WinRtRunnerHelper *m_runner;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -31,16 +31,24 @@
|
|||||||
#include "winrtrunconfiguration.h"
|
#include "winrtrunconfiguration.h"
|
||||||
#include "winrtruncontrol.h"
|
#include "winrtruncontrol.h"
|
||||||
#include "winrtconstants.h"
|
#include "winrtconstants.h"
|
||||||
|
#include "winrtdebugsupport.h"
|
||||||
|
|
||||||
#include <projectexplorer/target.h>
|
|
||||||
#include <projectexplorer/project.h>
|
|
||||||
#include <projectexplorer/kit.h>
|
#include <projectexplorer/kit.h>
|
||||||
#include <projectexplorer/kitinformation.h>
|
#include <projectexplorer/kitinformation.h>
|
||||||
|
#include <projectexplorer/project.h>
|
||||||
|
#include <projectexplorer/target.h>
|
||||||
|
#include <projectexplorer/toolchain.h>
|
||||||
|
|
||||||
|
#include <debugger/debuggerkitinformation.h>
|
||||||
|
#include <debugger/debuggerplugin.h>
|
||||||
#include <debugger/debuggerrunner.h>
|
#include <debugger/debuggerrunner.h>
|
||||||
|
#include <debugger/debuggerstartparameters.h>
|
||||||
|
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
|
#include <QLocalServer>
|
||||||
|
#include <QLocalSocket>
|
||||||
|
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
|
|
||||||
namespace WinRt {
|
namespace WinRt {
|
||||||
@@ -80,7 +88,6 @@ QString WinRtRunConfigurationFactory::displayNameForId(const Core::Id id) const
|
|||||||
|
|
||||||
bool WinRtRunConfigurationFactory::canCreate(Target *parent, const Core::Id id) const
|
bool WinRtRunConfigurationFactory::canCreate(Target *parent, const Core::Id id) const
|
||||||
{
|
{
|
||||||
Q_UNUSED(parent);
|
|
||||||
return id == winrtConfigurationIdC && isKitCompatible(parent->kit());
|
return id == winrtConfigurationIdC && isKitCompatible(parent->kit());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,7 +98,6 @@ RunConfiguration *WinRtRunConfigurationFactory::doCreate(Target *parent, const C
|
|||||||
|
|
||||||
bool WinRtRunConfigurationFactory::canRestore(Target *parent, const QVariantMap &map) const
|
bool WinRtRunConfigurationFactory::canRestore(Target *parent, const QVariantMap &map) const
|
||||||
{
|
{
|
||||||
Q_UNUSED(parent);
|
|
||||||
return ProjectExplorer::idFromMap(map) == winrtConfigurationIdC && isKitCompatible(parent->kit());
|
return ProjectExplorer::idFromMap(map) == winrtConfigurationIdC && isKitCompatible(parent->kit());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,9 +129,23 @@ WinRtRunControlFactory::WinRtRunControlFactory()
|
|||||||
bool WinRtRunControlFactory::canRun(ProjectExplorer::RunConfiguration *runConfiguration,
|
bool WinRtRunControlFactory::canRun(ProjectExplorer::RunConfiguration *runConfiguration,
|
||||||
ProjectExplorer::RunMode mode) const
|
ProjectExplorer::RunMode mode) const
|
||||||
{
|
{
|
||||||
if (mode != NormalRunMode)
|
if (!runConfiguration)
|
||||||
return false;
|
return false;
|
||||||
|
IDevice::ConstPtr device = DeviceKitInformation::device(runConfiguration->target()->kit());
|
||||||
|
if (!device)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case DebugRunMode:
|
||||||
|
case DebugRunModeWithBreakOnMain:
|
||||||
|
if (device->type() != Constants::WINRT_DEVICE_TYPE_LOCAL)
|
||||||
|
return false;
|
||||||
|
// fall through
|
||||||
|
case NormalRunMode:
|
||||||
return qobject_cast<WinRtRunConfiguration *>(runConfiguration);
|
return qobject_cast<WinRtRunConfiguration *>(runConfiguration);
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProjectExplorer::RunControl *WinRtRunControlFactory::create(
|
ProjectExplorer::RunControl *WinRtRunControlFactory::create(
|
||||||
@@ -137,6 +157,9 @@ ProjectExplorer::RunControl *WinRtRunControlFactory::create(
|
|||||||
switch (mode) {
|
switch (mode) {
|
||||||
case NormalRunMode:
|
case NormalRunMode:
|
||||||
return new WinRtRunControl(rc, mode);
|
return new WinRtRunControl(rc, mode);
|
||||||
|
case DebugRunMode:
|
||||||
|
case DebugRunModeWithBreakOnMain:
|
||||||
|
return WinRtDebugSupport::createDebugRunControl(rc, mode, errorMessage);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
240
src/plugins/winrt/winrtrunnerhelper.cpp
Normal file
240
src/plugins/winrt/winrtrunnerhelper.cpp
Normal file
@@ -0,0 +1,240 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** 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 Digia. For licensing terms and
|
||||||
|
** conditions see http://qt.digia.com/licensing. For further information
|
||||||
|
** use the contact form at http://qt.digia.com/contact-us.
|
||||||
|
**
|
||||||
|
** 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, Digia gives you certain additional
|
||||||
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include "winrtrunnerhelper.h"
|
||||||
|
|
||||||
|
#include "winrtconstants.h"
|
||||||
|
#include "winrtrunconfiguration.h"
|
||||||
|
|
||||||
|
#include <coreplugin/idocument.h>
|
||||||
|
#include <projectexplorer/buildtargetinfo.h>
|
||||||
|
#include <projectexplorer/devicesupport/idevice.h>
|
||||||
|
#include <projectexplorer/buildconfiguration.h>
|
||||||
|
#include <projectexplorer/kitinformation.h>
|
||||||
|
#include <projectexplorer/project.h>
|
||||||
|
#include <projectexplorer/runconfiguration.h>
|
||||||
|
#include <projectexplorer/target.h>
|
||||||
|
#include <qtsupport/baseqtversion.h>
|
||||||
|
#include <qtsupport/qtkitinformation.h>
|
||||||
|
#include <utils/qtcprocess.h>
|
||||||
|
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
using namespace WinRt;
|
||||||
|
using namespace WinRt::Internal;
|
||||||
|
|
||||||
|
WinRtRunnerHelper::WinRtRunnerHelper(WinRtRunConfiguration *runConfiguration, QString *errormessage)
|
||||||
|
: QObject(runConfiguration)
|
||||||
|
, m_messenger(0)
|
||||||
|
, m_runConfiguration(runConfiguration)
|
||||||
|
, m_process(0)
|
||||||
|
{
|
||||||
|
init(runConfiguration, errormessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
WinRtRunnerHelper::WinRtRunnerHelper(ProjectExplorer::RunControl *runControl)
|
||||||
|
: QObject(runControl)
|
||||||
|
, m_messenger(runControl)
|
||||||
|
, m_runConfiguration(0)
|
||||||
|
, m_process(0)
|
||||||
|
{
|
||||||
|
m_runConfiguration = qobject_cast<WinRtRunConfiguration *>(runControl->runConfiguration());
|
||||||
|
QString errorMessage;
|
||||||
|
if (!init(m_runConfiguration, &errorMessage))
|
||||||
|
runControl->appendMessage(errorMessage, Utils::ErrorMessageFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WinRtRunnerHelper::init(WinRtRunConfiguration *runConfiguration, QString *errorMessage)
|
||||||
|
{
|
||||||
|
ProjectExplorer::Target *target = runConfiguration->target();
|
||||||
|
m_device = ProjectExplorer::DeviceKitInformation::device(
|
||||||
|
target->kit()).dynamicCast<const WinRtDevice>();
|
||||||
|
|
||||||
|
const QtSupport::BaseQtVersion *qt = QtSupport::QtKitInformation::qtVersion(target->kit());
|
||||||
|
if (!qt) {
|
||||||
|
*errorMessage = tr("The current kit has no Qt version.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_isWinPhone = (qt->type() == QLatin1String(Constants::WINRT_WINPHONEQT));
|
||||||
|
m_runnerFilePath = qt->binPath().toString() + QStringLiteral("/winrtrunner.exe");
|
||||||
|
if (!QFile::exists(m_runnerFilePath)) {
|
||||||
|
*errorMessage = tr("Cannot find winrtrunner.exe in \"%1\".").arg(
|
||||||
|
QDir::toNativeSeparators(qt->binPath().toString()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Utils::FileName proFile = Utils::FileName::fromString(
|
||||||
|
target->project()->document()->filePath());
|
||||||
|
m_executableFilePath = target->applicationTargets().targetForProject(proFile).toString()
|
||||||
|
+ QStringLiteral(".exe"); // ### we should not need to append ".exe" here.
|
||||||
|
|
||||||
|
m_arguments = runConfiguration->arguments();
|
||||||
|
m_uninstallAfterStop = runConfiguration->uninstallAfterStop();
|
||||||
|
|
||||||
|
if (ProjectExplorer::BuildConfiguration *bc = target->activeBuildConfiguration())
|
||||||
|
m_environment = bc->environment();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WinRtRunnerHelper::debug(const QString &debuggerExecutable, const QString &debuggerArguments)
|
||||||
|
{
|
||||||
|
m_debuggerExecutable = debuggerExecutable;
|
||||||
|
m_debuggerArguments = debuggerArguments;
|
||||||
|
startWinRtRunner(Debug);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WinRtRunnerHelper::start()
|
||||||
|
{
|
||||||
|
startWinRtRunner(Start);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WinRtRunnerHelper::stop()
|
||||||
|
{
|
||||||
|
if (m_process)
|
||||||
|
m_process->interrupt();
|
||||||
|
else
|
||||||
|
startWinRtRunner(Stop);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WinRtRunnerHelper::waitForStarted(int msecs)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(m_process, return false);
|
||||||
|
return m_process->waitForStarted(msecs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WinRtRunnerHelper::setRunControl(ProjectExplorer::RunControl *runControl)
|
||||||
|
{
|
||||||
|
m_messenger = runControl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WinRtRunnerHelper::onProcessReadyReadStdOut()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(m_process, return);
|
||||||
|
if (m_messenger) {
|
||||||
|
m_messenger->appendMessage(QString::fromLocal8Bit(
|
||||||
|
m_process->readAllStandardOutput()), Utils::StdOutFormat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WinRtRunnerHelper::onProcessReadyReadStdErr()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(m_process, return);
|
||||||
|
if (m_messenger) {
|
||||||
|
m_messenger->appendMessage(QString::fromLocal8Bit(
|
||||||
|
m_process->readAllStandardError()), Utils::StdErrFormat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WinRtRunnerHelper::onProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(m_process, return);
|
||||||
|
m_process->disconnect();
|
||||||
|
m_process->deleteLater();
|
||||||
|
m_process = 0;
|
||||||
|
emit finished(exitCode, exitStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WinRtRunnerHelper::onProcessError(QProcess::ProcessError processError)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(m_process, return);
|
||||||
|
if (m_messenger) {
|
||||||
|
m_messenger->appendMessage(tr("Error while executing the WinRT Runner Tool: %1\n").arg(
|
||||||
|
m_process->errorString()),
|
||||||
|
Utils::ErrorMessageFormat);
|
||||||
|
}
|
||||||
|
m_process->disconnect();
|
||||||
|
m_process->deleteLater();
|
||||||
|
m_process = 0;
|
||||||
|
emit error(processError);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WinRtRunnerHelper::startWinRtRunner(const RunConf &conf)
|
||||||
|
{
|
||||||
|
using namespace Utils;
|
||||||
|
QString runnerArgs;
|
||||||
|
QtcProcess::addArg(&runnerArgs, QStringLiteral("--profile"));
|
||||||
|
QtcProcess::addArg(&runnerArgs, m_isWinPhone ? QStringLiteral("xap") : QStringLiteral("appx"));
|
||||||
|
if (m_device) {
|
||||||
|
QtcProcess::addArg(&runnerArgs, QStringLiteral("--device"));
|
||||||
|
QtcProcess::addArg(&runnerArgs, QString::number(m_device->deviceId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Utils::QtcProcess *process = 0;
|
||||||
|
bool connectProcess = false;
|
||||||
|
|
||||||
|
switch (conf) {
|
||||||
|
case Debug:
|
||||||
|
Utils::QtcProcess::addArg(&runnerArgs, QStringLiteral("--debug"));
|
||||||
|
Utils::QtcProcess::addArg(&runnerArgs, m_debuggerExecutable);
|
||||||
|
if (!m_debuggerArguments.isEmpty()) {
|
||||||
|
Utils::QtcProcess::addArg(&runnerArgs, QStringLiteral("--debugger-arguments"));
|
||||||
|
Utils::QtcProcess::addArg(&runnerArgs, m_debuggerArguments);
|
||||||
|
}
|
||||||
|
// fall through
|
||||||
|
case Start:
|
||||||
|
QtcProcess::addArgs(&runnerArgs, QStringLiteral("--start --stop --install --wait 0"));
|
||||||
|
connectProcess = true;
|
||||||
|
QTC_ASSERT(!m_process, m_process->deleteLater());
|
||||||
|
m_process = new QtcProcess(this);
|
||||||
|
process = m_process;
|
||||||
|
break;
|
||||||
|
case Stop:
|
||||||
|
Utils::QtcProcess::addArgs(&runnerArgs, QStringLiteral("--stop"));
|
||||||
|
process = new QtcProcess(this);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
QtcProcess::addArg(&runnerArgs, m_executableFilePath);
|
||||||
|
if (!m_arguments.isEmpty())
|
||||||
|
QtcProcess::addArgs(&runnerArgs, m_arguments);
|
||||||
|
|
||||||
|
if (m_messenger) {
|
||||||
|
m_messenger->appendMessage(QStringLiteral("winrtrunner ") + runnerArgs + QLatin1Char('\n'),
|
||||||
|
Utils::NormalMessageFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connectProcess) {
|
||||||
|
connect(process, SIGNAL(started()), SIGNAL(started()));
|
||||||
|
connect(process, SIGNAL(finished(int, QProcess::ExitStatus)),
|
||||||
|
SLOT(onProcessFinished(int, QProcess::ExitStatus)));
|
||||||
|
connect(process, SIGNAL(error(QProcess::ProcessError)),
|
||||||
|
SLOT(onProcessError(QProcess::ProcessError)));
|
||||||
|
connect(process, SIGNAL(readyReadStandardOutput()), SLOT(onProcessReadyReadStdOut()));
|
||||||
|
connect(process, SIGNAL(readyReadStandardError()), SLOT(onProcessReadyReadStdErr()));
|
||||||
|
}
|
||||||
|
|
||||||
|
process->setUseCtrlCStub(true);
|
||||||
|
process->setCommand(m_runnerFilePath, runnerArgs);
|
||||||
|
process->setEnvironment(m_environment);
|
||||||
|
process->setWorkingDirectory(QFileInfo(m_executableFilePath).absolutePath());
|
||||||
|
process->start();
|
||||||
|
}
|
||||||
99
src/plugins/winrt/winrtrunnerhelper.h
Normal file
99
src/plugins/winrt/winrtrunnerhelper.h
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** 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 Digia. For licensing terms and
|
||||||
|
** conditions see http://qt.digia.com/licensing. For further information
|
||||||
|
** use the contact form at http://qt.digia.com/contact-us.
|
||||||
|
**
|
||||||
|
** 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, Digia gives you certain additional
|
||||||
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef WINRTRUNNERHELPER_H
|
||||||
|
#define WINRTRUNNERHELPER_H
|
||||||
|
|
||||||
|
#include "winrtdevice.h"
|
||||||
|
|
||||||
|
#include <utils/environment.h>
|
||||||
|
#include <utils/outputformat.h>
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QProcess>
|
||||||
|
|
||||||
|
|
||||||
|
namespace Utils { class QtcProcess; }
|
||||||
|
namespace ProjectExplorer { class RunControl; }
|
||||||
|
|
||||||
|
namespace WinRt {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
class WinRtRunConfiguration;
|
||||||
|
|
||||||
|
class WinRtRunnerHelper : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
WinRtRunnerHelper(ProjectExplorer::RunControl *runControl);
|
||||||
|
WinRtRunnerHelper(WinRtRunConfiguration *runConfiguration, QString *errormessage);
|
||||||
|
|
||||||
|
void debug(const QString &debuggerExecutable, const QString &debuggerArguments = QString());
|
||||||
|
void start();
|
||||||
|
|
||||||
|
void stop();
|
||||||
|
|
||||||
|
bool waitForStarted(int msecs = 10000);
|
||||||
|
void setRunControl(ProjectExplorer::RunControl *runControl);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void started();
|
||||||
|
void finished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||||
|
void error(QProcess::ProcessError error);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onProcessReadyReadStdOut();
|
||||||
|
void onProcessReadyReadStdErr();
|
||||||
|
void onProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||||
|
void onProcessError(QProcess::ProcessError processError);
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum RunConf { Start, Stop, Debug };
|
||||||
|
void startWinRtRunner(const RunConf &conf);
|
||||||
|
bool init(WinRtRunConfiguration *runConfiguration, QString *errorMessage);
|
||||||
|
|
||||||
|
ProjectExplorer::RunControl *m_messenger;
|
||||||
|
WinRtRunConfiguration *m_runConfiguration;
|
||||||
|
WinRtDevice::ConstPtr m_device;
|
||||||
|
Utils::Environment m_environment;
|
||||||
|
QString m_runnerFilePath;
|
||||||
|
QString m_executableFilePath;
|
||||||
|
QString m_debuggerExecutable;
|
||||||
|
QString m_debuggerArguments;
|
||||||
|
QString m_arguments;
|
||||||
|
bool m_uninstallAfterStop;
|
||||||
|
bool m_isWinPhone;
|
||||||
|
Utils::QtcProcess *m_process;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace WinRt
|
||||||
|
} // namespace Internal
|
||||||
|
|
||||||
|
#endif // WINRTRUNNERHELPER_H
|
||||||
@@ -9,8 +9,9 @@ SUBDIRS = qtpromaker \
|
|||||||
buildoutputparser
|
buildoutputparser
|
||||||
|
|
||||||
win32 {
|
win32 {
|
||||||
SUBDIRS += qtcdebugger
|
SUBDIRS += qtcdebugger \
|
||||||
SUBDIRS += wininterrupt
|
wininterrupt \
|
||||||
|
winrtdebughelper
|
||||||
}
|
}
|
||||||
|
|
||||||
mac {
|
mac {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ Project {
|
|||||||
"sdktool/sdktool.qbs",
|
"sdktool/sdktool.qbs",
|
||||||
"valgrindfake/valgrindfake.qbs",
|
"valgrindfake/valgrindfake.qbs",
|
||||||
"3rdparty/iossim/iossim.qbs",
|
"3rdparty/iossim/iossim.qbs",
|
||||||
"iostool/iostool.qbs"
|
"iostool/iostool.qbs",
|
||||||
|
"winrtdebughelper/winrtdebughelper.qbs"
|
||||||
].concat(project.additionalTools)
|
].concat(project.additionalTools)
|
||||||
}
|
}
|
||||||
|
|||||||
78
src/tools/winrtdebughelper/winrtdebughelper.cpp
Normal file
78
src/tools/winrtdebughelper/winrtdebughelper.cpp
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** 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 Digia. For licensing terms and
|
||||||
|
** conditions see http://qt.digia.com/licensing. For further information
|
||||||
|
** use the contact form at http://qt.digia.com/contact-us.
|
||||||
|
**
|
||||||
|
** 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, Digia gives you certain additional
|
||||||
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int pid = -1;
|
||||||
|
const size_t maxPipeNameSize = 256;
|
||||||
|
wchar_t pipeName[maxPipeNameSize] = { 0 };
|
||||||
|
|
||||||
|
for (int i = 0; i < argc - 1; ++i) {
|
||||||
|
if (!strcmp(argv[i], "-t")) {
|
||||||
|
++i;
|
||||||
|
if (swprintf(pipeName, maxPipeNameSize, L"%hs", argv[i]) < 0)
|
||||||
|
return 0; // Pipe name too long
|
||||||
|
} else if (!strcmp(argv[i], "-p")) {
|
||||||
|
++i;
|
||||||
|
|
||||||
|
// check if -p is followed by a number
|
||||||
|
const char *pidString = argv[i];
|
||||||
|
char *end;
|
||||||
|
pid = strtoul(pidString, &end, 0);
|
||||||
|
if (*end != 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pid < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (*pipeName == 0)
|
||||||
|
swprintf(pipeName, maxPipeNameSize, L"\\\\.\\pipe\\QtCreatorWinRtDebugPIDPipe");
|
||||||
|
HANDLE pipe;
|
||||||
|
while (true) {
|
||||||
|
pipe = CreateFile(pipeName, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
if (pipe != INVALID_HANDLE_VALUE)
|
||||||
|
break;
|
||||||
|
if ((GetLastError() != ERROR_PIPE_BUSY) || (!WaitNamedPipe(pipeName, 10000)))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t msgBufferSize = 15;
|
||||||
|
char pidMessageBuffer[msgBufferSize];
|
||||||
|
int length = sprintf_s(pidMessageBuffer, msgBufferSize, "PID:%d", pid);
|
||||||
|
if (length >= 0)
|
||||||
|
WriteFile(pipe, pidMessageBuffer, length, NULL, NULL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
17
src/tools/winrtdebughelper/winrtdebughelper.pro
Normal file
17
src/tools/winrtdebughelper/winrtdebughelper.pro
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
CONFIG += warn_on console
|
||||||
|
CONFIG -= qt app_bundle
|
||||||
|
|
||||||
|
include(../../../qtcreator.pri)
|
||||||
|
|
||||||
|
TEMPLATE = app
|
||||||
|
DESTDIR = $$IDE_LIBEXEC_PATH
|
||||||
|
SOURCES = winrtdebughelper.cpp
|
||||||
|
|
||||||
|
build_all:!build_pass {
|
||||||
|
CONFIG -= build_all
|
||||||
|
CONFIG += release
|
||||||
|
}
|
||||||
|
|
||||||
|
TARGET = winrtdebughelper
|
||||||
|
target.path = $$IDE_LIBEXEC_PATH
|
||||||
|
INSTALLS += target
|
||||||
13
src/tools/winrtdebughelper/winrtdebughelper.qbs
Normal file
13
src/tools/winrtdebughelper/winrtdebughelper.qbs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import qbs 1.0
|
||||||
|
import QtcTool
|
||||||
|
|
||||||
|
QtcTool {
|
||||||
|
name: "winrtdebughelper"
|
||||||
|
condition: qbs.targetOS.contains("windows")
|
||||||
|
|
||||||
|
Depends { name: "Qt.network" }
|
||||||
|
|
||||||
|
files: [
|
||||||
|
"winrtdebughelper.cpp",
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user