forked from qt-creator/qt-creator
iOS: Refactor iOS tool chain and kit auto detection
It was all done in one huge, unreadable method. The refactoring along-side fixes the following: - iOS tool chains were demoted to manual at start up because there was no tool chain factory that would auto detect them - a QTC_CHECK failed because single Qt Versions could appear multiple times in the architecture->Qt version map, because each architecture is present in two abis (32-bit and 64-bit) The refactoring also removes unneeded automatic conversion from non-iOS Qt version to iOS Qt version, and removes considering GCC toolchains (which were not handled anyhow, because only Clang "platforms" were considered). Change-Id: Ic9ae797646f159ed45959fc797990aa98f2136fb Reviewed-by: Tobias Hunger <tobias.hunger@theqtcompany.com>
This commit is contained in:
@@ -35,6 +35,7 @@
|
|||||||
#include "iosprobe.h"
|
#include "iosprobe.h"
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
|
#include <utils/algorithm.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
#include <projectexplorer/kitmanager.h>
|
#include <projectexplorer/kitmanager.h>
|
||||||
#include <projectexplorer/kitinformation.h>
|
#include <projectexplorer/kitinformation.h>
|
||||||
@@ -52,8 +53,8 @@
|
|||||||
#include <qtsupport/qtversionfactory.h>
|
#include <qtsupport/qtversionfactory.h>
|
||||||
|
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
|
#include <QHash>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QMap>
|
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
@@ -73,307 +74,204 @@ namespace Internal {
|
|||||||
const QLatin1String SettingsGroup("IosConfigurations");
|
const QLatin1String SettingsGroup("IosConfigurations");
|
||||||
const QLatin1String ignoreAllDevicesKey("IgnoreAllDevices");
|
const QLatin1String ignoreAllDevicesKey("IgnoreAllDevices");
|
||||||
|
|
||||||
|
static Core::Id deviceId(const Platform &platform)
|
||||||
|
{
|
||||||
|
if (platform.name.startsWith(QLatin1String("iphoneos-")))
|
||||||
|
return Constants::IOS_DEVICE_TYPE;
|
||||||
|
else if (platform.name.startsWith(QLatin1String("iphonesimulator-")))
|
||||||
|
return Constants::IOS_SIMULATOR_TYPE;
|
||||||
|
return Core::Id();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool handledPlatform(const Platform &platform)
|
||||||
|
{
|
||||||
|
// do not want platforms that
|
||||||
|
// - are not iphone (e.g. watchos)
|
||||||
|
// - are not base
|
||||||
|
// - are C++11
|
||||||
|
// - are not clang
|
||||||
|
return deviceId(platform).isValid()
|
||||||
|
&& (platform.platformKind & Platform::BasePlatform) != 0
|
||||||
|
&& (platform.platformKind & Platform::Cxx11Support) == 0
|
||||||
|
&& platform.compilerPath.toString().contains(QLatin1String("clang"));
|
||||||
|
}
|
||||||
|
|
||||||
|
static QList<Platform> handledPlatforms()
|
||||||
|
{
|
||||||
|
QList<Platform> platforms = IosProbe::detectPlatforms().values();
|
||||||
|
return Utils::filtered(platforms, handledPlatform);
|
||||||
|
}
|
||||||
|
|
||||||
|
static QList<ClangToolChain *> clangToolChains(const QList<ToolChain *> &toolChains)
|
||||||
|
{
|
||||||
|
QList<ClangToolChain *> clangToolChains;
|
||||||
|
foreach (ToolChain *toolChain, toolChains)
|
||||||
|
if (toolChain->typeId() == ProjectExplorer::Constants::CLANG_TOOLCHAIN_TYPEID)
|
||||||
|
clangToolChains.append(static_cast<ClangToolChain *>(toolChain));
|
||||||
|
return clangToolChains;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QList<ClangToolChain *> autoDetectedIosToolChains()
|
||||||
|
{
|
||||||
|
const QList<ClangToolChain *> toolChains = clangToolChains(ToolChainManager::toolChains());
|
||||||
|
return Utils::filtered(toolChains, [](ClangToolChain *toolChain) {
|
||||||
|
return toolChain->isAutoDetected()
|
||||||
|
&& toolChain->displayName().startsWith(QLatin1String("iphone")); // TODO tool chains should be marked directly
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static ClangToolChain *findToolChainForPlatform(const Platform &platform, const QList<ClangToolChain *> &toolChains)
|
||||||
|
{
|
||||||
|
return Utils::findOrDefault(toolChains, [&platform](ClangToolChain *toolChain) {
|
||||||
|
return platform.compilerPath == toolChain->compilerCommand()
|
||||||
|
&& platform.backendFlags == toolChain->platformCodeGenFlags()
|
||||||
|
&& platform.backendFlags == toolChain->platformLinkerFlags();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static QHash<Platform, ClangToolChain *> findToolChains(const QList<Platform> &platforms)
|
||||||
|
{
|
||||||
|
QHash<Platform, ClangToolChain *> platformToolChainHash;
|
||||||
|
const QList<ClangToolChain *> toolChains = autoDetectedIosToolChains();
|
||||||
|
foreach (const Platform &platform, platforms) {
|
||||||
|
ClangToolChain *toolChain = findToolChainForPlatform(platform, toolChains);
|
||||||
|
if (toolChain)
|
||||||
|
platformToolChainHash.insert(platform, toolChain);
|
||||||
|
}
|
||||||
|
return platformToolChainHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QHash<Abi::Architecture, QSet<BaseQtVersion *>> iosQtVersions()
|
||||||
|
{
|
||||||
|
QHash<Abi::Architecture, QSet<BaseQtVersion *>> versions;
|
||||||
|
foreach (BaseQtVersion *qtVersion, QtVersionManager::versions()) {
|
||||||
|
if (!qtVersion->isValid() || qtVersion->type() != QLatin1String(Constants::IOSQT))
|
||||||
|
continue;
|
||||||
|
foreach (const Abi &abi, qtVersion->qtAbis())
|
||||||
|
versions[abi.architecture()].insert(qtVersion);
|
||||||
|
}
|
||||||
|
return versions;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void printQtVersions(const QHash<Abi::Architecture, QSet<BaseQtVersion *> > &map)
|
||||||
|
{
|
||||||
|
foreach (const Abi::Architecture &arch, map.keys()) {
|
||||||
|
qCDebug(kitSetupLog) << "-" << Abi::toString(arch);
|
||||||
|
foreach (const BaseQtVersion *version, map.value(arch))
|
||||||
|
qCDebug(kitSetupLog) << " -" << version->displayName() << version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static QSet<Kit *> existingAutoDetectedIosKits()
|
||||||
|
{
|
||||||
|
return Utils::filtered(KitManager::kits(), [](Kit *kit) -> bool {
|
||||||
|
Core::Id deviceKind = DeviceTypeKitInformation::deviceTypeId(kit);
|
||||||
|
return kit->isAutoDetected() && (deviceKind == Constants::IOS_DEVICE_TYPE
|
||||||
|
|| deviceKind == Constants::IOS_SIMULATOR_TYPE);
|
||||||
|
}).toSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void printKits(const QSet<Kit *> &kits)
|
||||||
|
{
|
||||||
|
foreach (const Kit *kit, kits)
|
||||||
|
qCDebug(kitSetupLog) << " -" << kit->displayName();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setupKit(Kit *kit, Core::Id pDeviceType, ClangToolChain *pToolchain,
|
||||||
|
const QVariant &debuggerId, const Utils::FileName &sdkPath, BaseQtVersion *qtVersion)
|
||||||
|
{
|
||||||
|
kit->setIconPath(FileName::fromString(QLatin1String(Constants::IOS_SETTINGS_CATEGORY_ICON)));
|
||||||
|
DeviceTypeKitInformation::setDeviceTypeId(kit, pDeviceType);
|
||||||
|
ToolChainKitInformation::setToolChain(kit, pToolchain);
|
||||||
|
QtKitInformation::setQtVersion(kit, qtVersion);
|
||||||
|
// only replace debugger with the default one if we find an unusable one here
|
||||||
|
// (since the user could have changed it)
|
||||||
|
if ((!DebuggerKitInformation::debugger(kit)
|
||||||
|
|| !DebuggerKitInformation::debugger(kit)->isValid()
|
||||||
|
|| DebuggerKitInformation::debugger(kit)->engineType() != LldbEngineType)
|
||||||
|
&& debuggerId.isValid())
|
||||||
|
DebuggerKitInformation::setDebugger(kit, debuggerId);
|
||||||
|
|
||||||
|
kit->setMutable(DeviceKitInformation::id(), true);
|
||||||
|
kit->setSticky(QtKitInformation::id(), true);
|
||||||
|
kit->setSticky(ToolChainKitInformation::id(), true);
|
||||||
|
kit->setSticky(DeviceTypeKitInformation::id(), true);
|
||||||
|
kit->setSticky(SysRootKitInformation::id(), true);
|
||||||
|
kit->setSticky(DebuggerKitInformation::id(), false);
|
||||||
|
|
||||||
|
SysRootKitInformation::setSysRoot(kit, sdkPath);
|
||||||
|
}
|
||||||
|
|
||||||
void IosConfigurations::updateAutomaticKitList()
|
void IosConfigurations::updateAutomaticKitList()
|
||||||
{
|
{
|
||||||
QMap<QString, Platform> platforms = IosProbe::detectPlatforms();
|
const QList<Platform> platforms = handledPlatforms();
|
||||||
|
qCDebug(kitSetupLog) << "Used platforms:" << platforms;
|
||||||
if (!platforms.isEmpty())
|
if (!platforms.isEmpty())
|
||||||
setDeveloperPath(platforms.begin().value().developerPath);
|
setDeveloperPath(platforms.first().developerPath);
|
||||||
// filter out all non iphone, non base, non clang or cxx11 platforms, as we don't set up kits for those
|
qCDebug(kitSetupLog) << "Developer path:" << developerPath();
|
||||||
{
|
|
||||||
QMap<QString, Platform>::iterator iter(platforms.begin());
|
|
||||||
while (iter != platforms.end()) {
|
|
||||||
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")))
|
|
||||||
iter = platforms.erase(iter);
|
|
||||||
else {
|
|
||||||
qCDebug(kitSetupLog) << "keeping" << p.name << " " << p.compilerPath.toString() << " "
|
|
||||||
<< p.backendFlags;
|
|
||||||
++iter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QMap<QString, GccToolChain *> platformToolchainMap;
|
// platform name -> tool chain
|
||||||
// check existing toolchains (and remove old ones)
|
const QHash<Platform, ClangToolChain *> platformToolChainHash = findToolChains(platforms);
|
||||||
foreach (ToolChain *tc, ToolChainManager::toolChains()) {
|
|
||||||
if (!tc->isAutoDetected()) // use also user toolchains?
|
const QHash<Abi::Architecture, QSet<BaseQtVersion *> > qtVersionsForArch = iosQtVersions();
|
||||||
continue;
|
qCDebug(kitSetupLog) << "iOS Qt versions:";
|
||||||
if (tc->typeId() != ProjectExplorer::Constants::CLANG_TOOLCHAIN_TYPEID
|
printQtVersions(qtVersionsForArch);
|
||||||
&& tc->typeId() != ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID)
|
|
||||||
continue;
|
|
||||||
GccToolChain *toolchain = static_cast<GccToolChain *>(tc);
|
|
||||||
QMapIterator<QString, Platform> 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.contains(p.name)) {
|
|
||||||
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()) {
|
|
||||||
found = true;
|
|
||||||
if ((p.architecture == QLatin1String("i386")
|
|
||||||
&& toolchain->targetAbi().wordWidth() != 32) ||
|
|
||||||
(p.architecture == QLatin1String("x86_64")
|
|
||||||
&& toolchain->targetAbi().wordWidth() != 64)) {
|
|
||||||
qCDebug(kitSetupLog) << "resetting api of " << toolchain->displayName();
|
|
||||||
toolchain->setTargetAbi(Abi(Abi::X86Architecture,
|
|
||||||
Abi::MacOS, Abi::GenericMacFlavor,
|
|
||||||
Abi::MachOFormat,
|
|
||||||
p.architecture.endsWith(QLatin1String("64"))
|
|
||||||
? 64 : 32));
|
|
||||||
}
|
|
||||||
platformToolchainMap[p.name] = toolchain;
|
|
||||||
qCDebug(kitSetupLog) << p.name << " -> " << toolchain->displayName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found && (tc->displayName().startsWith(QLatin1String("iphone"))
|
|
||||||
|| tc->displayName().startsWith(QLatin1String("mac")))) {
|
|
||||||
qCWarning(kitSetupLog) << "removing toolchain" << tc->displayName();
|
|
||||||
ToolChainManager::deregisterToolChain(tc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// add missing toolchains
|
|
||||||
{
|
|
||||||
QMapIterator<QString, Platform> iter(platforms);
|
|
||||||
while (iter.hasNext()) {
|
|
||||||
iter.next();
|
|
||||||
const Platform &p = iter.value();
|
|
||||||
if (platformToolchainMap.contains(p.name))
|
|
||||||
continue;
|
|
||||||
GccToolChain *toolchain;
|
|
||||||
if (p.compilerPath.toFileInfo().baseName().startsWith(QLatin1String("clang")))
|
|
||||||
toolchain = new ClangToolChain(ToolChain::AutoDetection);
|
|
||||||
else
|
|
||||||
toolchain = new GccToolChain(ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID,
|
|
||||||
ToolChain::AutoDetection);
|
|
||||||
QString baseDisplayName = p.name;
|
|
||||||
QString displayName = baseDisplayName;
|
|
||||||
for (int iVers = 1; iVers < 100; ++iVers) {
|
|
||||||
bool unique = true;
|
|
||||||
foreach (ToolChain *existingTC, ToolChainManager::toolChains()) {
|
|
||||||
if (existingTC->displayName() == displayName) {
|
|
||||||
unique = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (unique) break;
|
|
||||||
displayName = baseDisplayName + QLatin1Char('-') + QString::number(iVers);
|
|
||||||
}
|
|
||||||
toolchain->setDisplayName(displayName);
|
|
||||||
toolchain->setPlatformCodeGenFlags(p.backendFlags);
|
|
||||||
toolchain->setPlatformLinkerFlags(p.backendFlags);
|
|
||||||
toolchain->resetToolChain(p.compilerPath);
|
|
||||||
if (p.architecture == QLatin1String("i386")
|
|
||||||
|| p.architecture == QLatin1String("x86_64")) {
|
|
||||||
qCDebug(kitSetupLog) << "setting toolchain Abi for " << toolchain->displayName();
|
|
||||||
toolchain->setTargetAbi(Abi(Abi::X86Architecture,Abi::MacOS, Abi::GenericMacFlavor,
|
|
||||||
Abi::MachOFormat,
|
|
||||||
p.architecture.endsWith(QLatin1String("64"))
|
|
||||||
? 64 : 32));
|
|
||||||
}
|
|
||||||
qCDebug(kitSetupLog) << "adding toolchain " << p.name;
|
|
||||||
ToolChainManager::registerToolChain(toolchain);
|
|
||||||
platformToolchainMap.insert(p.name, toolchain);
|
|
||||||
QMapIterator<QString, Platform> 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
QMap<Abi::Architecture, QList<BaseQtVersion *> > qtVersionsForArch;
|
|
||||||
foreach (BaseQtVersion *qtVersion, QtVersionManager::versions()) {
|
|
||||||
qCDebug(kitSetupLog) << "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
|
|
||||||
BaseQtVersion *iosVersion =
|
|
||||||
QtVersionFactory::createQtVersionFromQMakePath(
|
|
||||||
qtVersion->qmakeCommand(),
|
|
||||||
qtVersion->isAutodetected(),
|
|
||||||
qtVersion->autodetectionSource());
|
|
||||||
if (iosVersion && iosVersion->type() == QLatin1String(Constants::IOSQT)) {
|
|
||||||
qCDebug(kitSetupLog) << "converting QT to iOS QT for " << qtVersion->qmakeCommand().toUserOutput();
|
|
||||||
QtVersionManager::removeVersion(qtVersion);
|
|
||||||
QtVersionManager::addVersion(iosVersion);
|
|
||||||
qtVersion = iosVersion;
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!qtVersion->isValid())
|
|
||||||
continue;
|
|
||||||
QList<Abi> qtAbis = qtVersion->qtAbis();
|
|
||||||
if (qtAbis.empty())
|
|
||||||
continue;
|
|
||||||
qCDebug(kitSetupLog) << "qt arch " << qtAbis.first().architecture();
|
|
||||||
foreach (const Abi &abi, qtAbis)
|
|
||||||
qtVersionsForArch[abi.architecture()].append(qtVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
const DebuggerItem *possibleDebugger = DebuggerItemManager::findByEngineType(LldbEngineType);
|
const DebuggerItem *possibleDebugger = DebuggerItemManager::findByEngineType(LldbEngineType);
|
||||||
QVariant debuggerId = (possibleDebugger ? possibleDebugger->id() : QVariant());
|
const QVariant debuggerId = (possibleDebugger ? possibleDebugger->id() : QVariant());
|
||||||
|
|
||||||
QList<Kit *> existingKits;
|
QSet<Kit *> existingKits = existingAutoDetectedIosKits();
|
||||||
QList<bool> kitMatched;
|
qCDebug(kitSetupLog) << "Existing auto-detected iOS kits:";
|
||||||
foreach (Kit *k, KitManager::kits()) {
|
printKits(existingKits);
|
||||||
Core::Id deviceKind = DeviceTypeKitInformation::deviceTypeId(k);
|
QSet<Kit *> resultingKits;
|
||||||
if (deviceKind != Constants::IOS_DEVICE_TYPE
|
// match existing kits and create missing kits
|
||||||
&& deviceKind != Constants::IOS_SIMULATOR_TYPE) {
|
foreach (const Platform &platform, platforms) {
|
||||||
qCDebug(kitSetupLog) << "skipping existing kit with deviceKind " << deviceKind.toString();
|
qCDebug(kitSetupLog) << "Guaranteeing kits for " << platform.name ;
|
||||||
|
ClangToolChain *pToolchain = platformToolChainHash.value(platform);
|
||||||
|
if (!pToolchain) {
|
||||||
|
qCDebug(kitSetupLog) << " - No tool chain found";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!k->isAutoDetected())
|
Core::Id pDeviceType = deviceId(platform);
|
||||||
continue;
|
QTC_ASSERT(pDeviceType.isValid(), continue);
|
||||||
existingKits << k;
|
Abi::Architecture arch = pToolchain->targetAbi().architecture();
|
||||||
kitMatched << false;
|
|
||||||
}
|
QSet<BaseQtVersion *> qtVersions = qtVersionsForArch.value(arch);
|
||||||
// create missing kits
|
foreach (BaseQtVersion *qtVersion, qtVersions) {
|
||||||
{
|
qCDebug(kitSetupLog) << " - Qt version:" << qtVersion->displayName();
|
||||||
QMapIterator<QString, Platform> iter(platforms);
|
Kit *kit = Utils::findOrDefault(existingKits, [&pDeviceType, &pToolchain, &qtVersion](const Kit *kit) {
|
||||||
while (iter.hasNext()) {
|
// we do not compare the sdk (thus automatically upgrading it in place if a
|
||||||
iter.next();
|
// new Xcode is used). Change?
|
||||||
const Platform &p = iter.value();
|
return DeviceTypeKitInformation::deviceTypeId(kit) == pDeviceType
|
||||||
GccToolChain *pToolchain = platformToolchainMap.value(p.name, 0);
|
&& ToolChainKitInformation::toolChain(kit) == pToolchain
|
||||||
if (!pToolchain)
|
&& QtKitInformation::qtVersion(kit) == qtVersion;
|
||||||
continue;
|
});
|
||||||
Core::Id pDeviceType;
|
QTC_ASSERT(!resultingKits.contains(kit), continue);
|
||||||
qCDebug(kitSetupLog) << "guaranteeing kit for " << p.name ;
|
if (kit) {
|
||||||
if (p.name.startsWith(QLatin1String("iphoneos-"))) {
|
qCDebug(kitSetupLog) << " - Kit matches:" << kit->displayName();
|
||||||
pDeviceType = Constants::IOS_DEVICE_TYPE;
|
kit->blockNotification();
|
||||||
} else if (p.name.startsWith(QLatin1String("iphonesimulator-"))) {
|
setupKit(kit, pDeviceType, pToolchain, debuggerId, platform.sdkPath, qtVersion);
|
||||||
pDeviceType = Constants::IOS_SIMULATOR_TYPE;
|
kit->unblockNotification();
|
||||||
qCDebug(kitSetupLog) << "pDeviceType " << pDeviceType.toString();
|
|
||||||
} else {
|
} else {
|
||||||
qCDebug(kitSetupLog) << "skipping non ios kit " << p.name;
|
qCDebug(kitSetupLog) << " - Setting up new kit";
|
||||||
// we looked up only the ios qt build above...
|
kit = new Kit;
|
||||||
continue;
|
kit->blockNotification();
|
||||||
//pDeviceType = Constants::DESKTOP_DEVICE_TYPE;
|
kit->setAutoDetected(true);
|
||||||
}
|
const QString baseDisplayName = tr("%1 %2").arg(platform.name, qtVersion->unexpandedDisplayName());
|
||||||
Abi::Architecture arch = pToolchain->targetAbi().architecture();
|
kit->setUnexpandedDisplayName(baseDisplayName);
|
||||||
|
setupKit(kit, pDeviceType, pToolchain, debuggerId, platform.sdkPath, qtVersion);
|
||||||
QList<BaseQtVersion *> qtVersions = qtVersionsForArch.value(arch);
|
kit->unblockNotification();
|
||||||
foreach (BaseQtVersion *qt, qtVersions) {
|
KitManager::registerKit(kit);
|
||||||
Kit *kitAtt = 0;
|
|
||||||
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
|
|
||||||
&& QtKitInformation::qtVersion(k) == qt)
|
|
||||||
{
|
|
||||||
QTC_CHECK(!kitMatched.value(i, true));
|
|
||||||
// as we generate only two kits per qt (one for device and one for simulator)
|
|
||||||
// we do not compare the sdk (thus automatically upgrading it in place if a
|
|
||||||
// new Xcode is used). Change?
|
|
||||||
kitExists = true;
|
|
||||||
kitAtt = k;
|
|
||||||
qCDebug(kitSetupLog) << "found existing kit " << k->displayName() << " for " << p.name
|
|
||||||
<< "," << qt->displayName();
|
|
||||||
if (i<kitMatched.size())
|
|
||||||
kitMatched.replace(i, true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (kitExists) {
|
|
||||||
kitAtt->blockNotification();
|
|
||||||
// TODO: this is just to fix up broken display names from before
|
|
||||||
QString baseDisplayName = tr("%1 %2").arg(p.name, qt->unexpandedDisplayName());
|
|
||||||
QString displayName = baseDisplayName;
|
|
||||||
for (int iVers = 1; iVers < 100; ++iVers) {
|
|
||||||
bool unique = true;
|
|
||||||
foreach (const Kit *k, existingKits) {
|
|
||||||
if (k == kitAtt)
|
|
||||||
continue;
|
|
||||||
if (k->displayName() == displayName) {
|
|
||||||
unique = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (unique) break;
|
|
||||||
displayName = baseDisplayName + QLatin1Char('-') + QString::number(iVers);
|
|
||||||
}
|
|
||||||
kitAtt->setUnexpandedDisplayName(displayName);
|
|
||||||
} else {
|
|
||||||
qCDebug(kitSetupLog) << "setting up new kit for " << p.name;
|
|
||||||
kitAtt = new Kit;
|
|
||||||
kitAtt->setAutoDetected(true);
|
|
||||||
QString baseDisplayName = tr("%1 %2").arg(p.name, qt->unexpandedDisplayName());
|
|
||||||
QString displayName = baseDisplayName;
|
|
||||||
for (int iVers = 1; iVers < 100; ++iVers) {
|
|
||||||
bool unique = true;
|
|
||||||
foreach (const Kit *k, existingKits) {
|
|
||||||
if (k->displayName() == displayName) {
|
|
||||||
unique = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (unique) break;
|
|
||||||
displayName = baseDisplayName + QLatin1Char('-') + QString::number(iVers);
|
|
||||||
}
|
|
||||||
kitAtt->setUnexpandedDisplayName(displayName);
|
|
||||||
}
|
|
||||||
kitAtt->setIconPath(FileName::fromString(
|
|
||||||
QLatin1String(Constants::IOS_SETTINGS_CATEGORY_ICON)));
|
|
||||||
DeviceTypeKitInformation::setDeviceTypeId(kitAtt, pDeviceType);
|
|
||||||
ToolChainKitInformation::setToolChain(kitAtt, pToolchain);
|
|
||||||
QtKitInformation::setQtVersion(kitAtt, qt);
|
|
||||||
if ((!DebuggerKitInformation::debugger(kitAtt)
|
|
||||||
|| !DebuggerKitInformation::debugger(kitAtt)->isValid()
|
|
||||||
|| DebuggerKitInformation::debugger(kitAtt)->engineType() != LldbEngineType)
|
|
||||||
&& debuggerId.isValid())
|
|
||||||
DebuggerKitInformation::setDebugger(kitAtt,
|
|
||||||
debuggerId);
|
|
||||||
|
|
||||||
kitAtt->setMutable(DeviceKitInformation::id(), true);
|
|
||||||
kitAtt->setSticky(QtKitInformation::id(), true);
|
|
||||||
kitAtt->setSticky(ToolChainKitInformation::id(), true);
|
|
||||||
kitAtt->setSticky(DeviceTypeKitInformation::id(), true);
|
|
||||||
kitAtt->setSticky(SysRootKitInformation::id(), true);
|
|
||||||
kitAtt->setSticky(DebuggerKitInformation::id(), false);
|
|
||||||
|
|
||||||
SysRootKitInformation::setSysRoot(kitAtt, p.sdkPath);
|
|
||||||
// QmakeProjectManager::QmakeKitInformation::setMkspec(newKit,
|
|
||||||
// Utils::FileName::fromLatin1("macx-ios-clang")));
|
|
||||||
if (kitExists) {
|
|
||||||
kitAtt->unblockNotification();
|
|
||||||
} else {
|
|
||||||
KitManager::registerKit(kitAtt);
|
|
||||||
existingKits << kitAtt;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
resultingKits.insert(kit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0; i < kitMatched.size(); ++i) {
|
// remove unused kits
|
||||||
// deleting extra (old) kits
|
existingKits.subtract(resultingKits);
|
||||||
if (!kitMatched.at(i)) {
|
qCDebug(kitSetupLog) << "Removing unused kits:";
|
||||||
qCWarning(kitSetupLog) << "deleting kit " << existingKits.at(i)->displayName();
|
printKits(existingKits);
|
||||||
KitManager::deregisterKit(existingKits.at(i));
|
foreach (Kit *kit, existingKits)
|
||||||
}
|
KitManager::deregisterKit(kit);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static IosConfigurations *m_instance = 0;
|
static IosConfigurations *m_instance = 0;
|
||||||
@@ -458,5 +356,32 @@ void IosConfigurations::setDeveloperPath(const FileName &devPath)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ClangToolChain *createToolChain(const Platform &platform)
|
||||||
|
{
|
||||||
|
ClangToolChain *toolChain = new ClangToolChain(ToolChain::AutoDetection);
|
||||||
|
toolChain->setDisplayName(platform.name);
|
||||||
|
toolChain->setPlatformCodeGenFlags(platform.backendFlags);
|
||||||
|
toolChain->setPlatformLinkerFlags(platform.backendFlags);
|
||||||
|
toolChain->resetToolChain(platform.compilerPath);
|
||||||
|
return toolChain;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<ToolChain *> IosToolChainFactory::autoDetect(const QList<ToolChain *> &existingToolChains)
|
||||||
|
{
|
||||||
|
QList<ClangToolChain *> existingClangToolChains = clangToolChains(existingToolChains);
|
||||||
|
const QList<Platform> platforms = handledPlatforms();
|
||||||
|
QList<ClangToolChain *> toolChains;
|
||||||
|
toolChains.reserve(platforms.size());
|
||||||
|
foreach (const Platform &platform, platforms) {
|
||||||
|
ClangToolChain *toolChain = findToolChainForPlatform(platform, existingClangToolChains);
|
||||||
|
if (!toolChain) {
|
||||||
|
ClangToolChain *newToolChain = createToolChain(platform);
|
||||||
|
toolChains.append(newToolChain);
|
||||||
|
existingClangToolChains.append(newToolChain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Utils::transform(toolChains, [](ClangToolChain *tc) -> ToolChain * { return tc; });
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Ios
|
} // namespace Ios
|
||||||
|
@@ -31,6 +31,7 @@
|
|||||||
#define IOSCONFIGURATIONS_H
|
#define IOSCONFIGURATIONS_H
|
||||||
|
|
||||||
#include <projectexplorer/abi.h>
|
#include <projectexplorer/abi.h>
|
||||||
|
#include <projectexplorer/toolchain.h>
|
||||||
#include <utils/fileutils.h>
|
#include <utils/fileutils.h>
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
@@ -44,6 +45,15 @@ QT_END_NAMESPACE
|
|||||||
namespace Ios {
|
namespace Ios {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
|
class IosToolChainFactory : public ProjectExplorer::ToolChainFactory
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
QList<ProjectExplorer::ToolChain *> autoDetect(const QList<ProjectExplorer::ToolChain *> &existingToolChains) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class IosConfigurations : public QObject
|
class IosConfigurations : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@@ -69,6 +69,7 @@ bool IosPlugin::initialize(const QStringList &arguments, QString *errorMessage)
|
|||||||
|
|
||||||
Internal::IosConfigurations::initialize();
|
Internal::IosConfigurations::initialize();
|
||||||
|
|
||||||
|
addAutoReleasedObject(new Internal::IosToolChainFactory);
|
||||||
addAutoReleasedObject(new Internal::IosRunControlFactory);
|
addAutoReleasedObject(new Internal::IosRunControlFactory);
|
||||||
addAutoReleasedObject(new Internal::IosRunConfigurationFactory);
|
addAutoReleasedObject(new Internal::IosRunConfigurationFactory);
|
||||||
addAutoReleasedObject(new Internal::IosSettingsPage);
|
addAutoReleasedObject(new Internal::IosSettingsPage);
|
||||||
|
@@ -290,4 +290,24 @@ QMap<QString, Platform> IosProbe::detectedPlatforms()
|
|||||||
return m_platforms;
|
return m_platforms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QDebug operator<<(QDebug debug, const Platform &platform)
|
||||||
|
{
|
||||||
|
QDebugStateSaver saver(debug); Q_UNUSED(saver)
|
||||||
|
debug.nospace() << "(name=" << platform.name
|
||||||
|
<< ", compiler=" << platform.compilerPath.toString()
|
||||||
|
<< ", flags=" << platform.backendFlags
|
||||||
|
<< ")";
|
||||||
|
return debug;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Platform::operator==(const Platform &other) const
|
||||||
|
{
|
||||||
|
return name == other.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint qHash(const Platform &platform)
|
||||||
|
{
|
||||||
|
return qHash(platform.name);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -54,8 +54,14 @@ public:
|
|||||||
Utils::FileName compilerPath;
|
Utils::FileName compilerPath;
|
||||||
QString architecture;
|
QString architecture;
|
||||||
QStringList backendFlags;
|
QStringList backendFlags;
|
||||||
|
|
||||||
|
// ignores anything besides name
|
||||||
|
bool operator==(const Platform &other) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
uint qHash(const Platform &platform);
|
||||||
|
QDebug operator<<(QDebug debug, const Platform &platform);
|
||||||
|
|
||||||
class IosProbe
|
class IosProbe
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
Reference in New Issue
Block a user