diff --git a/src/plugins/ios/iosconfigurations.cpp b/src/plugins/ios/iosconfigurations.cpp index 01ecfb5713f6ccad844371aee5bbea52e78c040b..362160018acdd46752fe60a53169065cc3ceca34 100644 --- a/src/plugins/ios/iosconfigurations.cpp +++ b/src/plugins/ios/iosconfigurations.cpp @@ -35,6 +35,7 @@ #include "iosprobe.h" #include +#include #include #include #include @@ -52,8 +53,8 @@ #include #include +#include #include -#include #include #include #include @@ -73,307 +74,204 @@ namespace Internal { const QLatin1String SettingsGroup("IosConfigurations"); const QLatin1String ignoreAllDevicesKey("IgnoreAllDevices"); -void IosConfigurations::updateAutomaticKitList() +static Core::Id deviceId(const Platform &platform) { - QMap platforms = IosProbe::detectPlatforms(); - if (!platforms.isEmpty()) - setDeveloperPath(platforms.begin().value().developerPath); - // filter out all non iphone, non base, non clang or cxx11 platforms, as we don't set up kits for those - { - QMap::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; - } - } - } + 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(); +} - QMap platformToolchainMap; - // check existing toolchains (and remove old ones) - foreach (ToolChain *tc, ToolChainManager::toolChains()) { - if (!tc->isAutoDetected()) // use also user toolchains? - continue; - if (tc->typeId() != ProjectExplorer::Constants::CLANG_TOOLCHAIN_TYPEID - && tc->typeId() != ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID) - continue; - 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.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 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 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; - } - } - } +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 handledPlatforms() +{ + QList platforms = IosProbe::detectPlatforms().values(); + return Utils::filtered(platforms, handledPlatform); +} + +static QList clangToolChains(const QList &toolChains) +{ + QList clangToolChains; + foreach (ToolChain *toolChain, toolChains) + if (toolChain->typeId() == ProjectExplorer::Constants::CLANG_TOOLCHAIN_TYPEID) + clangToolChains.append(static_cast(toolChain)); + return clangToolChains; +} + +static QList autoDetectedIosToolChains() +{ + const QList 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 &toolChains) +{ + return Utils::findOrDefault(toolChains, [&platform](ClangToolChain *toolChain) { + return platform.compilerPath == toolChain->compilerCommand() + && platform.backendFlags == toolChain->platformCodeGenFlags() + && platform.backendFlags == toolChain->platformLinkerFlags(); + }); +} + +static QHash findToolChains(const QList &platforms) +{ + QHash platformToolChainHash; + const QList toolChains = autoDetectedIosToolChains(); + foreach (const Platform &platform, platforms) { + ClangToolChain *toolChain = findToolChainForPlatform(platform, toolChains); + if (toolChain) + platformToolChainHash.insert(platform, toolChain); } - QMap > qtVersionsForArch; + return platformToolChainHash; +} + +static QHash> iosQtVersions() +{ + QHash> versions; 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 qtAbis = qtVersion->qtAbis(); - if (qtAbis.empty()) + if (!qtVersion->isValid() || qtVersion->type() != QLatin1String(Constants::IOSQT)) continue; - qCDebug(kitSetupLog) << "qt arch " << qtAbis.first().architecture(); - foreach (const Abi &abi, qtAbis) - qtVersionsForArch[abi.architecture()].append(qtVersion); + foreach (const Abi &abi, qtVersion->qtAbis()) + versions[abi.architecture()].insert(qtVersion); + } + return versions; +} + +static void printQtVersions(const QHash > &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 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 &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() +{ + const QList platforms = handledPlatforms(); + qCDebug(kitSetupLog) << "Used platforms:" << platforms; + if (!platforms.isEmpty()) + setDeveloperPath(platforms.first().developerPath); + qCDebug(kitSetupLog) << "Developer path:" << developerPath(); + + // platform name -> tool chain + const QHash platformToolChainHash = findToolChains(platforms); + + const QHash > qtVersionsForArch = iosQtVersions(); + qCDebug(kitSetupLog) << "iOS Qt versions:"; + printQtVersions(qtVersionsForArch); const DebuggerItem *possibleDebugger = DebuggerItemManager::findByEngineType(LldbEngineType); - QVariant debuggerId = (possibleDebugger ? possibleDebugger->id() : QVariant()); - - QList existingKits; - QList kitMatched; - foreach (Kit *k, KitManager::kits()) { - Core::Id deviceKind = DeviceTypeKitInformation::deviceTypeId(k); - if (deviceKind != Constants::IOS_DEVICE_TYPE - && deviceKind != Constants::IOS_SIMULATOR_TYPE) { - qCDebug(kitSetupLog) << "skipping existing kit with deviceKind " << deviceKind.toString(); + const QVariant debuggerId = (possibleDebugger ? possibleDebugger->id() : QVariant()); + + QSet existingKits = existingAutoDetectedIosKits(); + qCDebug(kitSetupLog) << "Existing auto-detected iOS kits:"; + printKits(existingKits); + QSet resultingKits; + // match existing kits and create missing kits + foreach (const Platform &platform, platforms) { + qCDebug(kitSetupLog) << "Guaranteeing kits for " << platform.name ; + ClangToolChain *pToolchain = platformToolChainHash.value(platform); + if (!pToolchain) { + qCDebug(kitSetupLog) << " - No tool chain found"; continue; } - if (!k->isAutoDetected()) - continue; - existingKits << k; - kitMatched << false; - } - // create missing kits - { - QMapIterator iter(platforms); - while (iter.hasNext()) { - iter.next(); - const Platform &p = iter.value(); - GccToolChain *pToolchain = platformToolchainMap.value(p.name, 0); - if (!pToolchain) - continue; - Core::Id pDeviceType; - qCDebug(kitSetupLog) << "guaranteeing kit for " << p.name ; - if (p.name.startsWith(QLatin1String("iphoneos-"))) { - pDeviceType = Constants::IOS_DEVICE_TYPE; - } else if (p.name.startsWith(QLatin1String("iphonesimulator-"))) { - pDeviceType = Constants::IOS_SIMULATOR_TYPE; - qCDebug(kitSetupLog) << "pDeviceType " << pDeviceType.toString(); + Core::Id pDeviceType = deviceId(platform); + QTC_ASSERT(pDeviceType.isValid(), continue); + Abi::Architecture arch = pToolchain->targetAbi().architecture(); + + QSet qtVersions = qtVersionsForArch.value(arch); + foreach (BaseQtVersion *qtVersion, qtVersions) { + qCDebug(kitSetupLog) << " - Qt version:" << qtVersion->displayName(); + Kit *kit = Utils::findOrDefault(existingKits, [&pDeviceType, &pToolchain, &qtVersion](const Kit *kit) { + // we do not compare the sdk (thus automatically upgrading it in place if a + // new Xcode is used). Change? + return DeviceTypeKitInformation::deviceTypeId(kit) == pDeviceType + && ToolChainKitInformation::toolChain(kit) == pToolchain + && QtKitInformation::qtVersion(kit) == qtVersion; + }); + QTC_ASSERT(!resultingKits.contains(kit), continue); + if (kit) { + qCDebug(kitSetupLog) << " - Kit matches:" << kit->displayName(); + kit->blockNotification(); + setupKit(kit, pDeviceType, pToolchain, debuggerId, platform.sdkPath, qtVersion); + kit->unblockNotification(); } else { - qCDebug(kitSetupLog) << "skipping non ios kit " << p.name; - // we looked up only the ios qt build above... - continue; - //pDeviceType = Constants::DESKTOP_DEVICE_TYPE; - } - Abi::Architecture arch = pToolchain->targetAbi().architecture(); - - QList qtVersions = qtVersionsForArch.value(arch); - foreach (BaseQtVersion *qt, qtVersions) { - 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 (iblockNotification(); - // 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; - } + qCDebug(kitSetupLog) << " - Setting up new kit"; + kit = new Kit; + kit->blockNotification(); + kit->setAutoDetected(true); + const QString baseDisplayName = tr("%1 %2").arg(platform.name, qtVersion->unexpandedDisplayName()); + kit->setUnexpandedDisplayName(baseDisplayName); + setupKit(kit, pDeviceType, pToolchain, debuggerId, platform.sdkPath, qtVersion); + kit->unblockNotification(); + KitManager::registerKit(kit); } + resultingKits.insert(kit); } } - for (int i = 0; i < kitMatched.size(); ++i) { - // deleting extra (old) kits - if (!kitMatched.at(i)) { - qCWarning(kitSetupLog) << "deleting kit " << existingKits.at(i)->displayName(); - KitManager::deregisterKit(existingKits.at(i)); - } - } + // remove unused kits + existingKits.subtract(resultingKits); + qCDebug(kitSetupLog) << "Removing unused kits:"; + printKits(existingKits); + foreach (Kit *kit, existingKits) + KitManager::deregisterKit(kit); } 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 IosToolChainFactory::autoDetect(const QList &existingToolChains) +{ + QList existingClangToolChains = clangToolChains(existingToolChains); + const QList platforms = handledPlatforms(); + QList 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 Ios diff --git a/src/plugins/ios/iosconfigurations.h b/src/plugins/ios/iosconfigurations.h index 9d9fea2df8550330fd0b9c971746a3c2c883a3fd..3bf7b3036a7384bdaffa98dda2f36eecd4a4a1f4 100644 --- a/src/plugins/ios/iosconfigurations.h +++ b/src/plugins/ios/iosconfigurations.h @@ -31,6 +31,7 @@ #define IOSCONFIGURATIONS_H #include +#include #include #include @@ -44,6 +45,15 @@ QT_END_NAMESPACE namespace Ios { namespace Internal { +class IosToolChainFactory : public ProjectExplorer::ToolChainFactory +{ + Q_OBJECT + +public: + QList autoDetect(const QList &existingToolChains) override; +}; + + class IosConfigurations : public QObject { Q_OBJECT diff --git a/src/plugins/ios/iosplugin.cpp b/src/plugins/ios/iosplugin.cpp index a3412057d9a7387450ac6fff82ab880f53e25dad..5ac0b11b0c6a0bfc137e3baad65e1e179ceb94b0 100644 --- a/src/plugins/ios/iosplugin.cpp +++ b/src/plugins/ios/iosplugin.cpp @@ -69,6 +69,7 @@ bool IosPlugin::initialize(const QStringList &arguments, QString *errorMessage) Internal::IosConfigurations::initialize(); + addAutoReleasedObject(new Internal::IosToolChainFactory); addAutoReleasedObject(new Internal::IosRunControlFactory); addAutoReleasedObject(new Internal::IosRunConfigurationFactory); addAutoReleasedObject(new Internal::IosSettingsPage); diff --git a/src/plugins/ios/iosprobe.cpp b/src/plugins/ios/iosprobe.cpp index 49634dcfbc6389d269e7ba3aadf1e44a7b7f1fd7..d48e97a4a5c9ff16f464075154086f78b8cb04c4 100644 --- a/src/plugins/ios/iosprobe.cpp +++ b/src/plugins/ios/iosprobe.cpp @@ -290,4 +290,24 @@ QMap IosProbe::detectedPlatforms() 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); +} + } diff --git a/src/plugins/ios/iosprobe.h b/src/plugins/ios/iosprobe.h index 8f70f1fa8ee6747bef67c6bd77e8542d1768668c..2459c7c1e374c14bfe07d0032eae815d541b50f0 100644 --- a/src/plugins/ios/iosprobe.h +++ b/src/plugins/ios/iosprobe.h @@ -54,8 +54,14 @@ public: Utils::FileName compilerPath; QString architecture; 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 { public: