diff --git a/src/plugins/ios/Ios.pluginspec.in b/src/plugins/ios/Ios.pluginspec.in
new file mode 100644
index 00000000000..dc4c0656d21
--- /dev/null
+++ b/src/plugins/ios/Ios.pluginspec.in
@@ -0,0 +1,17 @@
+
+ Digia Plc
+ (C) 2013 Digia Plc
+
+Commercial Usage
+
+Licensees holding valid Qt Commercial licenses may use this plugin in accordance with the Qt Commercial License Agreement provided with the Software or, alternatively, in accordance with the terms contained in a written agreement between you and Digia.
+
+GNU Lesser General Public License Usage
+
+Alternatively, this plugin may be used under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. 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.
+
+ Support for deployment to and execution on iOS Devices
+ Device Support
+ http://www.qt-project.org
+ $$dependencyList
+
diff --git a/src/plugins/ios/images/QtIos.png b/src/plugins/ios/images/QtIos.png
new file mode 100755
index 00000000000..b68467437a7
Binary files /dev/null and b/src/plugins/ios/images/QtIos.png differ
diff --git a/src/plugins/ios/ios.pro b/src/plugins/ios/ios.pro
new file mode 100644
index 00000000000..476df08e52b
--- /dev/null
+++ b/src/plugins/ios/ios.pro
@@ -0,0 +1,69 @@
+TEMPLATE = lib
+TARGET = Ios
+
+include(../../qtcreatorplugin.pri)
+
+QT += xml network
+
+HEADERS += \
+ iosconstants.h \
+ iosconfigurations.h \
+ iosmanager.h \
+ iosrunconfiguration.h \
+ iosruncontrol.h \
+ iosrunfactories.h \
+ iossettingspage.h \
+ iossettingswidget.h \
+ iosrunner.h \
+ iosdebugsupport.h \
+ iosqtversionfactory.h \
+ iosqtversion.h \
+ iosplugin.h \
+ iosdevicefactory.h \
+ iosdevice.h \
+ iossimulator.h \
+ iossimulatorfactory.h \
+ iosprobe.h \
+ iosbuildstep.h \
+ iostoolhandler.h \
+ iosdeployconfiguration.h \
+ iosdeploystep.h \
+ iosdeploystepfactory.h \
+ iosdeploystepwidget.h
+
+
+SOURCES += \
+ iosconfigurations.cpp \
+ iosmanager.cpp \
+ iosrunconfiguration.cpp \
+ iosruncontrol.cpp \
+ iosrunfactories.cpp \
+ iossettingspage.cpp \
+ iossettingswidget.cpp \
+ iosrunner.cpp \
+ iosdebugsupport.cpp \
+ iosqtversionfactory.cpp \
+ iosqtversion.cpp \
+ iosplugin.cpp \
+ iosdevicefactory.cpp \
+ iosdevice.cpp \
+ iossimulator.cpp \
+ iossimulatorfactory.cpp \
+ iosprobe.cpp \
+ iosbuildstep.cpp \
+ iostoolhandler.cpp \
+ iosdeployconfiguration.cpp \
+ iosdeploystep.cpp \
+ iosdeploystepfactory.cpp \
+ iosdeploystepwidget.cpp
+
+FORMS += \
+ iossettingswidget.ui \
+ iosbuildstep.ui \
+ iosrunconfiguration.ui \
+ iosdeploystepwidget.ui
+
+DEFINES += IOS_LIBRARY
+
+RESOURCES += ios.qrc
+
diff --git a/src/plugins/ios/ios.qbs b/src/plugins/ios/ios.qbs
new file mode 100644
index 00000000000..5c1ad996c27
--- /dev/null
+++ b/src/plugins/ios/ios.qbs
@@ -0,0 +1,73 @@
+import qbs.base 1.0
+
+import "../QtcPlugin.qbs" as QtcPlugin
+
+QtcPlugin {
+ name: "Ios"
+ condition: qbs.targetOS.contains("osx")
+
+ Depends { name: "Core" }
+ Depends { name: "ProjectExplorer" }
+ Depends { name: "Qt4ProjectManager" }
+ Depends { name: "Debugger" }
+ Depends { name: "QtSupport" }
+ Depends { name: "Qt"; submodules: ["widgets", "xml", "network"] }
+
+ cpp.includePaths: base.concat("../../shared")
+ cpp.frameworks: base.concat(["CoreFoundation", "IOKit"])
+
+ files: [
+ "ios.qrc",
+ "iosbuildstep.cpp",
+ "iosbuildstep.h",
+ "iosbuildstep.ui",
+ "iosconfigurations.cpp",
+ "iosconfigurations.h",
+ "iosconstants.h",
+ "iosdebugsupport.cpp",
+ "iosdebugsupport.h",
+ "iosdeployconfiguration.cpp",
+ "iosdeployconfiguration.h",
+ "iosdeploystep.cpp",
+ "iosdeploystep.h",
+ "iosdeploystepfactory.cpp",
+ "iosdeploystepfactory.h",
+ "iosdeploystepwidget.cpp",
+ "iosdeploystepwidget.h",
+ "iosdeploystepwidget.ui",
+ "iosdevice.cpp",
+ "iosdevice.h",
+ "iosdevicefactory.cpp",
+ "iosdevicefactory.h",
+ "iosmanager.cpp",
+ "iosmanager.h",
+ "iosplugin.cpp",
+ "iosplugin.h",
+ "iosprobe.cpp",
+ "iosprobe.h",
+ "iosqtversion.cpp",
+ "iosqtversion.h",
+ "iosqtversionfactory.cpp",
+ "iosqtversionfactory.h",
+ "iosrunconfiguration.cpp",
+ "iosrunconfiguration.h",
+ "iosrunconfiguration.ui",
+ "iosruncontrol.cpp",
+ "iosruncontrol.h",
+ "iosrunfactories.cpp",
+ "iosrunfactories.h",
+ "iosrunner.cpp",
+ "iosrunner.h",
+ "iossettingspage.cpp",
+ "iossettingspage.h",
+ "iossettingswidget.cpp",
+ "iossettingswidget.h",
+ "iossettingswidget.ui",
+ "iossimulator.cpp",
+ "iossimulator.h",
+ "iossimulatorfactory.cpp",
+ "iossimulatorfactory.h",
+ "iostoolhandler.cpp",
+ "iostoolhandler.h"
+ ]
+}
diff --git a/src/plugins/ios/ios.qrc b/src/plugins/ios/ios.qrc
new file mode 100644
index 00000000000..81314b84cd7
--- /dev/null
+++ b/src/plugins/ios/ios.qrc
@@ -0,0 +1,5 @@
+
+
+ images/QtIos.png
+
+
diff --git a/src/plugins/ios/ios_dependencies.pri b/src/plugins/ios/ios_dependencies.pri
new file mode 100644
index 00000000000..020498834b4
--- /dev/null
+++ b/src/plugins/ios/ios_dependencies.pri
@@ -0,0 +1,8 @@
+QTC_PLUGIN_NAME = Ios
+QTC_LIB_DEPENDS += \
+ utils
+QTC_PLUGIN_DEPENDS += \
+ coreplugin \
+ debugger \
+ projectexplorer \
+ qt4projectmanager
diff --git a/src/plugins/ios/iosbuildstep.cpp b/src/plugins/ios/iosbuildstep.cpp
new file mode 100644
index 00000000000..df63f0ef8cc
--- /dev/null
+++ b/src/plugins/ios/iosbuildstep.cpp
@@ -0,0 +1,433 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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 "iosbuildstep.h"
+#include "iosconstants.h"
+#include "ui_iosbuildstep.h"
+#include "iosmanager.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+using namespace Core;
+using namespace ProjectExplorer;
+using namespace Qt4ProjectManager;
+
+namespace Ios {
+namespace Internal {
+
+const char IOS_BUILD_STEP_ID[] = "Ios.IosBuildStep";
+const char IOS_BUILD_STEP_DISPLAY_NAME[] = QT_TRANSLATE_NOOP("Ios::Internal::IosBuildStep",
+ "xcodebuild");
+
+const char BUILD_USE_DEFAULT_ARGS_KEY[] = "Ios.IosBuildStep.XcodeArgumentsUseDefault";
+const char BUILD_ARGUMENTS_KEY[] = "Ios.IosBuildStep.XcodeArguments";
+const char CLEAN_KEY[] = "Ios.IosBuildStep.Clean";
+
+IosBuildStep::IosBuildStep(BuildStepList *parent) :
+ AbstractProcessStep(parent, Id(IOS_BUILD_STEP_ID)),
+ m_useDefaultArguments(true),
+ m_clean(false)
+{
+ ctor();
+}
+
+IosBuildStep::IosBuildStep(BuildStepList *parent, const Id id) :
+ AbstractProcessStep(parent, id),
+ m_useDefaultArguments(true),
+ m_clean(false)
+{
+ ctor();
+}
+
+IosBuildStep::IosBuildStep(BuildStepList *parent, IosBuildStep *bs) :
+ AbstractProcessStep(parent, bs),
+ m_baseBuildArguments(bs->m_baseBuildArguments),
+ m_useDefaultArguments(bs->m_useDefaultArguments),
+ m_clean(bs->m_clean)
+{
+ ctor();
+}
+
+void IosBuildStep::ctor()
+{
+ setDefaultDisplayName(QCoreApplication::translate("GenericProjectManager::Internal::IosBuildStep",
+ IOS_BUILD_STEP_DISPLAY_NAME));
+}
+
+IosBuildStep::~IosBuildStep()
+{
+}
+
+bool IosBuildStep::init()
+{
+ BuildConfiguration *bc = buildConfiguration();
+ if (!bc)
+ bc = target()->activeBuildConfiguration();
+
+ m_tasks.clear();
+ ToolChain *tc = ToolChainKitInformation::toolChain(target()->kit());
+ if (!tc) {
+ Task t = Task(Task::Error, tr("Qt Creator needs a compiler set up to build. Configure a compiler in the kit preferences."),
+ Utils::FileName(), -1,
+ Core::Id(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM));
+ m_tasks.append(t);
+ emit addTask(t);
+ return false;
+ }
+ ProcessParameters *pp = processParameters();
+ pp->setMacroExpander(bc->macroExpander());
+ pp->setWorkingDirectory(bc->buildDirectory().toString());
+ Utils::Environment env = bc->environment();
+ // Force output to english for the parsers. Do this here and not in the toolchain's
+ // addToEnvironment() to not screw up the users run environment.
+ env.set(QLatin1String("LC_ALL"), QLatin1String("C"));
+ pp->setEnvironment(env);
+ pp->setCommand(buildCommand());
+ pp->setArguments(Utils::QtcProcess::joinArgs(allArguments()));
+ pp->resolveAll();
+
+ // If we are cleaning, then build can fail with an error code, but that doesn't mean
+ // we should stop the clean queue
+ // That is mostly so that rebuild works on an already clean project
+ setIgnoreReturnValue(m_clean);
+
+ setOutputParser(new GnuMakeParser());
+ IOutputParser *parser = target()->kit()->createOutputParser();
+ if (parser)
+ appendOutputParser(parser);
+ outputParser()->setWorkingDirectory(pp->effectiveWorkingDirectory());
+
+ return AbstractProcessStep::init();
+}
+
+void IosBuildStep::setClean(bool clean)
+{
+ m_clean = clean;
+}
+
+bool IosBuildStep::isClean() const
+{
+ return m_clean;
+}
+
+QVariantMap IosBuildStep::toMap() const
+{
+ QVariantMap map(AbstractProcessStep::toMap());
+
+ map.insert(QLatin1String(BUILD_ARGUMENTS_KEY), m_baseBuildArguments);
+ map.insert(QLatin1String(BUILD_USE_DEFAULT_ARGS_KEY), m_useDefaultArguments);
+ map.insert(QLatin1String(CLEAN_KEY), m_clean);
+ return map;
+}
+
+bool IosBuildStep::fromMap(const QVariantMap &map)
+{
+ QVariant bArgs = map.value(QLatin1String(BUILD_ARGUMENTS_KEY));
+ m_baseBuildArguments = bArgs.toStringList();
+ m_useDefaultArguments = map.value(QLatin1String(BUILD_USE_DEFAULT_ARGS_KEY)).toBool();
+ m_clean = map.value(QLatin1String(CLEAN_KEY)).toBool();
+
+ return BuildStep::fromMap(map);
+}
+
+QStringList IosBuildStep::allArguments() const
+{
+ return baseArguments() + m_extraArguments;
+}
+
+QStringList IosBuildStep::defaultArguments() const
+{
+ QStringList res;
+ Kit *kit = target()->kit();
+ ToolChain *tc = ToolChainKitInformation::toolChain(kit);
+ switch (target()->activeBuildConfiguration()->buildType()) {
+ case BuildConfiguration::Debug :
+ res << QLatin1String("-configuration") << QLatin1String("Debug");
+ break;
+ case BuildConfiguration::Release :
+ res << QLatin1String("-configuration") << QLatin1String("Release");
+ break;
+ case BuildConfiguration::Unknown :
+ break;
+ default:
+ qDebug() << "IosBuildStep had an unknown buildType "
+ << target()->activeBuildConfiguration()->buildType();
+ }
+ if (tc->type() == QLatin1String("gcc") || tc->type() == QLatin1String("clang")) {
+ GccToolChain *gtc = static_cast(tc);
+ res << gtc->platformCodeGenFlags();
+ }
+ if (!SysRootKitInformation::sysRoot(kit).isEmpty())
+ res << QLatin1String("-sdk") << SysRootKitInformation::sysRoot(kit).toString();
+ res << QLatin1String("SYMROOT=") + IosManager::resDirForTarget(target());
+ return res;
+}
+
+QString IosBuildStep::buildCommand() const
+{
+ return QLatin1String("xcodebuild"); // add path?
+}
+
+void IosBuildStep::run(QFutureInterface &fi)
+{
+ bool canContinue = true;
+ foreach (const Task &t, m_tasks) {
+ addTask(t);
+ canContinue = false;
+ }
+ if (!canContinue) {
+ emit addOutput(tr("Configuration is faulty. Check the Issues output pane for details."),
+ BuildStep::MessageOutput);
+ fi.reportResult(false);
+ emit finished();
+ return;
+ }
+
+ AbstractProcessStep::run(fi);
+}
+
+BuildStepConfigWidget *IosBuildStep::createConfigWidget()
+{
+ return new IosBuildStepConfigWidget(this);
+}
+
+bool IosBuildStep::immutable() const
+{
+ return false;
+}
+
+void IosBuildStep::setBaseArguments(const QStringList &args)
+{
+ m_baseBuildArguments = args;
+ m_useDefaultArguments = (args == defaultArguments());
+}
+
+void IosBuildStep::setExtraArguments(const QStringList &extraArgs)
+{
+ m_extraArguments = extraArgs;
+}
+
+QStringList IosBuildStep::baseArguments() const
+{
+ if (m_useDefaultArguments)
+ return defaultArguments();
+ return m_baseBuildArguments;
+}
+
+//
+// IosBuildStepConfigWidget
+//
+
+IosBuildStepConfigWidget::IosBuildStepConfigWidget(IosBuildStep *buildStep)
+ : m_buildStep(buildStep)
+{
+ m_ui = new Ui::IosBuildStep;
+ m_ui->setupUi(this);
+
+ Project *pro = m_buildStep->target()->project();
+
+ m_ui->buildArgumentsTextEdit->setPlainText(Utils::QtcProcess::joinArgs(
+ m_buildStep->baseArguments()));
+ m_ui->extraArgumentsLineEdit->setText(Utils::QtcProcess::joinArgs(
+ m_buildStep->m_extraArguments));
+ m_ui->resetDefaultsButton->setEnabled(!m_buildStep->m_useDefaultArguments);
+ updateDetails();
+
+ connect(m_ui->buildArgumentsTextEdit, SIGNAL(textChanged()),
+ this, SLOT(buildArgumentsChanged()));
+ connect(m_ui->resetDefaultsButton, SIGNAL(clicked()),
+ this, SLOT(resetDefaultArguments()));
+ connect(m_ui->extraArgumentsLineEdit, SIGNAL(editingFinished()),
+ this, SLOT(extraArgumentsChanged()));
+
+ connect(ProjectExplorerPlugin::instance(), SIGNAL(settingsChanged()),
+ this, SLOT(updateDetails()));
+ connect(m_buildStep->target(), SIGNAL(kitChanged()),
+ this, SLOT(updateDetails()));
+ connect(pro, SIGNAL(environmentChanged()),
+ this, SLOT(updateDetails()));
+}
+
+IosBuildStepConfigWidget::~IosBuildStepConfigWidget()
+{
+ delete m_ui;
+}
+
+QString IosBuildStepConfigWidget::displayName() const
+{
+ return tr("iOS build", "iOS BuildStep display name.");
+}
+
+void IosBuildStepConfigWidget::updateDetails()
+{
+ BuildConfiguration *bc = m_buildStep->buildConfiguration();
+ if (!bc)
+ bc = m_buildStep->target()->activeBuildConfiguration();
+
+ ProcessParameters param;
+ param.setMacroExpander(bc->macroExpander());
+ param.setWorkingDirectory(bc->buildDirectory().toString());
+ param.setEnvironment(bc->environment());
+ param.setCommand(m_buildStep->buildCommand());
+ param.setArguments(Utils::QtcProcess::joinArgs(m_buildStep->allArguments()));
+ m_summaryText = param.summary(displayName());
+ emit updateSummary();
+}
+
+QString IosBuildStepConfigWidget::summaryText() const
+{
+ return m_summaryText;
+}
+
+void IosBuildStepConfigWidget::buildArgumentsChanged()
+{
+ m_buildStep->setBaseArguments(Utils::QtcProcess::splitArgs(
+ m_ui->buildArgumentsTextEdit->toPlainText()));
+ m_ui->resetDefaultsButton->setEnabled(!m_buildStep->m_useDefaultArguments);
+ updateDetails();
+}
+
+void IosBuildStepConfigWidget::resetDefaultArguments()
+{
+ m_buildStep->setBaseArguments(m_buildStep->defaultArguments());
+ m_ui->buildArgumentsTextEdit->setPlainText(Utils::QtcProcess::joinArgs(
+ m_buildStep->baseArguments()));
+ m_ui->resetDefaultsButton->setEnabled(!m_buildStep->m_useDefaultArguments);
+}
+
+void IosBuildStepConfigWidget::extraArgumentsChanged()
+{
+ m_buildStep->setExtraArguments(Utils::QtcProcess::splitArgs(
+ m_ui->extraArgumentsLineEdit->text()));
+}
+//
+// IosBuildStepFactory
+//
+
+IosBuildStepFactory::IosBuildStepFactory(QObject *parent) :
+ IBuildStepFactory(parent)
+{
+}
+
+bool IosBuildStepFactory::canCreate(BuildStepList *parent, const Id) const
+{
+ if (parent->id() != ProjectExplorer::Constants::BUILDSTEPS_CLEAN
+ && parent->id() != ProjectExplorer::Constants::BUILDSTEPS_BUILD)
+ return false;
+ Kit *kit = parent->target()->kit();
+ Core::Id deviceType = DeviceTypeKitInformation::deviceTypeId(kit);
+ return (deviceType == Constants::IOS_DEVICE_TYPE
+ || deviceType == Constants::IOS_SIMULATOR_TYPE);
+}
+
+BuildStep *IosBuildStepFactory::create(BuildStepList *parent, const Id id)
+{
+ if (!canCreate(parent, id))
+ return 0;
+ IosBuildStep *step = new IosBuildStep(parent);
+ if (parent->id() == ProjectExplorer::Constants::BUILDSTEPS_CLEAN) {
+ step->setClean(true);
+ step->setExtraArguments(QStringList(QLatin1String("clean")));
+ } else if (parent->id() == ProjectExplorer::Constants::BUILDSTEPS_BUILD) {
+ // nomal setup
+ }
+ return step;
+}
+
+bool IosBuildStepFactory::canClone(BuildStepList *parent, BuildStep *source) const
+{
+ return canCreate(parent, source->id());
+}
+
+BuildStep *IosBuildStepFactory::clone(BuildStepList *parent, BuildStep *source)
+{
+ if (!canClone(parent, source))
+ return 0;
+ IosBuildStep *old(qobject_cast(source));
+ Q_ASSERT(old);
+ return new IosBuildStep(parent, old);
+}
+
+bool IosBuildStepFactory::canRestore(BuildStepList *parent, const QVariantMap &map) const
+{
+ return canCreate(parent, idFromMap(map));
+}
+
+BuildStep *IosBuildStepFactory::restore(BuildStepList *parent, const QVariantMap &map)
+{
+ if (!canRestore(parent, map))
+ return 0;
+ IosBuildStep *bs(new IosBuildStep(parent));
+ if (bs->fromMap(map))
+ return bs;
+ delete bs;
+ return 0;
+}
+
+QList IosBuildStepFactory::availableCreationIds(BuildStepList *parent) const
+{
+ Kit *kit = parent->target()->kit();
+ Core::Id deviceType = DeviceTypeKitInformation::deviceTypeId(kit);
+ if (deviceType == Constants::IOS_DEVICE_TYPE
+ || deviceType == Constants::IOS_SIMULATOR_TYPE)
+ return QList() << Id(IOS_BUILD_STEP_ID);
+ return QList();
+}
+
+QString IosBuildStepFactory::displayNameForId(const Id id) const
+{
+ if (id == IOS_BUILD_STEP_ID)
+ return QCoreApplication::translate("GenericProjectManager::Internal::IosBuildStep",
+ IOS_BUILD_STEP_DISPLAY_NAME);
+ return QString();
+}
+
+} // namespace Internal
+} // namespace Ios
diff --git a/src/plugins/ios/iosbuildstep.h b/src/plugins/ios/iosbuildstep.h
new file mode 100644
index 00000000000..43d99ce8a4b
--- /dev/null
+++ b/src/plugins/ios/iosbuildstep.h
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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 IOSBUILDSTEP_H
+#define IOSBUILDSTEP_H
+
+#include
+
+QT_BEGIN_NAMESPACE
+class QListWidgetItem;
+QT_END_NAMESPACE
+
+namespace Ios {
+namespace Internal {
+
+class IosBuildStepConfigWidget;
+class IosBuildStepFactory;
+namespace Ui { class IosBuildStep; }
+
+class IosBuildStep : public ProjectExplorer::AbstractProcessStep
+{
+ Q_OBJECT
+
+ friend class IosBuildStepConfigWidget;
+ friend class IosBuildStepFactory;
+
+public:
+ IosBuildStep(ProjectExplorer::BuildStepList *parent);
+ ~IosBuildStep();
+
+ bool init();
+ void run(QFutureInterface &fi);
+
+ ProjectExplorer::BuildStepConfigWidget *createConfigWidget();
+ bool immutable() const;
+ void setBaseArguments(const QStringList &args);
+ void setExtraArguments(const QStringList &extraArgs);
+ QStringList baseArguments() const;
+ QStringList allArguments() const;
+ QStringList defaultArguments() const;
+ QString buildCommand() const;
+
+ void setClean(bool clean);
+ bool isClean() const;
+
+ QVariantMap toMap() const;
+protected:
+ IosBuildStep(ProjectExplorer::BuildStepList *parent, IosBuildStep *bs);
+ IosBuildStep(ProjectExplorer::BuildStepList *parent, const Core::Id id);
+ bool fromMap(const QVariantMap &map);
+
+private:
+ void ctor();
+
+ QStringList m_baseBuildArguments;
+ QStringList m_extraArguments;
+ QString m_buildCommand;
+ bool m_useDefaultArguments;
+ bool m_clean;
+ QList m_tasks;
+};
+
+class IosBuildStepConfigWidget : public ProjectExplorer::BuildStepConfigWidget
+{
+ Q_OBJECT
+
+public:
+ IosBuildStepConfigWidget(IosBuildStep *buildStep);
+ ~IosBuildStepConfigWidget();
+ QString displayName() const;
+ QString summaryText() const;
+
+private slots:
+ void buildArgumentsChanged();
+ void resetDefaultArguments();
+ void extraArgumentsChanged();
+ void updateDetails();
+
+private:
+ Ui::IosBuildStep *m_ui;
+ IosBuildStep *m_buildStep;
+ QString m_summaryText;
+};
+
+class IosBuildStepFactory : public ProjectExplorer::IBuildStepFactory
+{
+ Q_OBJECT
+
+public:
+ explicit IosBuildStepFactory(QObject *parent = 0);
+
+ bool canCreate(ProjectExplorer::BuildStepList *parent, const Core::Id id) const;
+ ProjectExplorer::BuildStep *create(ProjectExplorer::BuildStepList *parent, const Core::Id id);
+ bool canClone(ProjectExplorer::BuildStepList *parent,
+ ProjectExplorer::BuildStep *source) const;
+ ProjectExplorer::BuildStep *clone(ProjectExplorer::BuildStepList *parent,
+ ProjectExplorer::BuildStep *source);
+ bool canRestore(ProjectExplorer::BuildStepList *parent, const QVariantMap &map) const;
+ ProjectExplorer::BuildStep *restore(ProjectExplorer::BuildStepList *parent,
+ const QVariantMap &map);
+
+ QList availableCreationIds(ProjectExplorer::BuildStepList *bc) const;
+ QString displayNameForId(const Core::Id id) const;
+};
+
+} // namespace Internal
+} // namespace Ios
+
+#endif // IOSBUILDSTEP_H
diff --git a/src/plugins/ios/iosbuildstep.ui b/src/plugins/ios/iosbuildstep.ui
new file mode 100644
index 00000000000..70f15991018
--- /dev/null
+++ b/src/plugins/ios/iosbuildstep.ui
@@ -0,0 +1,65 @@
+
+
+ Ios::Internal::IosBuildStep
+
+
+
+ 0
+ 0
+ 756
+ 183
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 0
+
+
+
+ -
+
+
+ Base arguments:
+
+
+
+ -
+
+
+ -
+
+
+ Qt::RightToLeft
+
+
+ Reset defaults
+
+
+
+ -
+
+
+ Extra arguments:
+
+
+
+ -
+
+
+
+ buildArgumentsTextEdit
+ resetDefaultsButton
+ extraArgumentsLabel
+ extraArgumentsLineEdit
+ buildArgumentsLabel
+
+
+
+
diff --git a/src/plugins/ios/iosconfigurations.cpp b/src/plugins/ios/iosconfigurations.cpp
new file mode 100644
index 00000000000..19f0a4d8a84
--- /dev/null
+++ b/src/plugins/ios/iosconfigurations.cpp
@@ -0,0 +1,448 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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 "iosconfigurations.h"
+#include "iosconstants.h"
+#include "iosdevice.h"
+#include "iossimulator.h"
+#include "iosprobe.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+
+using namespace ProjectExplorer;
+using namespace Utils;
+
+static const bool debugProbe = true;
+
+namespace Ios {
+namespace Internal {
+
+namespace {
+ const QLatin1String SettingsGroup("IosConfigurations");
+ const QLatin1String developerPathKey("DeveloperPath");
+ const QLatin1String ignoreAllDevicesKey("IgnoreAllDevices");
+
+}
+
+IosConfig::IosConfig(const QSettings &settings)
+{
+ developerPath = FileName::fromString(settings.value(developerPathKey).toString());
+ ignoreAllDevices = settings.value(ignoreAllDevicesKey, false).toBool();
+}
+
+IosConfig::IosConfig() : ignoreAllDevices(false)
+{ }
+
+void IosConfig::save(QSettings &settings) const
+{
+ settings.setValue(developerPathKey, developerPath.toString());
+ settings.setValue(ignoreAllDevicesKey, ignoreAllDevices);
+}
+
+void IosConfigurations::setConfig(const IosConfig &devConfigs)
+{
+ m_config = devConfigs;
+ save();
+ updateAutomaticKitList();
+ emit updated();
+}
+
+FileName IosConfigurations::iosToolPath() const
+{
+ FileName res = FileName::fromString(QCoreApplication::applicationDirPath()
+ + QLatin1String("/iosTool"));
+ return res;
+}
+
+
+bool equalKits(Kit *a, Kit *b)
+{
+ return ToolChainKitInformation::toolChain(a) == ToolChainKitInformation::toolChain(b)
+ && QtSupport::QtKitInformation::qtVersion(a) == QtSupport::QtKitInformation::qtVersion(b);
+}
+
+void IosConfigurations::updateAutomaticKitList()
+{
+ QMap platforms = IosProbe::detectPlatforms(m_config.developerPath.toString());
+ QMap platformToolchainMap;
+ // check existing toolchains (and remove old ones)
+ foreach (ProjectExplorer::ToolChain *tc, ProjectExplorer::ToolChainManager::toolChains()) {
+ if (!tc->isAutoDetected()) // use also user toolchains?
+ continue;
+ if (tc->type() != QLatin1String("clang") && tc->type() != QLatin1String("gcc"))
+ continue;
+ ProjectExplorer::GccToolChain *toolchain = static_cast(tc);
+ QMapIterator iter(platforms);
+ bool found = false;
+ while (iter.hasNext()) {
+ iter.next();
+ const Platform &p = iter.value();
+ if (p.compilerPath == toolchain->compilerCommand()
+ && p.backendFlags == toolchain->platformCodeGenFlags()) {
+ platformToolchainMap[p.name] = toolchain;
+ found = true;
+ }
+ }
+ iter.toFront();
+ while (iter.hasNext()) {
+ iter.next();
+ const Platform &p = iter.value();
+ if (p.platformKind)
+ continue;
+ if (p.compilerPath == toolchain->compilerCommand()
+ && p.backendFlags == toolchain->platformCodeGenFlags()) {
+ platformToolchainMap[p.name] = toolchain;
+ found = true;
+ }
+ }
+ if (!found && (tc->displayName().startsWith(QLatin1String("iphone"))
+ || tc->displayName().startsWith(QLatin1String("mac")))) {
+ qDebug() << "removing toolchain" << tc->displayName();
+ ProjectExplorer::ToolChainManager::deregisterToolChain(tc);
+ }
+ }
+ // add missing toolchains
+ {
+ QMapIterator iter(platforms);
+ while (iter.hasNext()) {
+ iter.next();
+ const Platform &p = iter.value();
+ if (platformToolchainMap.contains(p.name)
+ || (p.platformKind & Platform::BasePlatform) == 0
+ || (p.name.startsWith(QLatin1String("iphone"))
+ && (p.platformKind & Platform::Cxx11Support) != 0))
+ continue;
+ ProjectExplorer::GccToolChain *toolchain;
+ if (p.compilerPath.toFileInfo().baseName().startsWith(QLatin1String("clang")))
+ toolchain = new ProjectExplorer::ClangToolChain(
+ ProjectExplorer::ToolChain::AutoDetection);
+ else
+ toolchain = new ProjectExplorer::GccToolChain(
+ QLatin1String(ProjectExplorer::Constants::GCC_TOOLCHAIN_ID),
+ ProjectExplorer::ToolChain::AutoDetection);
+ QString baseDisplayName = p.name;
+ QString displayName = baseDisplayName;
+ for (int iVers = 1; iVers < 100; ++iVers) {
+ bool unique = true;
+ foreach (ProjectExplorer::ToolChain *existingTC, ProjectExplorer::ToolChainManager::toolChains()) {
+ if (existingTC->displayName() == displayName) {
+ unique = false;
+ break;
+ }
+ }
+ if (unique) break;
+ displayName = baseDisplayName + QLatin1String("-") + QString::number(iVers);
+ }
+ toolchain->setDisplayName(displayName);
+ toolchain->setPlatformCodeGenFlags(p.backendFlags);
+ toolchain->setPlatformLinkerFlags(p.backendFlags);
+ toolchain->setCompilerCommand(p.compilerPath);
+ ProjectExplorer::ToolChainManager::registerToolChain(toolchain);
+ platformToolchainMap.insert(p.name, toolchain);
+ QMapIterator iter2(iter);
+ while (iter2.hasNext()) {
+ iter2.next();
+ const Platform &p2 = iter2.value();
+ if (!platformToolchainMap.contains(p2.name)
+ && p2.compilerPath == toolchain->compilerCommand()
+ && p2.backendFlags == toolchain->platformCodeGenFlags()) {
+ platformToolchainMap[p2.name] = toolchain;
+ }
+ }
+ }
+ }
+ // filter out all non iphone, non base, non clang or cxx11 platforms, as we don't set up kits for those
+ {
+ QStringList toRemove;
+ QMapIterator iter(platforms);
+ while (iter.hasNext()) {
+ iter.next();
+ const Platform &p = iter.value();
+ if (!p.name.startsWith(QLatin1String("iphone")) || (p.platformKind & Platform::BasePlatform) == 0
+ || (p.platformKind & Platform::Cxx11Support) != 0
+ || !p.compilerPath.toString().contains(QLatin1String("clang")))
+ toRemove.append(p.name);
+ }
+ foreach (const QString &pName, toRemove) {
+ if (debugProbe)
+ qDebug() << "filtering out " << pName;
+ platforms.remove(pName);
+ }
+ }
+ QMap > qtVersionsForArch;
+ foreach (QtSupport::BaseQtVersion *qtVersion, QtSupport::QtVersionManager::versions()) {
+ if (debugProbe)
+ qDebug() << "qt type " << qtVersion->type();
+ if (qtVersion->type() != QLatin1String(Constants::IOSQT)) {
+ if (qtVersion->qmakeProperty("QMAKE_PLATFORM").contains(QLatin1String("ios"))
+ || qtVersion->qmakeProperty("QMAKE_XSPEC").contains(QLatin1String("ios"))) {
+ // replace with an ios version
+ QtSupport::BaseQtVersion *iosVersion =
+ QtSupport::QtVersionFactory::createQtVersionFromQMakePath(
+ qtVersion->qmakeCommand(),
+ qtVersion->isAutodetected(),
+ qtVersion->autodetectionSource());
+ if (iosVersion && iosVersion->type() == QLatin1String(Constants::IOSQT)) {
+ if (debugProbe)
+ qDebug() << "converting QT to iOS QT for " << qtVersion->qmakeCommand().toUserOutput();
+ QtSupport::QtVersionManager::removeVersion(qtVersion);
+ QtSupport::QtVersionManager::addVersion(iosVersion);
+ qtVersion = iosVersion;
+ } else {
+ continue;
+ }
+ } else {
+ continue;
+ }
+ }
+ if (!qtVersion->isValid())
+ continue;
+ QList qtAbis = qtVersion->qtAbis();
+ if (qtAbis.empty())
+ continue;
+ if (debugProbe)
+ qDebug() << "qt arch " << qtAbis.first().architecture();
+ foreach (const ProjectExplorer::Abi &abi, qtAbis)
+ qtVersionsForArch[abi.architecture()].append(qtVersion);
+ }
+
+ QList existingKits;
+ QList kitMatched;
+ foreach (ProjectExplorer::Kit *k, ProjectExplorer::KitManager::kits()) {
+ Core::Id deviceKind=ProjectExplorer::DeviceTypeKitInformation::deviceTypeId(k);
+ if (deviceKind != Core::Id(Constants::IOS_DEVICE_TYPE)
+ && deviceKind != Core::Id(Constants::IOS_SIMULATOR_TYPE)
+ && deviceKind != Core::Id(ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)){
+ if (debugProbe)
+ qDebug() << "skipping existing kit with deviceKind " << deviceKind.toString();
+ continue;
+ }
+ if (!k->isAutoDetected()) // use also used set kits?
+ continue;
+ existingKits << k;
+ kitMatched << false;
+ }
+ // create missing kits
+ {
+ QMapIterator iter(platforms);
+ while (iter.hasNext()) {
+ iter.next();
+ const Platform &p = iter.value();
+ ProjectExplorer::GccToolChain *pToolchain = platformToolchainMap.value(p.name, 0);
+ if (!pToolchain)
+ continue;
+ Core::Id pDeviceType, pDeviceId;
+ if (debugProbe)
+ qDebug() << "guaranteeing kit for " << p.name ;
+ if (p.name.startsWith(QLatin1String("iphoneos-"))) {
+ pDeviceType = Core::Id(Constants::IOS_DEVICE_TYPE);
+ } else if (p.name.startsWith(QLatin1String("iphonesimulator-"))) {
+ pDeviceType = Core::Id(Constants::IOS_SIMULATOR_TYPE);
+ if (debugProbe)
+ qDebug() << "pDeviceType " << pDeviceType.toString();
+ } else {
+ if (debugProbe)
+ qDebug() << "skipping non ios kit " << p.name;
+ // we looked up only the ios qt build above...
+ continue;
+ //pDeviceType = Core::Id(ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE);
+ }
+ ProjectExplorer::Abi::Architecture arch = pToolchain->targetAbi().architecture();
+
+ QList qtVersions = qtVersionsForArch.value(arch);
+ foreach (QtSupport::BaseQtVersion *qt, qtVersions) {
+ bool kitExists = false;
+ for (int i = 0; i < existingKits.size(); ++i) {
+ Kit *k = existingKits.at(i);
+ if (DeviceTypeKitInformation::deviceTypeId(k) == pDeviceType
+ && ToolChainKitInformation::toolChain(k) == pToolchain
+ && SysRootKitInformation::sysRoot(k) == p.sdkPath
+ && QtSupport::QtKitInformation::qtVersion(k) == qt)
+ {
+ kitExists = true;
+ if (debugProbe)
+ qDebug() << "found existing kit " << k->displayName() << " for " << p.name
+ << "," << qt->displayName();
+ if (isetAutoDetected(true);
+ QString baseDisplayName = tr("%1 %2").arg(p.name, qt->displayName());
+ QString displayName = baseDisplayName;
+ for (int iVers = 1; iVers < 100; ++iVers) {
+ bool unique = true;
+ foreach (const ProjectExplorer::Kit *k, existingKits) {
+ if (k->displayName() == displayName) {
+ unique = false;
+ break;
+ }
+ }
+ if (unique) break;
+ displayName = baseDisplayName + QLatin1String("-") + QString::number(iVers);
+ }
+ newKit->setDisplayName(displayName);
+ //newKit->setIconPath(QLatin1String(Constants::IOS_SETTINGS_CATEGORY_ICON));
+ //DeviceKitInformation::setDevice(newKit, pDeviceType);
+ DeviceTypeKitInformation::setDeviceTypeId(newKit, pDeviceType);
+ ToolChainKitInformation::setToolChain(newKit, pToolchain);
+ QtSupport::QtKitInformation::setQtVersion(newKit, qt);
+ //DeviceKitInformation::setDevice(newKit, device);
+ Debugger::DebuggerKitInformation::setDebugger(newKit, pToolchain->suggestedDebugger());
+ SysRootKitInformation::setSysRoot(newKit, p.sdkPath);
+ //Qt4ProjectManager::QmakeKitInformation::setMkspec(newKit,
+ // Utils::FileName::fromString(QLatin1String("macx-ios-clang")));
+ KitManager::registerKit(newKit);
+ existingKits << newKit;
+ }
+ }
+ }
+ // deleting extra (old) kits
+ for (int i = 0; i < kitMatched.size(); ++i) {
+ if (!kitMatched.at(i) && !existingKits.at(i)->isValid()) {
+ qDebug() << "deleting kit " << existingKits.at(i)->displayName();
+ KitManager::deregisterKit(existingKits.at(i));
+ }
+ }
+}
+
+IosConfigurations &IosConfigurations::instance()
+{
+ if (m_instance == 0) {
+ m_instance = new IosConfigurations(0);
+ m_instance->updateSimulators();
+ connect(&(m_instance->m_updateAvailableDevices),SIGNAL(timeout()),
+ IosDeviceManager::instance(),SLOT(monitorAvailableDevices()));
+ m_instance->m_updateAvailableDevices.setSingleShot(true);
+ m_instance->m_updateAvailableDevices.start(10000);
+ }
+ return *m_instance;
+}
+
+void IosConfigurations::save()
+{
+ QSettings *settings = Core::ICore::instance()->settings();
+ settings->beginGroup(SettingsGroup);
+ m_config.save(*settings);
+ settings->endGroup();
+}
+
+IosConfigurations::IosConfigurations(QObject *parent)
+ : QObject(parent)
+{
+ load();
+}
+
+void IosConfigurations::load()
+{
+ QSettings *settings = Core::ICore::instance()->settings();
+ settings->beginGroup(SettingsGroup);
+ m_config = IosConfig(*settings);
+ settings->endGroup();
+}
+
+IosConfigurations *IosConfigurations::m_instance = 0;
+
+QStringList IosConfigurations::sdkTargets()
+{
+ QStringList res;
+ QTC_CHECK(false);
+ return res;
+}
+
+void IosConfigurations::updateSimulators() {
+ // currently we have just one simulator
+ DeviceManager *devManager = DeviceManager::instance();
+ Core::Id devId(Constants::IOS_SIMULATOR_DEVICE_ID);
+ QMap platforms = IosProbe::detectPlatforms(m_config.developerPath.toString());
+ QMapIterator iter(platforms);
+ Utils::FileName simulatorPath;
+ while (iter.hasNext()) {
+ iter.next();
+ const Platform &p = iter.value();
+ if (p.name.startsWith(QLatin1String("iphonesimulator-"))) {
+ simulatorPath = p.platformPath;
+ simulatorPath.appendPath(QLatin1String(
+ "/Developer/Applications/iPhone Simulator.app/Contents/MacOS/iPhone Simulator"));
+ if (simulatorPath.toFileInfo().exists())
+ break;
+ }
+ }
+ IDevice::ConstPtr dev = devManager->find(devId);
+ if (!simulatorPath.isEmpty() && simulatorPath.toFileInfo().exists()) {
+ if (!dev.isNull()) {
+ if (static_cast(dev.data())->simulatorPath() == simulatorPath)
+ return;
+ devManager->removeDevice(devId);
+ }
+ IosSimulator *newDev = new IosSimulator(devId, simulatorPath);
+ devManager->addDevice(IDevice::ConstPtr(newDev));
+ } else if (!dev.isNull()) {
+ devManager->removeDevice(devId);
+ }
+}
+
+} // namespace Internal
+} // namespace Ios
diff --git a/src/plugins/ios/iosconfigurations.h b/src/plugins/ios/iosconfigurations.h
new file mode 100644
index 00000000000..0bb0f1abf3f
--- /dev/null
+++ b/src/plugins/ios/iosconfigurations.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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 IOSCONFIGURATIONS_H
+#define IOSCONFIGURATIONS_H
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+QT_BEGIN_NAMESPACE
+class QSettings;
+QT_END_NAMESPACE
+
+namespace Ios {
+namespace Internal {
+
+class IosConfig
+{
+public:
+ IosConfig();
+ IosConfig(const QSettings &settings);
+ void save(QSettings &settings) const;
+
+ Utils::FileName developerPath;
+ bool ignoreAllDevices;
+};
+
+class IosConfigurations : public QObject
+{
+ Q_OBJECT
+
+public:
+ static IosConfigurations &instance();
+ IosConfig config() const { return m_config; }
+ void setConfig(const IosConfig &config);
+ Utils::FileName iosToolPath() const;
+
+ QStringList sdkTargets();
+ void updateSimulators();
+signals:
+ void updated();
+
+public slots:
+ void updateAutomaticKitList();
+
+private:
+ IosConfigurations(QObject *parent);
+ void load();
+ void save();
+
+ static IosConfigurations *m_instance;
+ IosConfig m_config;
+ QTimer m_updateAvailableDevices;
+};
+
+} // namespace Internal
+} // namespace Ios
+
+#endif // IOSCONFIGURATIONS_H
diff --git a/src/plugins/ios/iosconstants.h b/src/plugins/ios/iosconstants.h
new file mode 100644
index 00000000000..915b91f119e
--- /dev/null
+++ b/src/plugins/ios/iosconstants.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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 IOSCONSTANTS_H
+#define IOSCONSTANTS_H
+
+#include
+
+namespace Ios {
+namespace Internal {
+
+enum IosQemuStatus {
+ IosQemuStarting,
+ IosQemuFailedToStart,
+ IosQemuFinished,
+ IosQemuCrashed,
+ IosQemuUserReason
+};
+
+#ifdef Q_OS_WIN32
+#define IOS_BAT_SUFFIX ".bat"
+#else
+#define IOS_BAT_SUFFIX ""
+#endif
+
+} // namespace Internal
+
+namespace Constants {
+const char IOS_SETTINGS_ID[] = "ZZ.Ios Configurations";
+const char IOS_SETTINGS_CATEGORY[] = "XA.Ios";
+const char IOS_SETTINGS_TR_CATEGORY[] = QT_TRANSLATE_NOOP("Ios", "iOS");
+const char IOS_SETTINGS_CATEGORY_ICON[] = ":/ios/images/QtIos.png";
+const char IOSQT[] = "Qt4ProjectManager.QtVersion.Ios";
+
+const char IOS_DEVICE_TYPE[] = "Ios.Device.Type";
+const char IOS_SIMULATOR_TYPE[] = "Ios.Simulator.Type";
+const char IOS_DEVICE_ID[] = "iOS Device ";
+const char IOS_SIMULATOR_DEVICE_ID[] = "iOS Simulator Device ";
+} // namespace Constants;
+} // namespace Ios
+
+#endif // IOSCONSTANTS_H
diff --git a/src/plugins/ios/iosdebugsupport.cpp b/src/plugins/ios/iosdebugsupport.cpp
new file mode 100644
index 00000000000..2a9bf594452
--- /dev/null
+++ b/src/plugins/ios/iosdebugsupport.cpp
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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 "iosdebugsupport.h"
+
+#include "iosrunner.h"
+#include "iosmanager.h"
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+using namespace Debugger;
+using namespace ProjectExplorer;
+using namespace Qt4ProjectManager;
+
+namespace Ios {
+namespace Internal {
+
+static const char * const qMakeVariables[] = {
+ "QT_INSTALL_LIBS",
+ "QT_INSTALL_PLUGINS",
+ "QT_INSTALL_IMPORTS"
+};
+
+
+RunControl *IosDebugSupport::createDebugRunControl(IosRunConfiguration *runConfig,
+ QString *errorMessage)
+{
+ //Target *target = runConfig->target();
+ //Qt4Project *project = static_cast(target->project());
+
+ DebuggerStartParameters params;
+ params.startMode = AttachToRemoteServer;
+ //params.displayName = IosManager::packageName(target);
+ params.remoteSetupNeeded = true;
+
+ DebuggerRunControl * const debuggerRunControl
+ = DebuggerPlugin::createDebugger(params, runConfig, errorMessage);
+ new IosDebugSupport(runConfig, debuggerRunControl);
+ return debuggerRunControl;
+}
+
+IosDebugSupport::IosDebugSupport(IosRunConfiguration *runConfig,
+ DebuggerRunControl *runControl)
+ : QObject(runControl), m_runControl(runControl),
+ m_runner(new IosRunner(this, runConfig, true)),
+ m_gdbServerPort(0), m_qmlPort(0)
+{
+
+ connect(m_runControl->engine(), SIGNAL(requestRemoteSetup()),
+ m_runner, SLOT(start()));
+ connect(m_runControl, SIGNAL(finished()),
+ m_runner, SLOT(stop()));
+
+ connect(m_runner, SIGNAL(gotGdbSocket(int)),
+ SLOT(handleGdbServerFd(int)));
+ connect(m_runner, SIGNAL(finished(bool)),
+ SLOT(handleRemoteProcessFinished(bool)));
+
+ connect(m_runner, SIGNAL(errorMsg(QString)),
+ SLOT(handleRemoteErrorOutput(QString)));
+ connect(m_runner, SIGNAL(appOutput(QString)),
+ SLOT(handleRemoteOutput(QString)));
+}
+
+void IosDebugSupport::handleGdbServerFd(int gdbServerFd)
+{
+ QTC_CHECK(false); // to do transfer fd to debugger
+ //m_runControl->engine()->notifyEngineRemoteSetupDone(gdbServerPort, qmlPort);
+}
+
+void IosDebugSupport::handleRemoteProcessFinished(bool cleanEnd)
+{
+ if (!cleanEnd && m_runControl)
+ m_runControl->showMessage(tr("Run failed unexpectedly."), AppStuff);
+}
+
+void IosDebugSupport::handleRemoteOutput(const QString &output)
+{
+ if (m_runControl) {
+ if (m_runControl->engine())
+ m_runControl->engine()->showMessage(output, AppOutput);
+ else
+ m_runControl->showMessage(output, AppOutput);
+ }
+}
+
+void IosDebugSupport::handleRemoteErrorOutput(const QString &output)
+{
+ if (m_runControl) {
+ if (m_runControl->engine())
+ m_runControl->engine()->showMessage(output + QLatin1Char('\n'), AppError);
+ else
+ m_runControl->showMessage(output + QLatin1Char('\n'), AppError);
+ }
+}
+
+} // namespace Internal
+} // namespace Ios
diff --git a/src/plugins/ios/iosdebugsupport.h b/src/plugins/ios/iosdebugsupport.h
new file mode 100644
index 00000000000..7d2047bfc5c
--- /dev/null
+++ b/src/plugins/ios/iosdebugsupport.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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 IOSDEBUGSUPPORT_H
+#define IOSDEBUGSUPPORT_H
+
+#include "iosrunconfiguration.h"
+
+namespace Debugger { class DebuggerRunControl; }
+namespace ProjectExplorer { class RunControl; }
+
+namespace Ios {
+namespace Internal {
+
+class IosRunConfiguration;
+class IosRunner;
+
+class IosDebugSupport : public QObject
+{
+ Q_OBJECT
+
+public:
+ static ProjectExplorer::RunControl *createDebugRunControl(IosRunConfiguration *runConfig,
+ QString *errorMessage);
+
+ IosDebugSupport(IosRunConfiguration *runConfig,
+ Debugger::DebuggerRunControl *runControl);
+
+private slots:
+ void handleGdbServerFd(int gdbServerFd);
+ void handleRemoteProcessFinished(bool cleanEnd);
+
+ void handleRemoteOutput(const QString &output);
+ void handleRemoteErrorOutput(const QString &output);
+
+private:
+ Debugger::DebuggerRunControl *m_runControl;
+ IosRunner * const m_runner;
+ const QString m_dumperLib;
+
+ int m_gdbServerPort;
+ int m_qmlPort;
+};
+
+} // namespace Internal
+} // namespace Ios
+
+#endif // IOSDEBUGSUPPORT_H
diff --git a/src/plugins/ios/iosdeployconfiguration.cpp b/src/plugins/ios/iosdeployconfiguration.cpp
new file mode 100644
index 00000000000..975a62647a6
--- /dev/null
+++ b/src/plugins/ios/iosdeployconfiguration.cpp
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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 "iosconstants.h"
+#include "iosdeploystep.h"
+#include "iosdeployconfiguration.h"
+#include "iosmanager.h"
+
+#include
+#include
+
+#include
+#include
+#include
+
+using namespace ProjectExplorer;
+
+namespace Ios {
+namespace Internal {
+
+IosDeployConfiguration::IosDeployConfiguration(Target *parent, Core::Id id)
+ : DeployConfiguration(parent, id)
+{
+ setDisplayName(tr("Deploy to iOS"));
+ setDefaultDisplayName(displayName());
+}
+
+IosDeployConfiguration::IosDeployConfiguration(Target *parent, DeployConfiguration *source)
+ : DeployConfiguration(parent, source)
+{
+ cloneSteps(source);
+}
+
+IosDeployConfigurationFactory::IosDeployConfigurationFactory(QObject *parent)
+ : DeployConfigurationFactory(parent)
+{
+ setObjectName(QLatin1String("IosDeployConfigurationFactory"));
+}
+
+bool IosDeployConfigurationFactory::canCreate(Target *parent, const Core::Id id) const
+{
+ return availableCreationIds(parent).contains(id);
+}
+
+DeployConfiguration *IosDeployConfigurationFactory::create(Target *parent, const Core::Id id)
+{
+ IosDeployConfiguration *dc = new IosDeployConfiguration(parent, id);
+ if (!dc)
+ return 0;
+ dc->stepList()->insertStep(0, new IosDeployStep(dc->stepList()));
+ return dc;
+}
+
+bool IosDeployConfigurationFactory::canRestore(Target *parent, const QVariantMap &map) const
+{
+ return canCreate(parent, idFromMap(map));
+}
+
+DeployConfiguration *IosDeployConfigurationFactory::restore(Target *parent, const QVariantMap &map)
+{
+ if (!canRestore(parent, map))
+ return 0;
+
+ IosDeployConfiguration *dc = new IosDeployConfiguration(parent, idFromMap(map));
+ if (dc->fromMap(map))
+ return dc;
+
+ delete dc;
+ return 0;
+}
+
+bool IosDeployConfigurationFactory::canClone(Target *parent, DeployConfiguration *source) const
+{
+ if (!IosManager::supportsIos(parent))
+ return false;
+ return source->id() == IOS_DEPLOYCONFIGURATION_ID;
+}
+
+DeployConfiguration *IosDeployConfigurationFactory::clone(Target *parent, DeployConfiguration *source)
+{
+ if (!canClone(parent, source))
+ return 0;
+ return new IosDeployConfiguration(parent, source);
+}
+
+QList IosDeployConfigurationFactory::availableCreationIds(Target *parent) const
+{
+ QList ids;
+ if (!qobject_cast(parent->project()))
+ return ids;
+ if (!parent->project()->supportsKit(parent->kit()))
+ return ids;
+ if (!IosManager::supportsIos(parent))
+ return ids;
+ ids << Core::Id(IOS_DEPLOYCONFIGURATION_ID);
+ return ids;
+}
+
+QString IosDeployConfigurationFactory::displayNameForId(const Core::Id id) const
+{
+ if (id.name().startsWith(IOS_DC_PREFIX))
+ return tr("Deploy on iOS");
+ return QString();
+}
+
+bool IosDeployConfigurationFactory::canHandle(Target *parent) const
+{
+ return IosManager::supportsIos(parent);
+}
+
+} // namespace Internal
+} // namespace Ios
diff --git a/src/plugins/ios/iosdeployconfiguration.h b/src/plugins/ios/iosdeployconfiguration.h
new file mode 100644
index 00000000000..632b2b5aa48
--- /dev/null
+++ b/src/plugins/ios/iosdeployconfiguration.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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 IOSDEPLOYCONFIGURATION_H
+#define IOSDEPLOYCONFIGURATION_H
+
+#include
+
+namespace Ios {
+namespace Internal {
+
+const char IOS_DEPLOYCONFIGURATION_ID[] = "Qt4ProjectManager.IosDeployConfiguration";
+const char IOS_DC_PREFIX[] = "Qt4ProjectManager.IosDeployConfiguration.";
+
+class IosDeployConfiguration : public ProjectExplorer::DeployConfiguration
+{
+ Q_OBJECT
+ friend class IosDeployConfigurationFactory;
+
+public:
+ IosDeployConfiguration(ProjectExplorer::Target *parent, Core::Id id);
+
+protected:
+ IosDeployConfiguration(ProjectExplorer::Target *parent,
+ ProjectExplorer::DeployConfiguration *source);
+
+};
+
+class IosDeployConfigurationFactory : public ProjectExplorer::DeployConfigurationFactory
+{
+ Q_OBJECT
+
+public:
+ explicit IosDeployConfigurationFactory(QObject *parent = 0);
+
+ bool canCreate(ProjectExplorer::Target *parent, const Core::Id id) const;
+ ProjectExplorer::DeployConfiguration *create(ProjectExplorer::Target *parent, const Core::Id id);
+ bool canRestore(ProjectExplorer::Target *parent, const QVariantMap &map) const;
+ ProjectExplorer::DeployConfiguration *restore(ProjectExplorer::Target *parent,
+ const QVariantMap &map);
+ bool canClone(ProjectExplorer::Target *parent,
+ ProjectExplorer::DeployConfiguration *source) const;
+ ProjectExplorer::DeployConfiguration *clone(ProjectExplorer::Target *parent,
+ ProjectExplorer::DeployConfiguration *source);
+
+ QList availableCreationIds(ProjectExplorer::Target *parent) const;
+ // used to translate the ids to names to display to the user
+ QString displayNameForId(const Core::Id id) const;
+
+private:
+ bool canHandle(ProjectExplorer::Target *parent) const;
+};
+
+} // namespace Internal
+} // namespace Ios
+
+#endif // IOSDEPLOYCONFIGURATION_H
diff --git a/src/plugins/ios/iosdeploystep.cpp b/src/plugins/ios/iosdeploystep.cpp
new file mode 100644
index 00000000000..f6bce58dbc7
--- /dev/null
+++ b/src/plugins/ios/iosdeploystep.cpp
@@ -0,0 +1,231 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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 "iosdeploystepwidget.h"
+#include "iosdeploystep.h"
+#include "iosbuildstep.h"
+#include "iosconstants.h"
+#include "iosrunconfiguration.h"
+#include "iosmanager.h"
+#include "iostoolhandler.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include
+
+#define ASSERT_STATE(state) ASSERT_STATE_GENERIC(State, state, m_state)
+
+using namespace ProjectExplorer;
+using namespace Qt4ProjectManager;
+
+namespace Ios {
+namespace Internal {
+
+static const char USE_LOCAL_QT_KEY[] = "Qt4ProjectManager.IosDeployStep.UseLocalQtLibs";
+
+const Core::Id IosDeployStep::Id("Qt4ProjectManager.IosDeployStep");
+
+IosDeployStep::IosDeployStep(ProjectExplorer::BuildStepList *parent)
+ : BuildStep(parent, Id)
+{
+ ctor();
+}
+
+IosDeployStep::IosDeployStep(ProjectExplorer::BuildStepList *parent,
+ IosDeployStep *other)
+ : BuildStep(parent, other)
+{
+ ctor();
+}
+
+IosDeployStep::~IosDeployStep() { }
+
+void IosDeployStep::ctor()
+{
+ m_transferStatus = NoTransfer;
+ m_device = ProjectExplorer::DeviceKitInformation::device(target()->kit());
+ QString devName;
+ if (!m_device.isNull())
+ devName = m_device->displayName();
+ if (devName.isEmpty())
+ devName = tr("iOS device");
+ setDefaultDisplayName(tr("Deploy to %1").arg(devName));
+}
+
+bool IosDeployStep::init()
+{
+ QTC_CHECK(m_transferStatus == NoTransfer);
+ m_device = ProjectExplorer::DeviceKitInformation::device(target()->kit());
+ return true;
+}
+
+void IosDeployStep::run(QFutureInterface &fi)
+{
+ m_futureInterface = fi;
+ QTC_CHECK(m_transferStatus == NoTransfer);
+ if (iosdevice().isNull()) {
+ m_futureInterface.reportResult(!iossimulator().isNull());
+ cleanup();
+ m_futureInterface.reportFinished();
+ return;
+ }
+ m_transferStatus = TransferInProgress;
+ IosToolHandler *toolHandler = new IosToolHandler(IosToolHandler::IosDeviceType, this);
+ m_futureInterface.setProgressRange(0, 200);
+ m_futureInterface.setProgressValueAndText(0, QLatin1String("Transferring application"));
+ m_futureInterface.reportStarted();
+ connect(toolHandler, SIGNAL(isTransferringApp(Ios::IosToolHandler*,QString,QString,int,int,QString)),
+ SLOT(handleIsTransferringApp(Ios::IosToolHandler*,QString,QString,int,int,QString)));
+ connect(toolHandler, SIGNAL(didTransferApp(Ios::IosToolHandler*,QString,QString,Ios::IosToolHandler::OpStatus)),
+ SLOT(handleDidTransferApp(Ios::IosToolHandler*,QString,QString,Ios::IosToolHandler::OpStatus)));
+ connect(toolHandler, SIGNAL(finished(Ios::IosToolHandler*)),
+ SLOT(handleFinished(Ios::IosToolHandler*)));
+ toolHandler->requestTransferApp(appBundle(), deviceId());
+}
+
+void IosDeployStep::cancel()
+{
+ if (m_toolHandler)
+ m_toolHandler->stop();
+}
+
+void IosDeployStep::cleanup()
+{
+ QTC_CHECK(m_transferStatus != TransferInProgress);
+ m_transferStatus = NoTransfer;
+ m_device.clear();
+ m_toolHandler = 0;
+}
+
+void IosDeployStep::handleIsTransferringApp(IosToolHandler *handler, const QString &bundlePath,
+ const QString &deviceId, int progress, int maxProgress,
+ const QString &info)
+{
+ Q_UNUSED(handler); Q_UNUSED(bundlePath); Q_UNUSED(deviceId);
+ QTC_CHECK(m_transferStatus == TransferInProgress);
+ m_futureInterface.setProgressRange(0, maxProgress);
+ m_futureInterface.setProgressValueAndText(progress, info);
+}
+
+void IosDeployStep::handleDidTransferApp(IosToolHandler *handler, const QString &bundlePath,
+ const QString &deviceId, IosToolHandler::OpStatus status)
+{
+ Q_UNUSED(handler); Q_UNUSED(bundlePath); Q_UNUSED(deviceId);
+ QTC_CHECK(m_transferStatus == TransferInProgress);
+ if (status == IosToolHandler::Success)
+ m_transferStatus = TransferOk;
+ else
+ m_transferStatus = TransferFailed;
+ m_futureInterface.reportResult(status == IosToolHandler::Success);
+}
+
+void IosDeployStep::handleFinished(IosToolHandler *handler)
+{
+ switch (m_transferStatus) {
+ case TransferInProgress:
+ m_transferStatus = TransferFailed;
+ m_futureInterface.reportResult(false);
+ break;
+ case NoTransfer:
+ case TransferOk:
+ case TransferFailed:
+ break;
+ }
+ cleanup();
+ handler->deleteLater();
+ // move it when result is reported? (would need care to avoid problems with concurrent runs)
+ m_futureInterface.reportFinished();
+}
+
+BuildStepConfigWidget *IosDeployStep::createConfigWidget()
+{
+ return new IosDeployStepWidget(this);
+}
+
+bool IosDeployStep::fromMap(const QVariantMap &map)
+{
+ return ProjectExplorer::BuildStep::fromMap(map);
+}
+
+QVariantMap IosDeployStep::toMap() const
+{
+ QVariantMap map = ProjectExplorer::BuildStep::toMap();
+ return map;
+}
+
+QString IosDeployStep::deviceId() const
+{
+ if (iosdevice().isNull())
+ return QString();
+ return iosdevice()->uniqueDeviceID();
+}
+
+QString IosDeployStep::appBundle() const
+{
+ IosRunConfiguration * runConfig = qobject_cast(
+ this->target()->activeRunConfiguration());
+ return runConfig->bundleDir().toString();
+}
+
+void IosDeployStep::raiseError(const QString &errorString)
+{
+ emit addTask(Task(Task::Error, errorString, Utils::FileName::fromString(QString()), -1,
+ ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM));
+}
+
+void IosDeployStep::writeOutput(const QString &text, OutputFormat format)
+{
+ emit addOutput(text, format);
+}
+
+IDevice::ConstPtr IosDeployStep::device() const
+{
+ return m_device;
+}
+
+IosDevice::ConstPtr IosDeployStep::iosdevice() const
+{
+ return m_device.dynamicCast();
+}
+
+IosSimulator::ConstPtr IosDeployStep::iossimulator() const
+{
+ return m_device.dynamicCast();
+}
+
+} // namespace Internal
+} // namespace Qt4ProjectManager
diff --git a/src/plugins/ios/iosdeploystep.h b/src/plugins/ios/iosdeploystep.h
new file mode 100644
index 00000000000..23988cf68f5
--- /dev/null
+++ b/src/plugins/ios/iosdeploystep.h
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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 IOSDEPLOYSTEP_H
+#define IOSDEPLOYSTEP_H
+
+#include "iosconfigurations.h"
+#include "iosdevice.h"
+#include "iossimulator.h"
+
+#include
+#include
+#include
+
+#include
+#include
+
+QT_BEGIN_NAMESPACE
+class QEventLoop;
+class QTimer;
+QT_END_NAMESPACE
+
+namespace Ios {
+class IosToolHandler;
+namespace Internal {
+class IosDeviceConfigListModel;
+class IosPackageCreationStep;
+
+class DeployItem
+{
+public:
+ DeployItem(const QString &_localFileName,
+ unsigned int _localTimeStamp,
+ const QString &_remoteFileName,
+ bool _needsStrip)
+ : localFileName(_localFileName),
+ remoteFileName(_remoteFileName),
+ localTimeStamp(_localTimeStamp),
+ remoteTimeStamp(0),
+ needsStrip(_needsStrip)
+ {}
+ QString localFileName;
+ QString remoteFileName;
+ unsigned int localTimeStamp;
+ unsigned int remoteTimeStamp;
+ bool needsStrip;
+};
+
+class IosDeployStep : public ProjectExplorer::BuildStep
+{
+ Q_OBJECT
+public:
+ enum TransferStatus {
+ NoTransfer,
+ TransferInProgress,
+ TransferOk,
+ TransferFailed
+ };
+
+ friend class IosDeployStepFactory;
+ IosDeployStep(ProjectExplorer::BuildStepList *bc);
+
+ virtual ~IosDeployStep();
+
+ bool fromMap(const QVariantMap &map);
+ QVariantMap toMap() const;
+
+ virtual void run(QFutureInterface &fi);
+ void cleanup();
+ ProjectExplorer::IDevice::ConstPtr device() const;
+ IosDevice::ConstPtr iosdevice() const;
+ IosSimulator::ConstPtr iossimulator() const;
+ void cancel();
+signals:
+ //void done();
+ //void error();
+
+private slots:
+ void handleIsTransferringApp(Ios::IosToolHandler *handler, const QString &bundlePath,
+ const QString &deviceId, int progress, int maxProgress,
+ const QString &info);
+ void handleDidTransferApp(Ios::IosToolHandler *handler, const QString &bundlePath, const QString &deviceId,
+ Ios::IosToolHandler::OpStatus status);
+ void handleFinished(Ios::IosToolHandler *handler);
+
+private:
+ IosDeployStep(ProjectExplorer::BuildStepList *bc,
+ IosDeployStep *other);
+ bool init();
+ ProjectExplorer::BuildStepConfigWidget *createConfigWidget();
+ bool immutable() const { return true; }
+ bool runInGuiThread() const { return true; }
+
+ void ctor();
+ QString deviceId() const;
+ QString appBundle() const;
+ void raiseError(const QString &error);
+ void writeOutput(const QString &text, OutputFormat = MessageOutput);
+private:
+ TransferStatus m_transferStatus;
+ IosToolHandler *m_toolHandler;
+ QFutureInterface m_futureInterface;
+ ProjectExplorer::IDevice::ConstPtr m_device;
+ static const Core::Id Id;
+};
+
+} // namespace Internal
+} // namespace Ios
+
+#endif // IOSDEPLOYSTEP_H
diff --git a/src/plugins/ios/iosdeploystepfactory.cpp b/src/plugins/ios/iosdeploystepfactory.cpp
new file mode 100644
index 00000000000..8b8430fbe67
--- /dev/null
+++ b/src/plugins/ios/iosdeploystepfactory.cpp
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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 "iosdeploystepfactory.h"
+
+#include "iosdeploystep.h"
+#include "iosmanager.h"
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+using namespace ProjectExplorer;
+
+namespace Ios {
+namespace Internal {
+
+IosDeployStepFactory::IosDeployStepFactory(QObject *parent)
+ : IBuildStepFactory(parent)
+{
+}
+
+QList IosDeployStepFactory::availableCreationIds(BuildStepList *parent) const
+{
+ if (parent->id() != ProjectExplorer::Constants::BUILDSTEPS_DEPLOY)
+ return QList();
+ if (!IosManager::supportsIos(parent->target()))
+ return QList();
+ if (parent->contains(IosDeployStep::Id))
+ return QList();
+ return QList() << IosDeployStep::Id;
+}
+
+QString IosDeployStepFactory::displayNameForId(const Core::Id id) const
+{
+ if (id == IosDeployStep::Id)
+ return tr("Deploy to iOS device or emulator");
+ return QString();
+}
+
+bool IosDeployStepFactory::canCreate(BuildStepList *parent, const Core::Id id) const
+{
+ return availableCreationIds(parent).contains(id);
+}
+
+BuildStep *IosDeployStepFactory::create(BuildStepList *parent, const Core::Id id)
+{
+ Q_ASSERT(canCreate(parent, id));
+ Q_UNUSED(id);
+ return new IosDeployStep(parent);
+}
+
+bool IosDeployStepFactory::canRestore(BuildStepList *parent, const QVariantMap &map) const
+{
+ return canCreate(parent, idFromMap(map));
+}
+
+BuildStep *IosDeployStepFactory::restore(BuildStepList *parent, const QVariantMap &map)
+{
+ Q_ASSERT(canRestore(parent, map));
+ IosDeployStep * const step = new IosDeployStep(parent);
+ if (!step->fromMap(map)) {
+ delete step;
+ return 0;
+ }
+ return step;
+}
+
+bool IosDeployStepFactory::canClone(BuildStepList *parent, BuildStep *product) const
+{
+ return canCreate(parent, product->id());
+}
+
+BuildStep *IosDeployStepFactory::clone(BuildStepList *parent, BuildStep *product)
+{
+ Q_ASSERT(canClone(parent, product));
+ return new IosDeployStep(parent, static_cast(product));
+}
+
+} // namespace Internal
+} // namespace Ios
diff --git a/src/plugins/ios/iosdeploystepfactory.h b/src/plugins/ios/iosdeploystepfactory.h
new file mode 100644
index 00000000000..92494883924
--- /dev/null
+++ b/src/plugins/ios/iosdeploystepfactory.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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 IOSDEPLOYSTEPFACTORY_H
+#define IOSDEPLOYSTEPFACTORY_H
+
+#include
+
+namespace Ios {
+namespace Internal {
+
+class IosDeployStepFactory : public ProjectExplorer::IBuildStepFactory
+{
+ Q_OBJECT
+public:
+ explicit IosDeployStepFactory(QObject *parent = 0);
+
+ QList availableCreationIds(ProjectExplorer::BuildStepList *parent) const;
+ QString displayNameForId(const Core::Id id) const;
+
+ bool canCreate(ProjectExplorer::BuildStepList *parent,
+ const Core::Id id) const;
+ ProjectExplorer::BuildStep *create(ProjectExplorer::BuildStepList *parent, const Core::Id id);
+
+ bool canRestore(ProjectExplorer::BuildStepList *parent, const QVariantMap &map) const;
+ ProjectExplorer::BuildStep *restore(ProjectExplorer::BuildStepList *parent, const QVariantMap &map);
+
+ bool canClone(ProjectExplorer::BuildStepList *parent,
+ ProjectExplorer::BuildStep *product) const;
+ ProjectExplorer::BuildStep *clone(ProjectExplorer::BuildStepList *parent,
+ ProjectExplorer::BuildStep *product);
+};
+
+} // namespace Internal
+} // namespace Ios
+
+#endif // IOSDEPLOYSTEPFACTORY_H
diff --git a/src/plugins/ios/iosdeploystepwidget.cpp b/src/plugins/ios/iosdeploystepwidget.cpp
new file mode 100644
index 00000000000..d1e09b7adbf
--- /dev/null
+++ b/src/plugins/ios/iosdeploystepwidget.cpp
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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 "iosdeploystepwidget.h"
+#include "ui_iosdeploystepwidget.h"
+
+#include "iosdeploystep.h"
+#include "iosrunconfiguration.h"
+
+#include
+
+#include
+
+namespace Ios {
+namespace Internal {
+
+IosDeployStepWidget::IosDeployStepWidget(IosDeployStep *step) :
+ ProjectExplorer::BuildStepConfigWidget(),
+ ui(new Ui::IosDeployStepWidget),
+ m_step(step)
+{
+ ui->setupUi(this);
+}
+
+IosDeployStepWidget::~IosDeployStepWidget()
+{
+ delete ui;
+}
+
+QString IosDeployStepWidget::displayName() const
+{
+ QString deviceName = tr("iOS Device");
+ if (!m_step->device().isNull())
+ deviceName = m_step->device()->displayName();
+ return tr("Deploy to %1").arg(deviceName);
+}
+
+QString IosDeployStepWidget::summaryText() const
+{
+ return displayName();
+}
+
+} // namespace Internal
+} // namespace Qt4ProjectManager
diff --git a/src/plugins/ios/iosdeploystepwidget.h b/src/plugins/ios/iosdeploystepwidget.h
new file mode 100644
index 00000000000..1c3be04e40c
--- /dev/null
+++ b/src/plugins/ios/iosdeploystepwidget.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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 IOSDEPLOYSTEPWIDGET_H
+#define IOSDEPLOYSTEPWIDGET_H
+
+#include
+
+QT_BEGIN_NAMESPACE
+namespace Ui { class IosDeployStepWidget; }
+QT_END_NAMESPACE
+
+namespace Ios {
+namespace Internal {
+class IosDeployStep;
+
+class IosDeployStepWidget : public ProjectExplorer::BuildStepConfigWidget
+{
+ Q_OBJECT
+
+public:
+ IosDeployStepWidget(IosDeployStep *step);
+ ~IosDeployStepWidget();
+
+private:
+ virtual QString summaryText() const;
+ virtual QString displayName() const;
+
+ Ui::IosDeployStepWidget *ui;
+ IosDeployStep *m_step;
+};
+
+} // namespace Internal
+} // namespace Ios
+
+#endif // IOSDEPLOYSTEPWIDGET_H
diff --git a/src/plugins/ios/iosdeploystepwidget.ui b/src/plugins/ios/iosdeploystepwidget.ui
new file mode 100644
index 00000000000..7b97b387b2d
--- /dev/null
+++ b/src/plugins/ios/iosdeploystepwidget.ui
@@ -0,0 +1,26 @@
+
+
+ IosDeployStepWidget
+
+
+
+ 0
+ 0
+ 479
+ 76
+
+
+
+
+ 0
+ 0
+
+
+
+ Form
+
+
+
+
+
+
diff --git a/src/plugins/ios/iosdevice.cpp b/src/plugins/ios/iosdevice.cpp
new file mode 100644
index 00000000000..853328a0ff6
--- /dev/null
+++ b/src/plugins/ios/iosdevice.cpp
@@ -0,0 +1,519 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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 "iosdevice.h"
+#include "iosconstants.h"
+#include "iosconfigurations.h"
+#include "iostoolhandler.h"
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+using namespace ProjectExplorer;
+
+static bool debugDeviceDetection = false;
+
+namespace {
+QString CFStringRef2QString(CFStringRef s)
+{
+ unsigned char buf[250];
+ CFIndex len = CFStringGetLength(s);
+ CFIndex usedBufLen;
+ CFIndex converted = CFStringGetBytes(s, CFRangeMake(0,len), kCFStringEncodingUTF8,
+ '?', false, &buf[0], sizeof(buf), &usedBufLen);
+ if (converted == len)
+ return QString::fromUtf8(reinterpret_cast(&buf[0]), usedBufLen);
+ size_t bufSize = sizeof(buf)
+ + CFStringGetMaximumSizeForEncoding(len - converted, kCFStringEncodingUTF8);
+ unsigned char *bigBuf = new unsigned char[bufSize];
+ memcpy(bigBuf, buf, usedBufLen);
+ CFIndex newUseBufLen;
+ CFStringGetBytes(s, CFRangeMake(converted,len), kCFStringEncodingUTF8,
+ '?', false, &bigBuf[usedBufLen], bufSize, &newUseBufLen);
+ QString res = QString::fromUtf8(reinterpret_cast(bigBuf), usedBufLen + newUseBufLen);
+ delete[] bigBuf;
+ return res;
+}
+
+}
+
+namespace Ios {
+namespace Internal {
+
+const char extraInfoKey[] = "extraInfo";
+
+IosDevice::IosDevice()
+ : IDevice(Core::Id(Constants::IOS_DEVICE_TYPE),
+ IDevice::AutoDetected,
+ IDevice::Hardware,
+ Constants::IOS_DEVICE_ID)
+{
+ setDisplayName(QCoreApplication::translate("Ios::Internal::IosDevice", "iOS Device"));
+ setDeviceState(DeviceStateUnknown);
+}
+
+IosDevice::IosDevice(const IosDevice &other)
+ : IDevice(other), m_extraInfo(other.m_extraInfo), m_ignoreDevice(other.m_ignoreDevice)
+{ }
+
+IosDevice::IosDevice(const QString &uid)
+ : IDevice(Core::Id(Constants::IOS_DEVICE_TYPE),
+ IDevice::AutoDetected,
+ IDevice::Hardware,
+ Core::Id(Constants::IOS_DEVICE_ID).withSuffix(uid))
+{
+ setDisplayName(QCoreApplication::translate("Ios::Internal::IosDevice", "iOS Device"));
+ setDeviceState(DeviceStateUnknown);
+}
+
+
+IDevice::DeviceInfo IosDevice::deviceInformation() const
+{
+ IDevice::DeviceInfo res;
+ QMapIterator i(m_extraInfo);
+ while (i.hasNext()) {
+ i.next();
+ IosDeviceManager::TranslationMap tMap = IosDeviceManager::translationMap();
+ if (tMap.contains(i.key()))
+ res.append(DeviceInfoItem(tMap.value(i.key()), tMap.value(i.value(), i.value())));
+ }
+ return res;
+}
+
+QString IosDevice::displayType() const
+{
+ return QCoreApplication::translate("Ios::Internal::IosDevice", "iOS");
+}
+
+IDeviceWidget *IosDevice::createWidget()
+{
+ return 0;
+}
+
+QList IosDevice::actionIds() const
+{
+ return QList(); // add activation action?
+}
+
+QString IosDevice::displayNameForActionId(Core::Id actionId) const
+{
+ Q_UNUSED(actionId)
+ return QString();
+}
+
+void IosDevice::executeAction(Core::Id actionId, QWidget *parent)
+{
+ Q_UNUSED(actionId)
+ Q_UNUSED(parent)
+}
+
+DeviceProcessSignalOperation::Ptr IosDevice::signalOperation() const
+{
+ return DeviceProcessSignalOperation::Ptr();
+}
+
+IDevice::Ptr IosDevice::clone() const
+{
+ return IDevice::Ptr(new IosDevice(*this));
+}
+
+void IosDevice::fromMap(const QVariantMap &map)
+{
+ IDevice::fromMap(map);
+ QVariantMap vMap = map.value(QLatin1String(extraInfoKey)).toMap();
+ QMapIterator i(vMap);
+ m_extraInfo.clear();
+ while (i.hasNext()) {
+ i.next();
+ m_extraInfo.insert(i.key(), i.value().toString());
+ }
+}
+
+QVariantMap IosDevice::toMap() const
+{
+ QVariantMap res = IDevice::toMap();
+ QVariantMap vMap;
+ QMapIterator i(m_extraInfo);
+ while (i.hasNext()) {
+ i.next();
+ vMap.insert(i.key(), i.value());
+ }
+ res.insert(QLatin1String(extraInfoKey), vMap);
+ return res;
+}
+
+QString IosDevice::uniqueDeviceID() const
+{
+ return id().suffixAfter(Core::Id(Constants::IOS_DEVICE_ID));
+}
+/*
+// add back?
+
+QString IosDevice::cpuArchitecure() const
+{
+ return m_extraInfo.value(QLatin1String("deviceInfo")).toMap()
+ .value(QLatin1String("CPUArchitecture")).toString();
+}
+
+QString IosDevice::productType() const
+{
+ return m_extraInfo.value(QLatin1String("deviceInfo")).toMap()
+ .value(QLatin1String("ProductType")).toString();
+}*/
+
+
+// IosDeviceManager
+
+IosDeviceManager::TranslationMap IosDeviceManager::translationMap()
+{
+ static TranslationMap *translationMap = 0;
+ if (translationMap)
+ return *translationMap;
+ TranslationMap &tMap = *new TranslationMap;
+ tMap[QLatin1String("deviceName")] = tr("Device name");
+ tMap[QLatin1String("developerStatus")] = tr("Developer status");
+ tMap[QLatin1String("deviceConnected")] = tr("Connected");
+ tMap[QLatin1String("YES")] = tr("yes");
+ tMap[QLatin1String("NO")] = tr("no");
+ tMap[QLatin1String("YES")] = tr("yes");
+ tMap[QLatin1String("*unknown*")] = tr("unknown");
+ translationMap = &tMap;
+ return tMap;
+}
+
+void IosDeviceManager::deviceConnected(const QString &uid, const QString &name)
+{
+ DeviceManager *devManager = DeviceManager::instance();
+ Core::Id baseDevId(Constants::IOS_DEVICE_ID);
+ Core::Id devType(Constants::IOS_DEVICE_TYPE);
+ Core::Id devId = baseDevId.withSuffix(uid);
+ IDevice::ConstPtr dev = devManager->find(devId);
+ if (dev.isNull()) {
+ IosDevice *newDev = new IosDevice(uid);
+ if (!name.isNull())
+ newDev->setDisplayName(name);
+ if (debugDeviceDetection)
+ qDebug() << "adding ios device " << uid;
+ devManager->addDevice(IDevice::ConstPtr(newDev));
+ } else if (dev->deviceState() != IDevice::DeviceConnected &&
+ dev->deviceState() != IDevice::DeviceReadyToUse) {
+ if (debugDeviceDetection)
+ qDebug() << "updating ios device " << uid;
+ IosDevice *newDev = 0;
+ if (dev->type() == devType) {
+ const IosDevice *iosDev = static_cast(dev.data());
+ newDev = new IosDevice(*iosDev);
+ } else {
+ newDev = new IosDevice(uid);
+ }
+ devManager->addDevice(IDevice::ConstPtr(newDev));
+ }
+ updateInfo(uid);
+}
+
+void IosDeviceManager::deviceDisconnected(const QString &uid)
+{
+ if (debugDeviceDetection)
+ qDebug() << "detected disconnection of ios device " << uid;
+ DeviceManager *devManager = DeviceManager::instance();
+ Core::Id baseDevId(Constants::IOS_DEVICE_ID);
+ Core::Id devType(Constants::IOS_DEVICE_TYPE);
+ Core::Id devId = baseDevId.withSuffix(uid);
+ IDevice::ConstPtr dev = devManager->find(devId);
+ if (dev.isNull() || dev->type() != devType) {
+ qDebug() << "ignoring disconnection of ios device " << uid; // should neve happen
+ } else {
+ const IosDevice *iosDev = static_cast(dev.data());
+ if (iosDev->deviceState() != IDevice::DeviceDisconnected) {
+ if (debugDeviceDetection)
+ qDebug() << "disconnecting device " << iosDev->uniqueDeviceID();
+ devManager->setDeviceState(iosDev->id(), IDevice::DeviceDisconnected);
+ }
+ }
+}
+
+void IosDeviceManager::updateInfo(const QString &devId)
+{
+ IosToolHandler *requester = new IosToolHandler(IosToolHandler::IosDeviceType, this);
+ connect(requester, SIGNAL(deviceInfo(Ios::IosToolHandler*,QString,Ios::IosToolHandler::Dict)),
+ SLOT(deviceInfo(Ios::IosToolHandler *,QString,Ios::IosToolHandler::Dict)));
+ connect(requester, SIGNAL(finished(Ios::IosToolHandler*)),
+ SLOT(infoGathererFinished(Ios::IosToolHandler*)));
+ requester->requestDeviceInfo(devId);
+}
+
+void IosDeviceManager::deviceInfo(IosToolHandler *, const QString &uid,
+ const Ios::IosToolHandler::Dict &info)
+{
+ DeviceManager *devManager = DeviceManager::instance();
+ Core::Id baseDevId(Constants::IOS_DEVICE_ID);
+ Core::Id devType(Constants::IOS_DEVICE_TYPE);
+ Core::Id devId = baseDevId.withSuffix(uid);
+ IDevice::ConstPtr dev = devManager->find(devId);
+ bool skipUpdate = false;
+ IosDevice *newDev = 0;
+ if (!dev.isNull() && dev->type() == devType) {
+ const IosDevice *iosDev = static_cast(dev.data());
+ if (iosDev->m_extraInfo == info) {
+ skipUpdate = true;
+ newDev = const_cast(iosDev);
+ } else {
+ newDev = new IosDevice(*iosDev);
+ }
+ } else {
+ newDev = new IosDevice(uid);
+ }
+ if (!skipUpdate) {
+ QString devNameKey = QLatin1String("deviceName");
+ if (info.contains(devNameKey))
+ newDev->setDisplayName(info.value(devNameKey));
+ newDev->m_extraInfo = info;
+ if (debugDeviceDetection)
+ qDebug() << "updated info of ios device " << uid;
+ dev = IDevice::ConstPtr(newDev);
+ devManager->addDevice(dev);
+ }
+ QLatin1String devStatusKey = QLatin1String("developerStatus");
+ if (info.contains(devStatusKey)) {
+ QString devStatus = info.value(devStatusKey);
+ if (devStatus == QLatin1String("*off*")) {
+ devManager->setDeviceState(newDev->id(), IDevice::DeviceConnected);
+ if (!newDev->m_ignoreDevice && !IosConfigurations::instance().config().ignoreAllDevices) {
+ QMessageBox mBox;
+ mBox.setText(tr("An iOS device in user mode has been detected."));
+ mBox.setInformativeText(tr("Do you want to see how to set it up for development?"));
+ mBox.setStandardButtons(QMessageBox::NoAll | QMessageBox::No | QMessageBox::Yes);
+ mBox.setDefaultButton(QMessageBox::No);
+ int ret = mBox.exec();
+ switch (ret) {
+ case QMessageBox::Yes:
+ // open doc
+ break;
+ case QMessageBox::No:
+ newDev->m_ignoreDevice = true;
+ break;
+ case QMessageBox::NoAll:
+ {
+ IosConfig conf = IosConfigurations::instance().config();
+ conf.ignoreAllDevices = true;
+ IosConfigurations::instance().setConfig(conf);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ } else if (devStatus == QLatin1String("Development")) {
+ devManager->setDeviceState(newDev->id(), IDevice::DeviceReadyToUse);
+ } else {
+ devManager->setDeviceState(newDev->id(), IDevice::DeviceConnected);
+ }
+ }
+}
+
+void IosDeviceManager::infoGathererFinished(IosToolHandler *gatherer)
+{
+ gatherer->deleteLater();
+}
+
+namespace {
+io_iterator_t gAddedIter;
+io_iterator_t gRemovedIter;
+
+extern "C" {
+void deviceConnectedCallback(void *refCon, io_iterator_t iterator)
+{
+ kern_return_t kr;
+ io_service_t usbDevice;
+ (void) refCon;
+
+ while ((usbDevice = IOIteratorNext(iterator))) {
+ io_name_t deviceName;
+
+ // Get the USB device's name.
+ kr = IORegistryEntryGetName(usbDevice, deviceName);
+ QString name;
+ if (KERN_SUCCESS == kr)
+ name = QString::fromLocal8Bit(deviceName);
+ if (debugDeviceDetection)
+ qDebug() << "ios device " << name << " in deviceAddedCallback";
+
+ CFStringRef cfUid = static_cast(IORegistryEntryCreateCFProperty(
+ usbDevice,
+ CFSTR(kUSBSerialNumberString),
+ kCFAllocatorDefault, 0));
+ QString uid = CFStringRef2QString(cfUid);
+ CFRelease(cfUid);
+ IosDeviceManager::instance()->deviceConnected(uid, name);
+
+ // Done with this USB device; release the reference added by IOIteratorNext
+ kr = IOObjectRelease(usbDevice);
+ }
+}
+
+void deviceDisconnectedCallback(void *refCon, io_iterator_t iterator)
+{
+ kern_return_t kr;
+ io_service_t usbDevice;
+ (void) refCon;
+
+ while ((usbDevice = IOIteratorNext(iterator))) {
+ io_name_t deviceName;
+
+ // Get the USB device's name.
+ kr = IORegistryEntryGetName(usbDevice, deviceName);
+ if (KERN_SUCCESS != kr)
+ deviceName[0] = '\0';
+ if (debugDeviceDetection)
+ qDebug() << "ios device " << deviceName << " in deviceDisconnectedCallback";
+
+ {
+ CFStringRef cfUid = static_cast(IORegistryEntryCreateCFProperty(
+ usbDevice,
+ CFSTR(kUSBSerialNumberString),
+ kCFAllocatorDefault, 0));
+ QString uid = CFStringRef2QString(cfUid);
+ CFRelease(cfUid);
+ IosDeviceManager::instance()->deviceDisconnected(uid);
+ }
+
+ // Done with this USB device; release the reference added by IOIteratorNext
+ kr = IOObjectRelease(usbDevice);
+ }
+}
+
+} // extern C
+
+} // anonymous namespace
+
+void IosDeviceManager::monitorAvailableDevices()
+{
+ CFMutableDictionaryRef matchingDictionary =
+ IOServiceMatching("IOUSBDevice" );
+ {
+ UInt32 vendorId = 0x05ac;
+ CFNumberRef cfVendorValue = CFNumberCreate( kCFAllocatorDefault, kCFNumberSInt32Type,
+ &vendorId );
+ CFDictionaryAddValue( matchingDictionary, CFSTR( kUSBVendorID ), cfVendorValue);
+ CFRelease( cfVendorValue );
+ UInt32 productId = 0x1280;
+ CFNumberRef cfProductIdValue = CFNumberCreate( kCFAllocatorDefault, kCFNumberSInt32Type,
+ &productId );
+ CFDictionaryAddValue( matchingDictionary, CFSTR( kUSBProductID ), cfProductIdValue);
+ CFRelease( cfProductIdValue );
+ UInt32 productIdMask = 0xFFC0;
+ CFNumberRef cfProductIdMaskValue = CFNumberCreate( kCFAllocatorDefault, kCFNumberSInt32Type,
+ &productIdMask );
+ CFDictionaryAddValue( matchingDictionary, CFSTR( kUSBProductIDMask ), cfProductIdMaskValue);
+ CFRelease( cfProductIdMaskValue );
+ }
+
+ IONotificationPortRef notificationPort = IONotificationPortCreate(kIOMasterPortDefault);
+ CFRunLoopSourceRef runLoopSource = IONotificationPortGetRunLoopSource(notificationPort);
+
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopDefaultMode);
+
+ // IOServiceAddMatchingNotification releases this, so we retain for the next call
+ CFRetain(matchingDictionary);
+
+ // Now set up a notification to be called when a device is first matched by I/O Kit.
+ kern_return_t kr;
+ kr = IOServiceAddMatchingNotification(notificationPort,
+ kIOMatchedNotification,
+ matchingDictionary,
+ deviceConnectedCallback,
+ NULL,
+ &gAddedIter);
+
+
+ kr = IOServiceAddMatchingNotification(notificationPort,
+ kIOTerminatedNotification,
+ matchingDictionary,
+ deviceDisconnectedCallback,
+ NULL,
+ &gRemovedIter);
+
+ // Iterate once to get already-present devices and arm the notification
+ deviceConnectedCallback(NULL, gAddedIter);
+ deviceDisconnectedCallback(NULL, gRemovedIter);
+
+}
+
+
+IosDeviceManager::IosDeviceManager(QObject *parent) :
+ QObject(parent)
+{
+}
+
+IosDeviceManager *IosDeviceManager::instance()
+{
+ static IosDeviceManager obj;
+ return &obj;
+}
+
+void IosDeviceManager::updateAvailableDevices(const QStringList &devices)
+{
+ foreach (const QString &uid, devices)
+ deviceConnected(uid);
+
+ DeviceManager *devManager = DeviceManager::instance();
+ for (int iDevice = 0; iDevice < devManager->deviceCount(); ++iDevice) {
+ IDevice::ConstPtr dev = devManager->deviceAt(iDevice);
+ Core::Id devType(Constants::IOS_DEVICE_TYPE);
+ if (dev.isNull() || dev->type() != devType)
+ continue;
+ const IosDevice *iosDev = static_cast(dev.data());
+ if (devices.contains(iosDev->uniqueDeviceID()))
+ continue;
+ if (iosDev->deviceState() != IDevice::DeviceDisconnected) {
+ if (debugDeviceDetection)
+ qDebug() << "disconnecting device " << iosDev->uniqueDeviceID();
+ devManager->setDeviceState(iosDev->id(), IDevice::DeviceDisconnected);
+ }
+ }
+}
+
+IosDevice::ConstPtr IosKitInformation::device(Kit *kit)
+{
+ if (!kit)
+ return IosDevice::ConstPtr();
+ ProjectExplorer::IDevice::ConstPtr dev = ProjectExplorer::DeviceKitInformation::device(kit);
+ IosDevice::ConstPtr res = dev.dynamicCast();
+ return res;
+}
+
+} // namespace Internal
+} // namespace Ios
diff --git a/src/plugins/ios/iosdevice.h b/src/plugins/ios/iosdevice.h
new file mode 100644
index 00000000000..f8801ffbf52
--- /dev/null
+++ b/src/plugins/ios/iosdevice.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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 IOSDEVICE_H
+#define IOSDEVICE_H
+
+#include
+#include
+#include
+#include
+#include "iostoolhandler.h"
+#include
+
+namespace ProjectExplorer{
+class Kit;
+}
+namespace Ios {
+class IosConfigurations;
+
+namespace Internal {
+class IosDeviceManager;
+
+class IosDevice : public ProjectExplorer::IDevice
+{
+public:
+ typedef QMap Dict;
+ typedef QSharedPointer ConstPtr;
+ typedef QSharedPointer Ptr;
+
+ ProjectExplorer::IDevice::DeviceInfo deviceInformation() const;
+ ProjectExplorer::IDeviceWidget *createWidget();
+ QList actionIds() const;
+ QString displayNameForActionId(Core::Id actionId) const;
+ void executeAction(Core::Id actionId, QWidget *parent = 0);
+ ProjectExplorer::DeviceProcessSignalOperation::Ptr signalOperation() const;
+ QString displayType() const;
+
+ ProjectExplorer::IDevice::Ptr clone() const;
+ void fromMap(const QVariantMap &map);
+ QVariantMap toMap() const;
+ QString uniqueDeviceID() const;
+ IosDevice(const QString &uid);
+ // add back? currently unused...
+ //QString cpuArchitecure() const;
+ //QString productType() const;
+protected:
+ friend class IosDeviceFactory;
+ friend class Ios::Internal::IosDeviceManager;
+ IosDevice();
+ IosDevice(const IosDevice &other);
+ Dict m_extraInfo;
+ bool m_ignoreDevice;
+};
+
+class IosDeviceManager : public QObject {
+ Q_OBJECT
+public:
+ typedef QHash TranslationMap;
+
+ static TranslationMap translationMap();
+ static IosDeviceManager *instance();
+
+ void updateAvailableDevices(const QStringList &devices);
+ void deviceConnected(const QString &uid, const QString &name = QString());
+ void deviceDisconnected(const QString &uid);
+ friend class IosConfigurations;
+public slots:
+ void updateInfo(const QString &devId);
+//private slots:
+ void deviceInfo(Ios::IosToolHandler *gatherer, const QString &deviceId,
+ const Ios::IosToolHandler::Dict &info);
+ void infoGathererFinished(Ios::IosToolHandler *gatherer);
+ void monitorAvailableDevices();
+private:
+ IosDeviceManager(QObject *parent = 0);
+};
+
+namespace IosKitInformation {
+IosDevice::ConstPtr device(ProjectExplorer::Kit *);
+}
+
+} // namespace Internal
+
+} // namespace Ios
+
+#endif // IOSDEVICE_H
diff --git a/src/plugins/ios/iosdevicefactory.cpp b/src/plugins/ios/iosdevicefactory.cpp
new file mode 100644
index 00000000000..980e8ea4126
--- /dev/null
+++ b/src/plugins/ios/iosdevicefactory.cpp
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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 "iosdevicefactory.h"
+#include "iosdevice.h"
+
+#include "iosconstants.h"
+
+namespace Ios {
+namespace Internal {
+
+IosDeviceFactory::IosDeviceFactory()
+{
+ setObjectName(QLatin1String("IosDeviceFactory"));
+}
+
+QString IosDeviceFactory::displayNameForId(Core::Id type) const
+{
+ if (type == Constants::IOS_DEVICE_TYPE)
+ return tr("iOS Device");
+ return QString();
+}
+
+QList IosDeviceFactory::availableCreationIds() const
+{
+ return QList() << Core::Id(Constants::IOS_DEVICE_TYPE);
+}
+
+bool IosDeviceFactory::canCreate() const
+{
+ return false;
+}
+
+ProjectExplorer::IDevice::Ptr IosDeviceFactory::create(Core::Id id) const
+{
+ Q_UNUSED(id)
+ return ProjectExplorer::IDevice::Ptr();
+}
+
+bool IosDeviceFactory::canRestore(const QVariantMap &map) const
+{
+ return ProjectExplorer::IDevice::typeFromMap(map) == Constants::IOS_DEVICE_TYPE;
+}
+
+ProjectExplorer::IDevice::Ptr IosDeviceFactory::restore(const QVariantMap &map) const
+{
+ IosDevice *newDev = new IosDevice;
+ newDev->fromMap(map);
+ // updating the active ones should be enough...
+ //IosDeviceManager::instance()->updateInfo(newDev->uniqueDeviceID());
+ return ProjectExplorer::IDevice::Ptr(newDev);
+}
+
+} // namespace Internal
+} // namespace Ios
diff --git a/src/plugins/ios/iosdevicefactory.h b/src/plugins/ios/iosdevicefactory.h
new file mode 100644
index 00000000000..c77ecc74838
--- /dev/null
+++ b/src/plugins/ios/iosdevicefactory.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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 IOSDEVICEFACTORY_H
+#define IOSDEVICEFACTORY_H
+
+#include
+#include
+#include
+#include
+
+namespace Ios {
+namespace Internal {
+
+class IosDeviceFactory : public ProjectExplorer::IDeviceFactory
+{
+ Q_OBJECT
+public:
+ IosDeviceFactory();
+
+ QString displayNameForId(Core::Id type) const;
+ QList availableCreationIds() const;
+
+ bool canCreate() const;
+ ProjectExplorer::IDevice::Ptr create(Core::Id id) const;
+ bool canRestore(const QVariantMap &map) const;
+ ProjectExplorer::IDevice::Ptr restore(const QVariantMap &map) const;
+};
+
+} // namespace Internal
+} // namespace Ios
+
+#endif // IOSDEVICEFACTORY_H
diff --git a/src/plugins/ios/iosmanager.cpp b/src/plugins/ios/iosmanager.cpp
new file mode 100644
index 00000000000..4f25cba3b9c
--- /dev/null
+++ b/src/plugins/ios/iosmanager.cpp
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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 "iosmanager.h"
+#include "iosconfigurations.h"
+#include "iosrunconfiguration.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+using namespace Qt4ProjectManager;
+using namespace ProjectExplorer;
+
+namespace Ios {
+namespace Internal {
+
+bool IosManager::supportsIos(ProjectExplorer::Target *target)
+{
+ if (!qobject_cast(target->project()))
+ return false;
+ QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target->kit());
+ return version && version->type() == QLatin1String(Ios::Constants::IOSQT);
+}
+
+QString IosManager::resDirForTarget(Target *target)
+{
+ Qt4BuildConfiguration *bc =
+ qobject_cast(target->activeBuildConfiguration());
+ return bc->buildDirectory().toString();
+}
+
+} // namespace Internal
+} // namespace Qt4ProjectManager
diff --git a/src/plugins/ios/iosmanager.h b/src/plugins/ios/iosmanager.h
new file mode 100644
index 00000000000..83f1c58a02b
--- /dev/null
+++ b/src/plugins/ios/iosmanager.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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 IOSMANAGER_H
+#define IOSMANAGER_H
+
+#include
+
+#include
+#include
+#include
+
+namespace ProjectExplorer { class Target; }
+
+namespace Ios {
+namespace Internal {
+
+class IosManager : public QObject
+{
+ Q_OBJECT
+
+public:
+ static bool supportsIos(ProjectExplorer::Target *target);
+ static QString resDirForTarget(ProjectExplorer::Target *target);
+};
+
+} // namespace Internal
+} // namespace Ios
+
+#endif // IOSMANAGER_H
diff --git a/src/plugins/ios/iosplugin.cpp b/src/plugins/ios/iosplugin.cpp
new file mode 100644
index 00000000000..c4eb2325750
--- /dev/null
+++ b/src/plugins/ios/iosplugin.cpp
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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 "iosplugin.h"
+
+#include "iosconstants.h"
+#include "iosconfigurations.h"
+#include "iosdevicefactory.h"
+#include "iossimulator.h"
+#include "iossimulatorfactory.h"
+#include "iosconfigurations.h"
+#include "iosmanager.h"
+#include "iosrunfactories.h"
+#include "iossettingspage.h"
+#include "iosqtversionfactory.h"
+#include "iosbuildstep.h"
+#include "iosdeploystepfactory.h"
+#include "iosdeployconfiguration.h"
+#include
+#include
+
+#include
+
+#include
+
+namespace Ios {
+
+IosPlugin::IosPlugin()
+{ }
+
+bool IosPlugin::initialize(const QStringList &arguments, QString *errorMessage)
+{
+ Q_UNUSED(arguments);
+ Q_UNUSED(errorMessage);
+
+ Internal::IosConfigurations::instance();
+
+ addAutoReleasedObject(new Internal::IosRunControlFactory);
+ addAutoReleasedObject(new Internal::IosRunConfigurationFactory);
+ addAutoReleasedObject(new Internal::IosSettingsPage);
+ addAutoReleasedObject(new Internal::IosQtVersionFactory);
+ addAutoReleasedObject(new Internal::IosDeviceFactory);
+ addAutoReleasedObject(new Internal::IosSimulatorFactory);
+ addAutoReleasedObject(new Internal::IosBuildStepFactory);
+ addAutoReleasedObject(new Internal::IosDeployStepFactory);
+ addAutoReleasedObject(new Internal::IosDeployConfigurationFactory);
+ //ProjectExplorer::KitManager::instance()->registerKitInformation(new Internal::IosGdbServerKitInformation);
+ return true;
+}
+
+void IosPlugin::extensionsInitialized()
+{
+ connect(ProjectExplorer::KitManager::instance(), SIGNAL(kitsLoaded()),
+ this, SLOT(kitsRestored()));
+}
+
+void IosPlugin::kitsRestored()
+{
+ disconnect(ProjectExplorer::KitManager::instance(), SIGNAL(kitsLoaded()),
+ this, SLOT(kitsRestored()));
+ Internal::IosConfigurations::instance().updateAutomaticKitList();
+ connect(QtSupport::QtVersionManager::instance(),
+ SIGNAL(qtVersionsChanged(QList,QList,QList)),
+ &Internal::IosConfigurations::instance(),
+ SLOT(updateAutomaticKitList()));
+}
+
+} // namespace Ios
+
+Q_EXPORT_PLUGIN(Ios::IosPlugin)
diff --git a/src/plugins/ios/iosplugin.h b/src/plugins/ios/iosplugin.h
new file mode 100644
index 00000000000..832343919e2
--- /dev/null
+++ b/src/plugins/ios/iosplugin.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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 IOSPLUGIN_H
+#define IOSPLUGIN_H
+
+#include
+
+namespace Ios {
+
+class IosPlugin : public ExtensionSystem::IPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Ios.json")
+
+public:
+ IosPlugin();
+
+ bool initialize(const QStringList &arguments, QString *errorMessage);
+ void extensionsInitialized();
+private slots:
+ void kitsRestored();
+};
+
+} // namespace Ios
+
+#endif // IOSPLUGIN_H
diff --git a/src/plugins/ios/iosprobe.cpp b/src/plugins/ios/iosprobe.cpp
new file mode 100644
index 00000000000..318220cb8d8
--- /dev/null
+++ b/src/plugins/ios/iosprobe.cpp
@@ -0,0 +1,355 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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 "iosprobe.h"
+#include
+#include
+#include
+#include
+#include
+
+static const bool debugProbe = false;
+
+namespace Ios {
+
+static QString qsystem(const QString &exe, const QStringList &args = QStringList())
+{
+ QProcess p;
+ p.setProcessChannelMode(QProcess::MergedChannels);
+ p.start(exe, args);
+ p.waitForFinished();
+ return QString::fromLocal8Bit(p.readAll());
+}
+
+QMap IosProbe::detectPlatforms(const QString &devPath)
+{
+ IosProbe probe;
+ probe.addDeveloperPath(devPath);
+ probe.detectAll();
+ return probe.detectedPlatforms();
+}
+
+int IosProbe::compareVersions(const QString &v1, const QString &v2)
+{
+ QStringList v1L = v1.split(QLatin1Char('.'));
+ QStringList v2L = v2.split(QLatin1Char('.'));
+ int i = 0;
+ while (v1.length() > i && v1.length() > i) {
+ bool n1Ok, n2Ok;
+ int n1 = v1L.value(i).toInt(&n1Ok);
+ int n2 = v2L.value(i).toInt(&n2Ok);
+ if (!(n1Ok && n2Ok)) {
+ qDebug() << QString::fromLatin1("Failed to compare version %1 and %2").arg(v1,v2);
+ return 0;
+ }
+ if (n1 > n2)
+ return -1;
+ else if (n1 < n2)
+ return 1;
+ ++i;
+ }
+ if (v1.length() > v2.length())
+ return -1;
+ if (v1.length() < v2.length())
+ return 1;
+ return 0;
+}
+
+bool IosProbe::addDeveloperPath(const QString &path)
+{
+ if (path.isEmpty())
+ return false;
+ QFileInfo pInfo(path);
+ if (!pInfo.exists() || !pInfo.isDir())
+ return false;
+ if (m_developerPaths.contains(path))
+ return false;
+ m_developerPaths.append(path);
+ if (debugProbe)
+ qDebug() << QString::fromLatin1("Added developer path %1").arg(path);
+ return true;
+}
+
+void IosProbe::detectDeveloperPaths()
+{
+ QProcess selectedXcode;
+ QString program = QLatin1String("/usr/bin/xcode-select");
+ QStringList arguments(QLatin1String("--print-path"));
+ selectedXcode.start(program, arguments, QProcess::ReadOnly);
+ if (!selectedXcode.waitForFinished() || selectedXcode.exitCode()) {
+ qDebug() << QString::fromLatin1("Could not detect selected xcode with /usr/bin/xcode-select");
+ } else {
+ QString path = QString::fromLocal8Bit(selectedXcode.readAllStandardOutput());
+ addDeveloperPath(path);
+ }
+ addDeveloperPath(QLatin1String("/Applications/Xcode.app/Contents/Developer"));
+}
+
+void IosProbe::setArch(Platform *platform, const QString &pathToGcc, const QStringList &extraFlags)
+{
+ if (!extraFlags.isEmpty())
+ platform->backendFlags = extraFlags;
+ // setting architecture and endianness only here, bercause the same compiler
+ // can support several ones
+ QStringList flags(extraFlags);
+ flags << QLatin1String("-dumpmachine");
+ QString compilerTriplet = qsystem(pathToGcc, flags).simplified();
+ QStringList compilerTripletl = compilerTriplet.split(QLatin1Char('-'));
+ if (compilerTripletl.count() < 2) {
+ qDebug() << QString::fromLatin1("Detected '%1', but I don't understand "
+ "its architecture '%2'.")
+ .arg(pathToGcc, compilerTriplet);
+ return;
+ }
+
+ QString endianness, architecture;
+ architecture = compilerTripletl.at(0);
+ endianness = QLatin1String("little");
+
+ if (debugProbe)
+ qDebug() << QString::fromLatin1(" Toolchain %1 detected:\n"
+ " binary: %2\n"
+ " triplet: %3\n"
+ " arch: %4").arg(platform->name, pathToGcc,
+ compilerTriplet, architecture);
+
+ platform->architecture = architecture;
+}
+
+void IosProbe::setupDefaultToolchains(const QString &devPath, const QString &xCodeName)
+{
+ if (debugProbe)
+ qDebug() << QString::fromLatin1("Setting up platform '%1'.").arg(xCodeName);
+ QString indent = QLatin1String(" ");
+
+ // detect clang (default toolchain)
+ QFileInfo clangFileInfo(devPath
+ + QLatin1String("/Toolchains/XcodeDefault.xctoolchain/usr/bin")
+ + QLatin1String("/clang++"));
+ bool hasClang = clangFileInfo.exists();
+ QSettingsPtr toolchainInfo;
+ if (hasClang)
+ toolchainInfo = QSettingsPtr(new QSettings(
+ devPath + QLatin1String("/Toolchains/XcodeDefault.xctoolchain/ToolchainInfo.plist")
+ , QSettings::NativeFormat));
+ else
+ qDebug() << indent << QString::fromLatin1("Default toolchain %1 not found.")
+ .arg(clangFileInfo.canonicalFilePath());
+ // Platforms
+ QDir platformsDir(devPath + QLatin1String("/Platforms"));
+ QFileInfoList platforms = platformsDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
+ foreach (const QFileInfo &fInfo, platforms) {
+ if (fInfo.isDir() && fInfo.suffix() == QLatin1String("platform")) {
+ if (debugProbe)
+ qDebug() << indent << QString::fromLatin1("Setting up %1").arg(fInfo.fileName());
+ QSettingsPtr infoSettings(new QSettings(
+ fInfo.absoluteFilePath() + QLatin1String("/Info.plist")
+ , QSettings::NativeFormat));
+ if (!infoSettings->contains(QLatin1String("Name"))) {
+ qDebug() << indent << QString::fromLatin1("Missing platform name in Info.plist of %1")
+ .arg(fInfo.absoluteFilePath());
+ continue;
+ }
+ QString targetOS;
+ QString name = infoSettings->value(QLatin1String("Name")).toString();
+ if (name != QLatin1String("macosx") && name != QLatin1String("iphoneos")
+ && name != QLatin1String("iphonesimulator"))
+ {
+ qDebug() << indent << QString::fromLatin1("Skipping unknown platform %1").arg(name);
+ continue;
+ }
+
+ // prepare default platform properties
+ QVariantMap defaultProp = infoSettings->value(QLatin1String("DefaultProperties"))
+ .toMap();
+ QVariantMap overrideProp = infoSettings->value(QLatin1String("OverrideProperties"))
+ .toMap();
+ QMapIterator i(overrideProp);
+ while (i.hasNext()) {
+ i.next();
+ // use unite? might lead to double insertions...
+ defaultProp[i.key()] = i.value();
+ }
+
+ QString clangFullName = name + QLatin1String("-clang") + xCodeName;
+ QString clang11FullName = name + QLatin1String("-clang11") + xCodeName;
+ // detect gcc
+ QFileInfo gccFileInfo(fInfo.absoluteFilePath() + QLatin1String("/Developer/usr/bin/g++"));
+ QString gccFullName = name + QLatin1String("-gcc") + xCodeName;
+ if (!gccFileInfo.exists())
+ gccFileInfo = QFileInfo(devPath + QLatin1String("/usr/bin/g++"));
+ bool hasGcc = gccFileInfo.exists();
+
+ QStringList extraFlags;
+ if (defaultProp.contains(QLatin1String("ARCHS"))) {
+ QString arch = defaultProp.value(QLatin1String("ARCHS")).toString();
+ if (arch == QLatin1String("$(NATIVE_ARCH_32_BIT)"))
+ extraFlags << QLatin1String("-arch") << QLatin1String("i386");
+ }
+ if (defaultProp.contains(QLatin1String("NATIVE_ARCH"))) {
+ QString arch = defaultProp.value(QLatin1String("NATIVE_ARCH")).toString();
+ if (!arch.startsWith(QLatin1String("arm")))
+ qDebug() << indent << QString::fromLatin1("Expected arm architecture, not %1").arg(arch);
+ extraFlags << QLatin1String("-arch") << arch;
+ }
+ if (hasClang) {
+ Platform clangProfile;
+ clangProfile.platformKind = 0;
+ clangProfile.name = clangFullName;
+ clangProfile.platformPath = Utils::FileName(fInfo);
+ clangProfile.platformInfo = infoSettings;
+ clangProfile.compilerPath = Utils::FileName(clangFileInfo);
+ setArch(&clangProfile, clangFileInfo.canonicalFilePath(), extraFlags);
+ if (debugProbe)
+ qDebug() << indent << QString::fromLatin1("* adding profile %1").arg(clangProfile.name);
+ this->m_platforms[clangProfile.name] = clangProfile;
+ clangProfile.platformKind |= Platform::Cxx11Support;
+ clangProfile.backendFlags.append(QLatin1String("-std=c++11"));
+ clangProfile.backendFlags.append(QLatin1String("-stdlib=libc++"));
+ clangProfile.name = clang11FullName;
+ this->m_platforms[clangProfile.name] = clangProfile;
+ }
+ if (hasGcc) {
+ Platform gccProfile;
+ gccProfile.name = gccFullName;
+ gccProfile.platformKind = 0;
+ // use the arm-apple-darwin10-llvm-* variant and avoid the extraFlags if available???
+ gccProfile.platformPath = Utils::FileName(fInfo);
+ gccProfile.platformInfo = infoSettings;
+ gccProfile.compilerPath = Utils::FileName(gccFileInfo);
+ setArch(&gccProfile, gccFileInfo.canonicalFilePath(), extraFlags);
+ if (debugProbe)
+ qDebug() << indent << QString::fromLatin1("* adding profile %1").arg(gccProfile.name);
+ this->m_platforms[gccProfile.name] = gccProfile;
+ }
+
+ // set SDKs/sysroot
+ QString sysRoot;
+ QSettingsPtr sdkSettings;
+ {
+ QString sdkName;
+ if (defaultProp.contains(QLatin1String("SDKROOT")))
+ sdkName = defaultProp.value(QLatin1String("SDKROOT")).toString();
+ QString sdkPath;
+ QDir sdks(fInfo.absoluteFilePath() + QLatin1String("/Developer/SDKs"));
+ QString maxVersion;
+ foreach (const QFileInfo &sdkDirInfo, sdks.entryInfoList(QDir::Dirs
+ | QDir::NoDotAndDotDot)) {
+ indent = QLatin1String(" ");
+ QSettingsPtr sdkInfo(new QSettings(sdkDirInfo.absoluteFilePath()
+ + QLatin1String("/SDKSettings.plist")
+ , QSettings::NativeFormat));
+ QString versionStr = sdkInfo->value(QLatin1String("Version")).toString();
+ QVariant currentSdkName = sdkInfo->value(QLatin1String("CanonicalName"));
+ bool isBaseSdk = sdkInfo->value((QLatin1String("isBaseSDK"))).toString()
+ .toLower() != QLatin1String("no");
+ if (!isBaseSdk) {
+ if (debugProbe)
+ qDebug() << indent << QString::fromLatin1("Skipping non base Sdk %1")
+ .arg(currentSdkName.toString());
+ continue;
+ }
+ QString safeName = currentSdkName.toString().replace(QLatin1Char('-'), QLatin1Char('_'))
+ .replace(QRegExp(QLatin1String("[^-a-zA-Z0-9]")),QLatin1String("-"));
+ if (sdkName.isEmpty()) {
+ if (compareVersions(maxVersion,versionStr) > 0) {
+ maxVersion = versionStr;
+ sdkPath = sdkDirInfo.canonicalFilePath();
+ sdkSettings = sdkInfo;
+ }
+ } else if (currentSdkName == sdkName) {
+ sdkPath = sdkDirInfo.canonicalFilePath();
+ sdkSettings = sdkInfo;
+ }
+ if (hasClang){
+ Platform pSdk;
+ pSdk = this->m_platforms[clangFullName];
+ pSdk.name = safeName + QLatin1String("-clang") + xCodeName;
+ pSdk.sdkPath = Utils::FileName(sdkDirInfo);
+ pSdk.sdkSettings = sdkInfo;
+ if (debugProbe)
+ qDebug() << indent << QString::fromLatin1("* adding profile %1").arg(pSdk.name);
+ this->m_platforms[pSdk.name] = pSdk;
+ pSdk.backendFlags.append(QLatin1String("-std=c++11"));
+ pSdk.backendFlags.append(QLatin1String("-stdlib=libc++"));
+ pSdk.name = safeName + QLatin1String("-clang11") + xCodeName;
+ this->m_platforms[pSdk.name] = pSdk;
+ }
+ if (hasGcc) {
+ Platform pSdk;
+ pSdk = this->m_platforms[gccFullName];
+ pSdk.name = safeName + QLatin1String("-gcc") + xCodeName;
+ pSdk.sdkPath = Utils::FileName(sdkDirInfo);
+ pSdk.sdkSettings = sdkInfo;
+ if (debugProbe)
+ qDebug() << indent << QString::fromLatin1("* adding profile %1").arg(pSdk.name);
+ this->m_platforms[pSdk.name] = pSdk;
+ }
+ }
+ if (!sdkPath.isEmpty())
+ sysRoot = sdkPath;
+ else if (!sdkName.isEmpty())
+ qDebug() << indent << QString::fromLatin1("Failed to find sysroot %1").arg(sdkName);
+ }
+ //this->m_platforms.remove(clangFullName);
+ if (hasClang && !sysRoot.isEmpty()) {
+ this->m_platforms[clangFullName].platformKind |= Platform::BasePlatform;
+ this->m_platforms[clangFullName].sdkPath = Utils::FileName::fromString(sysRoot);
+ this->m_platforms[clangFullName].sdkSettings = sdkSettings;
+ this->m_platforms[clang11FullName].platformKind |= Platform::BasePlatform;
+ this->m_platforms[clang11FullName].sdkPath = Utils::FileName::fromString(sysRoot);
+ this->m_platforms[clang11FullName].sdkSettings = sdkSettings;
+ }
+ //this->m_platforms.remove(gccFullName);
+ if (hasGcc && !sysRoot.isEmpty()) {
+ this->m_platforms[gccFullName].platformKind |= Platform::BasePlatform;
+ this->m_platforms[gccFullName].sdkPath = Utils::FileName::fromString(sysRoot);
+ this->m_platforms[gccFullName].sdkSettings = sdkSettings;
+ }
+ }
+ indent = QLatin1String(" ");
+ }
+}
+
+void IosProbe::detectAll()
+{
+ detectDeveloperPaths();
+ QString xcodeName = QLatin1String("");
+ for (int iXcode = 0; iXcode < m_developerPaths.count(); ++iXcode) {
+ setupDefaultToolchains(m_developerPaths.value(iXcode), xcodeName);
+ xcodeName = QString::fromLatin1("-%1").arg(iXcode + 2);
+ }
+}
+
+QMap IosProbe::detectedPlatforms()
+{
+ return m_platforms;
+}
+
+}
diff --git a/src/plugins/ios/iosprobe.h b/src/plugins/ios/iosprobe.h
new file mode 100644
index 00000000000..cc481881b5c
--- /dev/null
+++ b/src/plugins/ios/iosprobe.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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 IOSPROBE_H
+#define IOSPROBE_H
+#include
+#include
+#include
+#include
+#include
+
+namespace Ios {
+
+typedef QSharedPointer QSettingsPtr;
+
+class Platform
+{
+public:
+ enum PlatformKind {
+ BasePlatform = 1 << 0,
+ Cxx11Support = 1 << 1
+ };
+
+ quint32 platformKind;
+ QString name;
+ Utils::FileName developerPath;
+ Utils::FileName platformPath;
+ Utils::FileName sdkPath;
+ Utils::FileName defaultToolchainPath;
+ Utils::FileName compilerPath;
+ QString architecture;
+ QStringList backendFlags;
+ QSettingsPtr platformInfo;
+ QSettingsPtr sdkSettings;
+ QSettingsPtr toolchainInfo;
+};
+
+class IosProbe
+{
+public:
+ static QMap detectPlatforms(const QString &devPath);
+ IosProbe()
+ { }
+
+private:
+ static int compareVersions(const QString &v1, const QString &v2);
+ bool addDeveloperPath(const QString &path);
+ void detectDeveloperPaths();
+ void setArch(Platform *platform, const QString &pathToGcc, const QStringList &extraFlags);
+ void setupDefaultToolchains(const QString &devPath, const QString &xCodeName);
+ void detectAll();
+ QMap detectedPlatforms();
+private:
+ QMap m_platforms;
+ QStringList m_developerPaths;
+};
+} // namespace Ios
+
+#endif // IOSPROBE_H
diff --git a/src/plugins/ios/iosqtversion.cpp b/src/plugins/ios/iosqtversion.cpp
new file mode 100644
index 00000000000..881cc415674
--- /dev/null
+++ b/src/plugins/ios/iosqtversion.cpp
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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 "iosqtversion.h"
+#include "iosconstants.h"
+#include "iosconfigurations.h"
+#include "iosmanager.h"
+
+#include
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+
+using namespace Ios::Internal;
+using namespace ProjectExplorer;
+using namespace Qt4ProjectManager;
+
+IosQtVersion::IosQtVersion()
+ : QtSupport::BaseQtVersion()
+{
+}
+
+IosQtVersion::IosQtVersion(const Utils::FileName &path, bool isAutodetected,
+ const QString &autodetectionSource)
+ : QtSupport::BaseQtVersion(path, isAutodetected, autodetectionSource)
+{
+ setDisplayName(defaultDisplayName(qtVersionString(), path, false));
+}
+
+IosQtVersion *IosQtVersion::clone() const
+{
+ return new IosQtVersion(*this);
+}
+
+QString IosQtVersion::type() const
+{
+ return QLatin1String(Constants::IOSQT);
+}
+
+bool IosQtVersion::isValid() const
+{
+ if (!BaseQtVersion::isValid())
+ return false;
+ if (qtAbis().isEmpty())
+ return false;
+ return true;
+}
+
+QString IosQtVersion::invalidReason() const
+{
+ QString tmp = BaseQtVersion::invalidReason();
+ if (tmp.isEmpty() && qtAbis().isEmpty())
+ return tr("Failed to detect the ABIs used by the Qt version.");
+ return tmp;
+}
+
+QList IosQtVersion::detectQtAbis() const
+{
+ QList abis = qtAbisFromLibrary(qtCorePath(versionInfo(), qtVersionString()));
+ for (int i = 0; i < abis.count(); ++i) {
+ abis[i] = Abi(abis.at(i).architecture(),
+ abis.at(i).os(),
+ ProjectExplorer::Abi::GenericMacFlavor,
+ abis.at(i).binaryFormat(),
+ abis.at(i).wordWidth());
+ }
+ return abis;
+}
+
+void IosQtVersion::addToEnvironment(const ProjectExplorer::Kit *k, Utils::Environment &env) const
+{
+ Q_UNUSED(k);
+ Q_UNUSED(env);
+}
+
+QString IosQtVersion::description() const
+{
+ //: Qt Version is meant for Ios
+ return tr("iOS");
+}
+
+Core::FeatureSet IosQtVersion::availableFeatures() const
+{
+ Core::FeatureSet features = QtSupport::BaseQtVersion::availableFeatures();
+ features |= Core::FeatureSet(QtSupport::Constants::FEATURE_MOBILE);
+ return features;
+}
+
+QString IosQtVersion::platformName() const
+{
+ return QLatin1String(QtSupport::Constants::IOS_PLATFORM);
+}
+
+QString IosQtVersion::platformDisplayName() const
+{
+ return QLatin1String(QtSupport::Constants::IOS_PLATFORM_TR);
+}
diff --git a/src/plugins/ios/iosqtversion.h b/src/plugins/ios/iosqtversion.h
new file mode 100644
index 00000000000..7c720a05907
--- /dev/null
+++ b/src/plugins/ios/iosqtversion.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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 IOSQTVERSION_H
+#define IOSQTVERSION_H
+
+#include
+
+#include
+
+namespace Ios {
+namespace Internal {
+
+class IosQtVersion : public QtSupport::BaseQtVersion
+{
+ Q_DECLARE_TR_FUNCTIONS(Ios::Internal::IosQtVersion)
+
+public:
+ IosQtVersion();
+ IosQtVersion(const Utils::FileName &path, bool isAutodetected = false,
+ const QString &autodetectionSource = QString());
+
+ IosQtVersion *clone() const;
+ QString type() const;
+ bool isValid() const;
+ QString invalidReason() const;
+
+ QList detectQtAbis() const;
+
+ void addToEnvironment(const ProjectExplorer::Kit *k, Utils::Environment &env) const;
+
+ Core::FeatureSet availableFeatures() const;
+ QString platformName() const;
+ QString platformDisplayName() const;
+
+ QString description() const;
+};
+
+} // namespace Internal
+} // namespace Ios
+
+#endif // IOSQTVERSION_H
diff --git a/src/plugins/ios/iosqtversionfactory.cpp b/src/plugins/ios/iosqtversionfactory.cpp
new file mode 100644
index 00000000000..c842c5a9c27
--- /dev/null
+++ b/src/plugins/ios/iosqtversionfactory.cpp
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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 "iosqtversionfactory.h"
+#include "iosqtversion.h"
+#include "iosconstants.h"
+#include
+#include
+#include
+
+#include
+#include
+
+namespace Ios {
+namespace Internal {
+
+IosQtVersionFactory::IosQtVersionFactory(QObject *parent)
+ : QtSupport::QtVersionFactory(parent)
+{
+}
+
+bool IosQtVersionFactory::canRestore(const QString &type)
+{
+ return type == QLatin1String(Constants::IOSQT);
+}
+
+QtSupport::BaseQtVersion *IosQtVersionFactory::restore(const QString &type,
+ const QVariantMap &data)
+{
+ QTC_ASSERT(canRestore(type), return 0);
+ IosQtVersion *v = new IosQtVersion;
+ v->fromMap(data);
+ return v;
+}
+
+int IosQtVersionFactory::priority() const
+{
+ return 90;
+}
+
+QtSupport::BaseQtVersion *IosQtVersionFactory::create(const Utils::FileName &qmakePath,
+ ProFileEvaluator *evaluator,
+ bool isAutoDetected,
+ const QString &autoDetectionSource)
+{
+ if (!(evaluator->values(QLatin1String("QMAKE_PLATFORM")).contains(QLatin1String("ios"))))
+ return 0;
+ return new IosQtVersion(qmakePath, isAutoDetected, autoDetectionSource);
+}
+
+} // Internal
+} // Ios
diff --git a/src/plugins/ios/iosqtversionfactory.h b/src/plugins/ios/iosqtversionfactory.h
new file mode 100644
index 00000000000..d63b5780862
--- /dev/null
+++ b/src/plugins/ios/iosqtversionfactory.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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 IOSQTVERSIONFACTORY_H
+#define IOSQTVERSIONFACTORY_H
+
+#include
+
+namespace Ios {
+namespace Internal {
+
+class IosQtVersionFactory : public QtSupport::QtVersionFactory
+{
+public:
+ explicit IosQtVersionFactory(QObject *parent = 0);
+
+ bool canRestore(const QString &type);
+ QtSupport::BaseQtVersion *restore(const QString &type, const QVariantMap &data);
+
+ int priority() const;
+ QtSupport::BaseQtVersion *create(const Utils::FileName &qmakePath, ProFileEvaluator *evaluator,
+ bool isAutoDetected = false,
+ const QString &autoDetectionSource = QString());
+};
+
+} // namespace Internal
+} // namespace Ios
+
+#endif // IOSQTVERSIONFACTORY_H
diff --git a/src/plugins/ios/iosrunconfiguration.cpp b/src/plugins/ios/iosrunconfiguration.cpp
new file mode 100644
index 00000000000..851d6574be1
--- /dev/null
+++ b/src/plugins/ios/iosrunconfiguration.cpp
@@ -0,0 +1,275 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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 "iosrunconfiguration.h"
+#include "iosmanager.h"
+#include "iosdeploystep.h"
+
+#include