diff options
-rw-r--r-- | src/plugins/ios/ios.pro | 6 | ||||
-rw-r--r-- | src/plugins/ios/ios.qbs | 6 | ||||
-rw-r--r-- | src/plugins/ios/iosanalyzesupport.cpp | 98 | ||||
-rw-r--r-- | src/plugins/ios/iosanalyzesupport.h | 59 | ||||
-rw-r--r-- | src/plugins/ios/iosdebugsupport.cpp | 230 | ||||
-rw-r--r-- | src/plugins/ios/iosdebugsupport.h | 63 | ||||
-rw-r--r-- | src/plugins/ios/iosruncontrol.cpp | 98 | ||||
-rw-r--r-- | src/plugins/ios/iosruncontrol.h | 57 | ||||
-rw-r--r-- | src/plugins/ios/iosrunfactories.cpp | 37 | ||||
-rw-r--r-- | src/plugins/ios/iosrunfactories.h | 3 | ||||
-rw-r--r-- | src/plugins/ios/iosrunner.cpp | 373 | ||||
-rw-r--r-- | src/plugins/ios/iosrunner.h | 91 |
12 files changed, 413 insertions, 708 deletions
diff --git a/src/plugins/ios/ios.pro b/src/plugins/ios/ios.pro index 3e5f5bd959..07396fbc9d 100644 --- a/src/plugins/ios/ios.pro +++ b/src/plugins/ios/ios.pro @@ -12,12 +12,10 @@ HEADERS += \ iosconfigurations.h \ iosmanager.h \ iosrunconfiguration.h \ - iosruncontrol.h \ iosrunfactories.h \ iossettingspage.h \ iossettingswidget.h \ iosrunner.h \ - iosdebugsupport.h \ iosdsymbuildstep.h \ iosqtversionfactory.h \ iosqtversion.h \ @@ -33,7 +31,6 @@ HEADERS += \ iosdeploystep.h \ iosdeploystepfactory.h \ iosdeploystepwidget.h \ - iosanalyzesupport.h \ simulatorcontrol.h \ iosbuildconfiguration.h \ iosbuildsettingswidget.h @@ -43,12 +40,10 @@ SOURCES += \ iosconfigurations.cpp \ iosmanager.cpp \ iosrunconfiguration.cpp \ - iosruncontrol.cpp \ iosrunfactories.cpp \ iossettingspage.cpp \ iossettingswidget.cpp \ iosrunner.cpp \ - iosdebugsupport.cpp \ iosdsymbuildstep.cpp \ iosqtversionfactory.cpp \ iosqtversion.cpp \ @@ -64,7 +59,6 @@ SOURCES += \ iosdeploystep.cpp \ iosdeploystepfactory.cpp \ iosdeploystepwidget.cpp \ - iosanalyzesupport.cpp \ simulatorcontrol.cpp \ iosbuildconfiguration.cpp \ iosbuildsettingswidget.cpp diff --git a/src/plugins/ios/ios.qbs b/src/plugins/ios/ios.qbs index 8f156b421c..0e67c9a857 100644 --- a/src/plugins/ios/ios.qbs +++ b/src/plugins/ios/ios.qbs @@ -15,8 +15,6 @@ QtcPlugin { files: [ "ios.qrc", - "iosanalyzesupport.cpp", - "iosanalyzesupport.h", "iosbuildconfiguration.cpp", "iosbuildconfiguration.h", "iosbuildsettingswidget.cpp", @@ -28,8 +26,6 @@ QtcPlugin { "iosconfigurations.cpp", "iosconfigurations.h", "iosconstants.h", - "iosdebugsupport.cpp", - "iosdebugsupport.h", "iosdeployconfiguration.cpp", "iosdeployconfiguration.h", "iosdeploystep.cpp", @@ -58,8 +54,6 @@ QtcPlugin { "iosqtversionfactory.h", "iosrunconfiguration.cpp", "iosrunconfiguration.h", - "iosruncontrol.cpp", - "iosruncontrol.h", "iosrunfactories.cpp", "iosrunfactories.h", "iosrunner.cpp", diff --git a/src/plugins/ios/iosanalyzesupport.cpp b/src/plugins/ios/iosanalyzesupport.cpp deleted file mode 100644 index 795da9d1aa..0000000000 --- a/src/plugins/ios/iosanalyzesupport.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "iosanalyzesupport.h" -#include "iosrunner.h" - -using namespace ProjectExplorer; - -namespace Ios { -namespace Internal { - -IosAnalyzeSupport::IosAnalyzeSupport(RunControl *runControl, bool cppDebug, bool qmlDebug) - : RunWorker(runControl), - m_runner(new IosRunner(this, runControl, cppDebug, qmlDebug ? QmlDebug::QmlProfilerServices : - QmlDebug::NoQmlDebugServices)) -{ - connect(runControl, &RunControl::starting, - m_runner, &IosRunner::start); - connect(runControl, &RunControl::finished, - m_runner, &IosRunner::stop); - connect(&m_outputParser, &QmlDebug::QmlOutputParser::waitingForConnectionOnPort, - this, &IosAnalyzeSupport::qmlServerReady); - - connect(m_runner, &IosRunner::gotServerPorts, - this, &IosAnalyzeSupport::handleServerPorts); - connect(m_runner, &IosRunner::gotInferiorPid, - this, &IosAnalyzeSupport::handleGotInferiorPid); - connect(m_runner, &IosRunner::finished, - this, &IosAnalyzeSupport::handleRemoteProcessFinished); - - connect(m_runner, &IosRunner::errorMsg, - this, &IosAnalyzeSupport::handleRemoteErrorOutput); - connect(m_runner, &IosRunner::appOutput, - this, &IosAnalyzeSupport::handleRemoteOutput); -} - -void IosAnalyzeSupport::qmlServerReady() -{ - runControl()->notifyRemoteSetupDone(m_qmlPort); -} - -void IosAnalyzeSupport::handleServerPorts(Utils::Port gdbServerPort, Utils::Port qmlPort) -{ - Q_UNUSED(gdbServerPort); - m_qmlPort = qmlPort; -} - -void IosAnalyzeSupport::handleGotInferiorPid(qint64 pid, Utils::Port qmlPort) -{ - Q_UNUSED(pid); - m_qmlPort = qmlPort; -} - -void IosAnalyzeSupport::handleRemoteProcessFinished(bool cleanEnd) -{ - if (!cleanEnd) - appendMessage(tr("Run ended with error."), Utils::ErrorMessageFormat); - else - appendMessage(tr("Run ended."), Utils::NormalMessageFormat); - runControl()->notifyRemoteFinished(); -} - -void IosAnalyzeSupport::handleRemoteOutput(const QString &output) -{ - appendMessage(output, Utils::StdOutFormat); - m_outputParser.processOutput(output); -} - -void IosAnalyzeSupport::handleRemoteErrorOutput(const QString &output) -{ - appendMessage(output, Utils::StdErrFormat); - m_outputParser.processOutput(output); -} - -} // namespace Internal -} // namespace Ios diff --git a/src/plugins/ios/iosanalyzesupport.h b/src/plugins/ios/iosanalyzesupport.h deleted file mode 100644 index 2b621034ea..0000000000 --- a/src/plugins/ios/iosanalyzesupport.h +++ /dev/null @@ -1,59 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#pragma once - -#include <qmldebug/qmloutputparser.h> - -#include <projectexplorer/runconfiguration.h> - -namespace Ios { -namespace Internal { - -class IosRunner; - -class IosAnalyzeSupport : public ProjectExplorer::RunWorker -{ - Q_OBJECT - -public: - IosAnalyzeSupport(ProjectExplorer::RunControl *runControl, bool cppDebug, bool qmlDebug); - -private: - void qmlServerReady(); - void handleServerPorts(Utils::Port gdbServerPort, Utils::Port qmlPort); - void handleGotInferiorPid(qint64 pid, Utils::Port qmlPort); - void handleRemoteProcessFinished(bool cleanEnd); - - void handleRemoteOutput(const QString &output); - void handleRemoteErrorOutput(const QString &output); - - IosRunner * const m_runner; - QmlDebug::QmlOutputParser m_outputParser; - Utils::Port m_qmlPort; -}; - -} // namespace Internal -} // namespace Ios diff --git a/src/plugins/ios/iosdebugsupport.cpp b/src/plugins/ios/iosdebugsupport.cpp deleted file mode 100644 index 55e87cccad..0000000000 --- a/src/plugins/ios/iosdebugsupport.cpp +++ /dev/null @@ -1,230 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "iosdebugsupport.h" - -#include "iosrunner.h" -#include "iosmanager.h" -#include "iosdevice.h" - -#include <debugger/debuggerplugin.h> -#include <debugger/debuggerkitinformation.h> -#include <debugger/debuggerruncontrol.h> -#include <debugger/debuggerstartparameters.h> -#include <debugger/debuggerrunconfigurationaspect.h> -#include <projectexplorer/toolchain.h> -#include <projectexplorer/target.h> -#include <projectexplorer/taskhub.h> -#include <qtsupport/qtkitinformation.h> -#include <utils/fileutils.h> -#include <utils/qtcprocess.h> - -#include <QDateTime> -#include <QDir> -#include <QTcpServer> -#include <QSettings> - -#include <stdio.h> -#include <fcntl.h> -#ifdef Q_OS_UNIX -#include <unistd.h> -#else -#include <io.h> -#endif - -using namespace Debugger; -using namespace ProjectExplorer; - -namespace Ios { -namespace Internal { - -RunControl *IosDebugSupport::createDebugRunControl(RunConfiguration *runConfig, - QString *errorMessage) -{ - Target *target = runConfig->target(); - if (!target) - return 0; - IDevice::ConstPtr device = DeviceKitInformation::device(target->kit()); - if (device.isNull()) - return 0; - - DebuggerStartParameters params; - if (device->type() == Core::Id(Ios::Constants::IOS_DEVICE_TYPE)) { - params.startMode = AttachToRemoteProcess; - params.platform = QLatin1String("remote-ios"); - IosDevice::ConstPtr iosDevice = device.dynamicCast<const IosDevice>(); - if (iosDevice.isNull()) - return 0; - QString osVersion = iosDevice->osVersion(); - Utils::FileName deviceSdk1 = Utils::FileName::fromString(QDir::homePath() - + QLatin1String("/Library/Developer/Xcode/iOS DeviceSupport/") - + osVersion + QLatin1String("/Symbols")); - QString deviceSdk; - if (deviceSdk1.toFileInfo().isDir()) { - deviceSdk = deviceSdk1.toString(); - } else { - Utils::FileName deviceSdk2 = IosConfigurations::developerPath() - .appendPath(QLatin1String("Platforms/iPhoneOS.platform/DeviceSupport/")) - .appendPath(osVersion).appendPath(QLatin1String("Symbols")); - if (deviceSdk2.toFileInfo().isDir()) { - deviceSdk = deviceSdk2.toString(); - } else { - TaskHub::addTask(Task::Warning, tr( - "Could not find device specific debug symbols at %1. " - "Debugging initialization will be slow until you open the Organizer window of " - "Xcode with the device connected to have the symbols generated.") - .arg(deviceSdk1.toUserOutput()), - ProjectExplorer::Constants::TASK_CATEGORY_DEPLOYMENT); - } - } - params.deviceSymbolsRoot = deviceSdk; - } else { - params.startMode = AttachExternal; - params.platform = QLatin1String("ios-simulator"); - } - - auto iosRunConfig = qobject_cast<IosRunConfiguration *>(runConfig); - params.displayName = iosRunConfig->applicationName(); - params.remoteSetupNeeded = true; - params.continueAfterAttach = true; - - auto aspect = runConfig->extraAspect<DebuggerRunConfigurationAspect>(); - bool cppDebug = aspect->useCppDebugger(); - bool qmlDebug = aspect->useQmlDebugger(); - if (cppDebug) { - params.inferior.executable = iosRunConfig->localExecutable().toString(); - params.remoteChannel = QLatin1String("connect://localhost:0"); - - Utils::FileName xcodeInfo = IosConfigurations::developerPath().parentDir() - .appendPath(QLatin1String("Info.plist")); - bool buggyLldb = false; - if (xcodeInfo.exists()) { - QSettings settings(xcodeInfo.toString(), QSettings::NativeFormat); - QStringList version = settings.value(QLatin1String("CFBundleShortVersionString")).toString() - .split(QLatin1Char('.')); - if (version.value(0).toInt() == 5 && version.value(1, QString::number(1)).toInt() == 0) - buggyLldb = true; - } - QString bundlePath = iosRunConfig->bundleDirectory().toString(); - bundlePath.chop(4); - Utils::FileName dsymPath = Utils::FileName::fromString( - bundlePath.append(QLatin1String(".dSYM"))); - if (!dsymPath.exists()) { - if (buggyLldb) - TaskHub::addTask(Task::Warning, - tr("Debugging with Xcode 5.0.x can be unreliable without a dSYM. " - "To create one, add a dsymutil deploystep."), - ProjectExplorer::Constants::TASK_CATEGORY_DEPLOYMENT); - } else if (dsymPath.toFileInfo().lastModified() - < QFileInfo(iosRunConfig->localExecutable().toUserOutput()).lastModified()) { - TaskHub::addTask(Task::Warning, - tr("The dSYM %1 seems to be outdated, it might confuse the debugger.") - .arg(dsymPath.toUserOutput()), - ProjectExplorer::Constants::TASK_CATEGORY_DEPLOYMENT); - } - } - - if (qmlDebug) { - QTcpServer server; - QTC_ASSERT(server.listen(QHostAddress::LocalHost) - || server.listen(QHostAddress::LocalHostIPv6), return 0); - params.qmlServer.host = server.serverAddress().toString(); - if (!cppDebug) - params.startMode = AttachToRemoteServer; - } - - Q_UNUSED(errorMessage); // FIXME - auto runControl = new RunControl(runConfig, ProjectExplorer::Constants::DEBUG_RUN_MODE); - (void) new IosDebugSupport(runControl, params, cppDebug, qmlDebug); - return runControl; -} - -IosDebugSupport::IosDebugSupport(RunControl *runControl, const DebuggerStartParameters &sp, bool cppDebug, bool qmlDebug) - : Debugger::DebuggerRunTool(runControl, sp), - m_runner(new IosRunner(this, runControl, cppDebug, - qmlDebug ? QmlDebug::QmlDebuggerServices : QmlDebug::NoQmlDebugServices)) -{ - connect(this, &Debugger::DebuggerRunTool::requestRemoteSetup, - m_runner, &IosRunner::start); - connect(runControl, &RunControl::finished, - m_runner, &IosRunner::stop); - - connect(m_runner, &IosRunner::gotServerPorts, - this, &IosDebugSupport::handleServerPorts); - connect(m_runner, &IosRunner::gotInferiorPid, - this, &IosDebugSupport::handleGotInferiorPid); - connect(m_runner, &IosRunner::finished, - this, &IosDebugSupport::handleRemoteProcessFinished); - - connect(m_runner, &IosRunner::errorMsg, - this, &IosDebugSupport::handleRemoteErrorOutput); - connect(m_runner, &IosRunner::appOutput, - this, &IosDebugSupport::handleRemoteOutput); -} - -void IosDebugSupport::handleServerPorts(Utils::Port gdbServerPort, Utils::Port qmlPort) -{ - RemoteSetupResult result; - result.gdbServerPort = gdbServerPort; - result.qmlServerPort = qmlPort; - result.success = gdbServerPort.isValid() - || (m_runner && !m_runner->cppDebug() && qmlPort.isValid()); - if (!result.success) - result.reason = tr("Could not get debug server file descriptor."); - notifyEngineRemoteSetupFinished(result); -} - -void IosDebugSupport::handleGotInferiorPid(qint64 pid, Utils::Port qmlPort) -{ - RemoteSetupResult result; - result.qmlServerPort = qmlPort; - result.inferiorPid = pid; - result.success = pid > 0; - if (!result.success) - result.reason = tr("Got an invalid process id."); - notifyEngineRemoteSetupFinished(result); -} - -void IosDebugSupport::handleRemoteProcessFinished(bool cleanEnd) -{ - if (!cleanEnd) - appendMessage(tr("Run ended with error."), Utils::DebugFormat); - else - appendMessage(tr("Run ended."), Utils::DebugFormat); - abortDebugger(); -} - -void IosDebugSupport::handleRemoteOutput(const QString &output) -{ - showMessage(output, AppOutput); -} - -void IosDebugSupport::handleRemoteErrorOutput(const QString &output) -{ - showMessage(output, AppError); -} - -} // namespace Internal -} // namespace Ios diff --git a/src/plugins/ios/iosdebugsupport.h b/src/plugins/ios/iosdebugsupport.h deleted file mode 100644 index 5e791fb7bc..0000000000 --- a/src/plugins/ios/iosdebugsupport.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#pragma once - -#include "iosrunconfiguration.h" - -#include <debugger/debuggerruncontrol.h> - -namespace Ios { -namespace Internal { - -class IosRunConfiguration; -class IosRunner; - -class IosDebugSupport : public Debugger::DebuggerRunTool -{ - Q_OBJECT - -public: - static ProjectExplorer::RunControl *createDebugRunControl(ProjectExplorer::RunConfiguration *runConfig, - QString *errorMessage); - - IosDebugSupport(ProjectExplorer::RunControl *runControl, - const Debugger::DebuggerStartParameters &sp, - bool cppDebug, bool qmlDebug); - -private: - void handleServerPorts(Utils::Port gdbServerPort, Utils::Port qmlPort); - void handleGotInferiorPid(qint64, Utils::Port qmlPort); - void handleRemoteProcessFinished(bool cleanEnd); - - void handleRemoteOutput(const QString &output); - void handleRemoteErrorOutput(const QString &output); - - IosRunner * const m_runner; - const QString m_dumperLib; -}; - -} // namespace Internal -} // namespace Ios diff --git a/src/plugins/ios/iosruncontrol.cpp b/src/plugins/ios/iosruncontrol.cpp deleted file mode 100644 index d181edee42..0000000000 --- a/src/plugins/ios/iosruncontrol.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "iosruncontrol.h" - -#include "iosrunconfiguration.h" -#include "iosrunner.h" - -#include <utils/utilsicons.h> - -#include <projectexplorer/projectexplorerconstants.h> - -using namespace ProjectExplorer; - -namespace Ios { -namespace Internal { - -IosRunControl::IosRunControl(IosRunConfiguration *rc) - : RunControl(rc, ProjectExplorer::Constants::NORMAL_RUN_MODE) - , m_runner(new IosRunner(this, this, false, QmlDebug::NoQmlDebugServices)) -{ - setIcon(Utils::Icons::RUN_SMALL_TOOLBAR); -} - -IosRunControl::~IosRunControl() -{ - stop(); -} - -void IosRunControl::start() -{ - reportApplicationStart(); - disconnect(m_runner, 0, this, 0); - - connect(m_runner, &IosRunner::errorMsg, - this, &IosRunControl::handleRemoteErrorOutput); - connect(m_runner, &IosRunner::appOutput, - this, &IosRunControl::handleRemoteOutput); - connect(m_runner, &IosRunner::finished, - this, &IosRunControl::handleRemoteProcessFinished); - appendMessage(tr("Starting remote process.") + QLatin1Char('\n'), Utils::NormalMessageFormat); - m_runner->start(); -} - -void IosRunControl::stop() -{ - m_runner->stop(); -} - -void IosRunControl::handleRemoteProcessFinished(bool cleanEnd) -{ - if (!cleanEnd) - appendMessage(tr("Run ended with error."), Utils::ErrorMessageFormat); - else - appendMessage(tr("Run ended."), Utils::NormalMessageFormat); - disconnect(m_runner, 0, this, 0); - reportApplicationStop(); -} - -void IosRunControl::handleRemoteOutput(const QString &output) -{ - appendMessage(output, Utils::StdOutFormatSameLine); -} - -void IosRunControl::handleRemoteErrorOutput(const QString &output) -{ - appendMessage(output, Utils::StdErrFormat); -} - -QString IosRunControl::displayName() const -{ - return m_runner->displayName(); -} - -} // namespace Internal -} // namespace Ios diff --git a/src/plugins/ios/iosruncontrol.h b/src/plugins/ios/iosruncontrol.h deleted file mode 100644 index 400087fe9c..0000000000 --- a/src/plugins/ios/iosruncontrol.h +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#pragma once - -#include <projectexplorer/runconfiguration.h> - -namespace Ios { -namespace Internal { - -class IosRunConfiguration; -class IosRunner; - -class IosRunControl : public ProjectExplorer::RunControl -{ - Q_OBJECT - -public: - explicit IosRunControl(IosRunConfiguration *runConfig); - ~IosRunControl() override; - - void start() override; - void stop() override; - QString displayName() const override; - -private: - void handleRemoteProcessFinished(bool cleanEnd); - void handleRemoteOutput(const QString &output); - void handleRemoteErrorOutput(const QString &output); - - IosRunner *const m_runner; -}; - -} // namespace Internal -} // namespace Ios diff --git a/src/plugins/ios/iosrunfactories.cpp b/src/plugins/ios/iosrunfactories.cpp index 5571258d63..f559d9754f 100644 --- a/src/plugins/ios/iosrunfactories.cpp +++ b/src/plugins/ios/iosrunfactories.cpp @@ -26,11 +26,9 @@ #include "iosrunfactories.h" #include "iosconstants.h" -#include "iosdebugsupport.h" #include "iosrunconfiguration.h" -#include "iosruncontrol.h" +#include "iosrunner.h" #include "iosmanager.h" -#include "iosanalyzesupport.h" #include <debugger/analyzer/analyzermanager.h> #include <debugger/analyzer/analyzerstartparameters.h> @@ -45,7 +43,6 @@ #include <qmakeprojectmanager/qmakenodes.h> #include <qmakeprojectmanager/qmakeproject.h> -#include <coreplugin/id.h> using namespace Debugger; using namespace ProjectExplorer; @@ -168,12 +165,13 @@ bool IosRunControlFactory::canRun(RunConfiguration *runConfiguration, RunControl *IosRunControlFactory::create(RunConfiguration *runConfig, Core::Id mode, QString *errorMessage) { + Q_UNUSED(errorMessage); Q_ASSERT(canRun(runConfig, mode)); IosRunConfiguration *rc = qobject_cast<IosRunConfiguration *>(runConfig); Q_ASSERT(rc); Target *target = runConfig->target(); QTC_ASSERT(target, return 0); - RunControl *res = 0; + Core::Id devId = DeviceKitInformation::deviceId(rc->target()->kit()); // The device can only run an application at a time, if an app is running stop it. if (m_activeRunControls.contains(devId)) { @@ -181,28 +179,19 @@ RunControl *IosRunControlFactory::create(RunConfiguration *runConfig, activeRunControl->initiateStop(); m_activeRunControls.remove(devId); } - if (mode == ProjectExplorer::Constants::NORMAL_RUN_MODE) - res = new Ios::Internal::IosRunControl(rc); - else if (mode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) { - auto runControl = new RunControl(runConfig, mode); + auto runControl = new RunControl(runConfig, mode); + if (mode == ProjectExplorer::Constants::NORMAL_RUN_MODE) { + (void) new Ios::Internal::IosRunSupport(runControl); + } else if (mode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) { runControl->createWorker(mode); - auto iosRunConfig = qobject_cast<IosRunConfiguration *>(runConfig); - StandardRunnable runnable; - runnable.executable = iosRunConfig->localExecutable().toUserOutput(); - runnable.commandLineArguments = iosRunConfig->commandLineArguments(); - AnalyzerConnection connection; - connection.analyzerHost = QLatin1String("localhost"); - runControl->setRunnable(runnable); - runControl->setConnection(connection); - runControl->setDisplayName(iosRunConfig->applicationName()); - (void) new IosAnalyzeSupport(runControl, false, true); - return runControl; + (void) new IosAnalyzeSupport(runControl); + } else { + (void) new IosDebugSupport(runControl); } - else - res = IosDebugSupport::createDebugRunControl(rc, errorMessage); + if (devId.isValid()) - m_activeRunControls[devId] = res; - return res; + m_activeRunControls[devId] = runControl; + return runControl; } } // namespace Internal diff --git a/src/plugins/ios/iosrunfactories.h b/src/plugins/ios/iosrunfactories.h index 325deb8d87..8e9b072639 100644 --- a/src/plugins/ios/iosrunfactories.h +++ b/src/plugins/ios/iosrunfactories.h @@ -78,8 +78,7 @@ public: bool canRun(ProjectExplorer::RunConfiguration *runConfiguration, Core::Id mode) const override; ProjectExplorer::RunControl *create(ProjectExplorer::RunConfiguration *runConfiguration, - Core::Id mode, - QString *errorMessage) override; + Core::Id mode, QString *) override; private: mutable QMap<Core::Id, QPointer<ProjectExplorer::RunControl> > m_activeRunControls; }; diff --git a/src/plugins/ios/iosrunner.cpp b/src/plugins/ios/iosrunner.cpp index 5bf8057320..f2635a9600 100644 --- a/src/plugins/ios/iosrunner.cpp +++ b/src/plugins/ios/iosrunner.cpp @@ -32,29 +32,51 @@ #include "iossimulator.h" #include "iosconstants.h" +#include <debugger/analyzer/analyzerstartparameters.h> +#include <debugger/debuggerplugin.h> +#include <debugger/debuggerkitinformation.h> +#include <debugger/debuggerruncontrol.h> + #include <projectexplorer/kitinformation.h> +#include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/target.h> #include <projectexplorer/taskhub.h> -#include <projectexplorer/projectexplorerconstants.h> -#include <debugger/debuggerrunconfigurationaspect.h> +#include <projectexplorer/toolchain.h> + #include <qmldebug/qmldebugcommandlinearguments.h> +#include <qtsupport/qtkitinformation.h> + +#include <utils/fileutils.h> +#include <utils/qtcprocess.h> +#include <utils/utilsicons.h> + +#include <QDateTime> #include <QDir> -#include <QTime> #include <QMessageBox> #include <QRegExp> +#include <QSettings> +#include <QTcpServer> +#include <QTime> +#include <stdio.h> +#include <fcntl.h> +#ifdef Q_OS_UNIX +#include <unistd.h> +#else +#include <io.h> +#endif #include <signal.h> +using namespace Debugger; using namespace ProjectExplorer; +using namespace Utils; namespace Ios { namespace Internal { -IosRunner::IosRunner(QObject *parent, RunControl *runControl, bool cppDebug, - QmlDebug::QmlDebugServicesPreset qmlDebugServices) - : QObject(parent), - m_cppDebug(cppDebug), m_qmlDebugServices(qmlDebugServices) +IosRunner::IosRunner(RunControl *runControl) + : RunWorker(runControl) { auto runConfig = qobject_cast<IosRunConfiguration *>(runControl->runConfiguration()); m_bundleDir = runConfig->bundleDirectory().toString(); @@ -68,6 +90,16 @@ IosRunner::~IosRunner() stop(); } +void IosRunner::setCppDebugging(bool cppDebug) +{ + m_cppDebug = cppDebug; +} + +void IosRunner::setQmlDebugging(QmlDebug::QmlDebugServicesPreset qmlDebugServices) +{ + m_qmlDebugServices = qmlDebugServices; +} + QString IosRunner::bundlePath() { return m_bundleDir; @@ -76,8 +108,8 @@ QString IosRunner::bundlePath() QStringList IosRunner::extraArgs() { QStringList res = m_arguments; - if (m_qmlPort.isValid()) - res << QmlDebug::qmlDebugTcpArguments(m_qmlDebugServices, m_qmlPort); + if (m_qmlServerPort.isValid()) + res << QmlDebug::qmlDebugTcpArguments(m_qmlDebugServices, m_qmlServerPort); return res; } @@ -108,35 +140,34 @@ QmlDebug::QmlDebugServicesPreset IosRunner::qmlDebugServices() const void IosRunner::start() { - if (m_toolHandler) { + if (m_toolHandler && isAppRunning()) m_toolHandler->stop(); - emit finished(m_cleanExit); - } + m_cleanExit = false; - m_qmlPort = Utils::Port(); + m_qmlServerPort = Port(); if (!QFileInfo::exists(m_bundleDir)) { TaskHub::addTask(Task::Warning, tr("Could not find %1.").arg(m_bundleDir), ProjectExplorer::Constants::TASK_CATEGORY_DEPLOYMENT); - emit finished(m_cleanExit); + reportFailure(); return; } if (m_device->type() == Ios::Constants::IOS_DEVICE_TYPE) { IosDevice::ConstPtr iosDevice = m_device.dynamicCast<const IosDevice>(); if (m_device.isNull()) { - emit finished(m_cleanExit); + reportFailure(); return; } if (m_qmlDebugServices != QmlDebug::NoQmlDebugServices) - m_qmlPort = iosDevice->nextPort(); + m_qmlServerPort = iosDevice->nextPort(); } else { IosSimulator::ConstPtr sim = m_device.dynamicCast<const IosSimulator>(); if (sim.isNull()) { - emit finished(m_cleanExit); + reportFailure(); return; } if (m_qmlDebugServices != QmlDebug::NoQmlDebugServices) - m_qmlPort = sim->nextPort(); + m_qmlServerPort = sim->nextPort(); } m_toolHandler = new IosToolHandler(m_deviceType, this); @@ -159,7 +190,7 @@ void IosRunner::start() void IosRunner::stop() { - if (m_toolHandler && m_toolHandler->isRunning()) + if (isAppRunning()) m_toolHandler->stop(); } @@ -167,46 +198,73 @@ void IosRunner::handleDidStartApp(IosToolHandler *handler, const QString &bundle const QString &deviceId, IosToolHandler::OpStatus status) { Q_UNUSED(bundlePath); Q_UNUSED(deviceId); - if (m_toolHandler == handler) - emit didStartApp(status); + if (m_toolHandler == handler && runType() == IosToolHandler::NormalRun) { + // For normal run type the notify reportStarted here for debug type wait for + // server ports or PID for device and simulator respectivelly. + if (status == IosToolHandler::Success) + reportStarted(); + else + reportFailure(); + } } void IosRunner::handleGotServerPorts(IosToolHandler *handler, const QString &bundlePath, - const QString &deviceId, Utils::Port gdbPort, - Utils::Port qmlPort) + const QString &deviceId, Port gdbPort, + Port qmlPort) { + // Called when debugging on Device. Q_UNUSED(bundlePath); Q_UNUSED(deviceId); - m_qmlPort = qmlPort; - if (m_toolHandler == handler) - emit gotServerPorts(gdbPort, qmlPort); + if (m_toolHandler == handler && runType() == IosToolHandler::DebugRun) { + m_gdbServerPort = gdbPort; + m_qmlServerPort = qmlPort; + bool portsValid = m_gdbServerPort.isValid() && m_qmlServerPort.isValid(); + bool qmlDebugging = m_qmlDebugServices != QmlDebug::NoQmlDebugServices; + if ( (qmlDebugging && m_cppDebug && portsValid) // Mixed mode debuggin & valid ports + || (qmlDebugging && !m_cppDebug && m_qmlServerPort.isValid()) // Qml debugging only + || (m_cppDebug && !qmlDebugging && m_gdbServerPort.isValid())) { // C++ debugging only + reportStarted(); + } else { + reportFailure(tr("Could not get debug server file descriptor.")); + } + } } void IosRunner::handleGotInferiorPid(IosToolHandler *handler, const QString &bundlePath, const QString &deviceId, qint64 pid) { + // Called when debugging on Simulator. Q_UNUSED(bundlePath); Q_UNUSED(deviceId); m_pid = pid; - if (m_toolHandler == handler) - emit gotInferiorPid(pid, m_qmlPort); + if (m_pid <= 0) + reportFailure(tr("Could not get inferior PID.")); + + if (m_toolHandler == handler && runType() == IosToolHandler::DebugRun) { + bool qmlDebugging = m_qmlDebugServices != QmlDebug::NoQmlDebugServices; + if ((qmlDebugging && m_qmlServerPort.isValid()) || (m_cppDebug && !qmlDebugging)) + reportStarted(); + else + reportFailure(tr("Could not get debug server file descriptor.")); + } } void IosRunner::handleAppOutput(IosToolHandler *handler, const QString &output) { Q_UNUSED(handler); - QRegExp qmlPortRe(QLatin1String("QML Debugger: Waiting for connection on port ([0-9]+)...")); + QRegExp qmlPortRe("QML Debugger: Waiting for connection on port ([0-9]+)..."); int index = qmlPortRe.indexIn(output); QString res(output); - if (index != -1 && m_qmlPort.isValid()) - res.replace(qmlPortRe.cap(1), QString::number(m_qmlPort.number())); - emit appOutput(res); + if (index != -1 && m_qmlServerPort.isValid()) + res.replace(qmlPortRe.cap(1), QString::number(m_qmlServerPort.number())); + appendMessage(output, StdOutFormat); + appOutput(res); } void IosRunner::handleErrorMsg(IosToolHandler *handler, const QString &msg) { Q_UNUSED(handler); QString res(msg); - QLatin1String lockedErr = QLatin1String("Unexpected reply: ELocked (454c6f636b6564) vs OK (4f4b)"); - if (msg.contains(QLatin1String("AMDeviceStartService returned -402653150"))) { + QString lockedErr ="Unexpected reply: ELocked (454c6f636b6564) vs OK (4f4b)"; + if (msg.contains("AMDeviceStartService returned -402653150")) { TaskHub::addTask(Task::Warning, tr("Run failed. The settings in the Organizer window of Xcode might be incorrect."), ProjectExplorer::Constants::TASK_CATEGORY_DEPLOYMENT); @@ -216,11 +274,13 @@ void IosRunner::handleErrorMsg(IosToolHandler *handler, const QString &msg) ProjectExplorer::Constants::TASK_CATEGORY_DEPLOYMENT); res.replace(lockedErr, message); } - QRegExp qmlPortRe(QLatin1String("QML Debugger: Waiting for connection on port ([0-9]+)...")); + QRegExp qmlPortRe("QML Debugger: Waiting for connection on port ([0-9]+)..."); int index = qmlPortRe.indexIn(msg); - if (index != -1 && m_qmlPort.isValid()) - res.replace(qmlPortRe.cap(1), QString::number(m_qmlPort.number())); - emit errorMsg(res); + if (index != -1 && m_qmlServerPort.isValid()) + res.replace(qmlPortRe.cap(1), QString::number(m_qmlServerPort.number())); + + appendMessage(res, StdErrFormat); + errorMsg(res); } void IosRunner::handleToolExited(IosToolHandler *handler, int code) @@ -232,16 +292,243 @@ void IosRunner::handleToolExited(IosToolHandler *handler, int code) void IosRunner::handleFinished(IosToolHandler *handler) { if (m_toolHandler == handler) { - emit finished(m_cleanExit); - m_toolHandler = 0; + if (m_cleanExit) + appendMessage(tr("Run ended."), NormalMessageFormat); + else + appendMessage(tr("Run ended with error."), ErrorMessageFormat); + m_toolHandler = nullptr; } handler->deleteLater(); + reportStopped(); +} + +qint64 IosRunner::pid() const +{ + return m_pid; +} + +bool IosRunner::isAppRunning() const +{ + return m_toolHandler && m_toolHandler->isRunning(); +} + +Utils::Port IosRunner::gdbServerPort() const +{ + return m_gdbServerPort; +} + +Utils::Port IosRunner::qmlServerPort() const +{ + return m_qmlServerPort; +} + +// +// IosRunner +// + +IosRunSupport::IosRunSupport(RunControl *runControl) + : IosRunner(runControl) +{ + runControl->setIcon(Icons::RUN_SMALL_TOOLBAR); + QString displayName = QString("Run on %1").arg(device().isNull() ? QString() : device()->displayName()); + runControl->setDisplayName(displayName); +} + +IosRunSupport::~IosRunSupport() +{ + stop(); +} + +void IosRunSupport::start() +{ + appendMessage(tr("Starting remote process."), NormalMessageFormat); + IosRunner::start(); +} + +void IosRunSupport::stop() +{ + IosRunner::stop(); +} + +// +// IosAnalyzeSupport +// + +IosAnalyzeSupport::IosAnalyzeSupport(RunControl *runControl) + : IosRunner(runControl) +{ + m_runner = new IosRunner(runControl); + addDependency(m_runner); + + setDisplayName("IosAnalyzeSupport"); + setQmlDebugging(QmlDebug::QmlProfilerServices); + + auto iosRunConfig = qobject_cast<IosRunConfiguration *>(runControl->runConfiguration()); + StandardRunnable runnable; + runnable.executable = iosRunConfig->localExecutable().toUserOutput(); + runnable.commandLineArguments = iosRunConfig->commandLineArguments(); + Debugger::AnalyzerConnection connection; + connection.analyzerHost = "localhost"; + runControl->setRunnable(runnable); + runControl->setConnection(connection); + runControl->setDisplayName(iosRunConfig->applicationName()); + + connect(&m_outputParser, &QmlDebug::QmlOutputParser::waitingForConnectionOnPort, + this, &IosAnalyzeSupport::qmlServerReady); +} + +void IosAnalyzeSupport::start() +{ + // Use m_runner->qmlServerPort() // FIXME +} + +void IosAnalyzeSupport::qmlServerReady() +{ +// runControl()->notifyRemoteSetupDone(m_qmlServerPort); +} + +void IosAnalyzeSupport::appOutput(const QString &output) +{ + m_outputParser.processOutput(output); +} + +void IosAnalyzeSupport::errorMsg(const QString &output) +{ + m_outputParser.processOutput(output); +} + +// +// IosDebugSupport +// + +IosDebugSupport::IosDebugSupport(RunControl *runControl) + : Debugger::DebuggerRunTool(runControl) +{ + m_runner = new IosRunner(runControl); + m_runner->setCppDebugging(isCppDebugging()); + m_runner->setQmlDebugging(isQmlDebugging() ? QmlDebug::QmlDebuggerServices : QmlDebug::NoQmlDebugServices); + + addDependency(m_runner); +} + +void IosDebugSupport::start() +{ + RunConfiguration *runConfig = runControl()->runConfiguration(); + + DebuggerStartParameters params; + if (device()->type() == Ios::Constants::IOS_DEVICE_TYPE) { + IosDevice::ConstPtr dev = device().dynamicCast<const IosDevice>(); + params.startMode = AttachToRemoteProcess; + params.platform = "remote-ios"; + QString osVersion = dev->osVersion(); + FileName deviceSdk1 = FileName::fromString(QDir::homePath() + + "/Library/Developer/Xcode/iOS DeviceSupport/" + + osVersion + "/Symbols"); + QString deviceSdk; + if (deviceSdk1.toFileInfo().isDir()) { + deviceSdk = deviceSdk1.toString(); + } else { + FileName deviceSdk2 = IosConfigurations::developerPath() + .appendPath("Platforms/iPhoneOS.platform/DeviceSupport/") + .appendPath(osVersion).appendPath("Symbols"); + if (deviceSdk2.toFileInfo().isDir()) { + deviceSdk = deviceSdk2.toString(); + } else { + TaskHub::addTask(Task::Warning, tr( + "Could not find device specific debug symbols at %1. " + "Debugging initialization will be slow until you open the Organizer window of " + "Xcode with the device connected to have the symbols generated.") + .arg(deviceSdk1.toUserOutput()), + ProjectExplorer::Constants::TASK_CATEGORY_DEPLOYMENT); + } + } + params.deviceSymbolsRoot = deviceSdk; + } else { + params.startMode = AttachExternal; + params.platform = "ios-simulator"; + } + + auto iosRunConfig = qobject_cast<IosRunConfiguration *>(runConfig); + params.displayName = iosRunConfig->applicationName(); + params.remoteSetupNeeded = true; + params.continueAfterAttach = true; + + Utils::Port gdbServerPort = m_runner->gdbServerPort(); + Utils::Port qmlServerPort = m_runner->qmlServerPort(); + params.attachPID = ProcessHandle(m_runner->pid()); + + const bool cppDebug = isCppDebugging(); + const bool qmlDebug = isQmlDebugging(); + if (cppDebug) { + params.inferior.executable = iosRunConfig->localExecutable().toString(); + if (gdbServerPort.isValid()) + params.remoteChannel = "connect://localhost:" + gdbServerPort.toString(); + else + params.remoteChannel = "connect://localhost:0"; + + FileName xcodeInfo = IosConfigurations::developerPath().parentDir().appendPath("Info.plist"); + bool buggyLldb = false; + if (xcodeInfo.exists()) { + QSettings settings(xcodeInfo.toString(), QSettings::NativeFormat); + QStringList version = settings.value(QLatin1String("CFBundleShortVersionString")).toString() + .split('.'); + if (version.value(0).toInt() == 5 && version.value(1, QString::number(1)).toInt() == 0) + buggyLldb = true; + } + QString bundlePath = iosRunConfig->bundleDirectory().toString(); + bundlePath.chop(4); + FileName dsymPath = FileName::fromString(bundlePath.append(".dSYM")); + if (!dsymPath.exists()) { + if (buggyLldb) + TaskHub::addTask(Task::Warning, + tr("Debugging with Xcode 5.0.x can be unreliable without a dSYM. " + "To create one, add a dsymutil deploystep."), + ProjectExplorer::Constants::TASK_CATEGORY_DEPLOYMENT); + } else if (dsymPath.toFileInfo().lastModified() + < QFileInfo(iosRunConfig->localExecutable().toUserOutput()).lastModified()) { + TaskHub::addTask(Task::Warning, + tr("The dSYM %1 seems to be outdated, it might confuse the debugger.") + .arg(dsymPath.toUserOutput()), + ProjectExplorer::Constants::TASK_CATEGORY_DEPLOYMENT); + } + } + + if (qmlDebug) { + QTcpServer server; + QTC_ASSERT(server.listen(QHostAddress::LocalHost) + || server.listen(QHostAddress::LocalHostIPv6), return); + params.qmlServer.host = server.serverAddress().toString(); + if (!cppDebug) + params.startMode = AttachToRemoteServer; + } + + if (qmlServerPort.isValid()) { + params.qmlServer.port = qmlServerPort; + params.inferior.commandLineArguments.replace("%qml_port%", qmlServerPort.toString()); + } + + setStartParameters(params); + + if (!m_runner->isAppRunning()) { + reportFailure(tr("Application not running.")); + return; + } + + RemoteSetupResult result; + if (m_runner->pid() > 0) + result.inferiorPid = m_runner->pid(); + else + result.gdbServerPort = gdbServerPort; + result.qmlServerPort = qmlServerPort; + result.success = true; // Port validation already checked. + notifyEngineRemoteSetupFinished(result); + + DebuggerRunTool::start(); } -QString IosRunner::displayName() const +void IosDebugSupport::onFinished() { - return QString::fromLatin1("Run on %1").arg(m_device.isNull() ? QString() - : m_device->displayName()); + abortDebugger(); } } // namespace Internal diff --git a/src/plugins/ios/iosrunner.h b/src/plugins/ios/iosrunner.h index 315d9a5a27..c380edf72f 100644 --- a/src/plugins/ios/iosrunner.h +++ b/src/plugins/ios/iosrunner.h @@ -30,31 +30,27 @@ #include "iossimulator.h" #include <debugger/debuggerconstants.h> +#include <debugger/debuggerruncontrol.h> #include <projectexplorer/devicesupport/idevice.h> #include <projectexplorer/runconfiguration.h> #include <qmldebug/qmldebugcommandlinearguments.h> - -#include <QTimer> -#include <QThread> -#include <QProcess> -#include <QMutex> +#include <qmldebug/qmloutputparser.h> namespace Ios { namespace Internal { -class IosRunner : public QObject +class IosRunner : public ProjectExplorer::RunWorker { Q_OBJECT public: - IosRunner(QObject *parent, ProjectExplorer::RunControl *runControl, - bool cppDebug, - QmlDebug::QmlDebugServicesPreset qmlDebugServices); + IosRunner(ProjectExplorer::RunControl *runControl); ~IosRunner(); - QString displayName() const; + void setCppDebugging(bool cppDebug); + void setQmlDebugging(QmlDebug::QmlDebugServicesPreset qmlDebugServices); QString bundlePath(); QStringList extraArgs(); @@ -63,16 +59,16 @@ public: bool cppDebug() const; QmlDebug::QmlDebugServicesPreset qmlDebugServices() const; - void start(); - void stop(); + void start() override; + void stop() override; + + virtual void appOutput(const QString &/*output*/) {} + virtual void errorMsg(const QString &/*msg*/) {} -signals: - void didStartApp(Ios::IosToolHandler::OpStatus status); - void gotServerPorts(Utils::Port gdbPort, Utils::Port qmlPort); - void gotInferiorPid(qint64 pid, Utils::Port qmlPort); - void appOutput(const QString &output); - void errorMsg(const QString &msg); - void finished(bool cleanExit); + Utils::Port qmlServerPort() const; + Utils::Port gdbServerPort() const; + qint64 pid() const; + bool isAppRunning() const; private: void handleDidStartApp(Ios::IosToolHandler *handler, const QString &bundlePath, @@ -91,13 +87,64 @@ private: QStringList m_arguments; ProjectExplorer::IDevice::ConstPtr m_device; IosDeviceType m_deviceType; - bool m_cppDebug; - QmlDebug::QmlDebugServicesPreset m_qmlDebugServices; + bool m_cppDebug = false; + QmlDebug::QmlDebugServicesPreset m_qmlDebugServices = QmlDebug::NoQmlDebugServices; bool m_cleanExit = false; - Utils::Port m_qmlPort; + Utils::Port m_qmlServerPort; + Utils::Port m_gdbServerPort; qint64 m_pid = 0; }; + +class IosRunSupport : public IosRunner +{ + Q_OBJECT + +public: + explicit IosRunSupport(ProjectExplorer::RunControl *runControl); + ~IosRunSupport() override; + + void didStartApp(IosToolHandler::OpStatus status); +private: + void start() override; + void stop() override; +}; + + +class IosAnalyzeSupport : public IosRunner +{ + Q_OBJECT + +public: + IosAnalyzeSupport(ProjectExplorer::RunControl *runControl); + +private: + void start() override; + + void qmlServerReady(); + void appOutput(const QString &output) override; + void errorMsg(const QString &output) override; + + QmlDebug::QmlOutputParser m_outputParser; + IosRunner *m_runner; +}; + + +class IosDebugSupport : public Debugger::DebuggerRunTool +{ + Q_OBJECT + +public: + IosDebugSupport(ProjectExplorer::RunControl *runControl); + +private: + void start() override; + void onFinished() override; + + const QString m_dumperLib; + IosRunner *m_runner; +}; + } // namespace Internal } // namespace Ios |