summaryrefslogtreecommitdiff
path: root/src/plugins
diff options
context:
space:
mode:
authorVikas Pachdha <vikas.pachdha@qt.io>2016-11-16 14:59:10 +0100
committerVikas Pachdha <vikas.pachdha@qt.io>2016-11-25 12:37:53 +0000
commit9f0bb3c93a1c4f69e2d523206fa31dbc779e2e9b (patch)
treeb1fcc5258cca3486a263c93c137b41c309f0b423 /src/plugins
parent38753d06a2badf6e33e34ed4c0b494aea5e41a64 (diff)
downloadqt-creator-9f0bb3c93a1c4f69e2d523206fa31dbc779e2e9b.tar.gz
iOS: Add C toolchain
To fix kits complaining about incorrect C compiler and ABI incompatibility Task-number: QTCREATORBUG-17135 Change-Id: I69ece613453463b97d193bb1740044d16f62172f Reviewed-by: Tobias Hunger <tobias.hunger@qt.io> Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/ios/iosconfigurations.cpp85
-rw-r--r--src/plugins/ios/iosprobe.cpp132
-rw-r--r--src/plugins/ios/iosprobe.h9
3 files changed, 143 insertions, 83 deletions
diff --git a/src/plugins/ios/iosconfigurations.cpp b/src/plugins/ios/iosconfigurations.cpp
index 0f0bf50502..0a8f45f2db 100644
--- a/src/plugins/ios/iosconfigurations.cpp
+++ b/src/plugins/ios/iosconfigurations.cpp
@@ -64,6 +64,7 @@ namespace {
Q_LOGGING_CATEGORY(kitSetupLog, "qtc.ios.kitSetup")
}
+using ToolChainPair = std::pair<ClangToolChain *, ClangToolChain *>;
namespace Ios {
namespace Internal {
@@ -89,7 +90,7 @@ static bool handledPlatform(const Platform &platform)
return deviceId(platform).isValid()
&& (platform.platformKind & Platform::BasePlatform) != 0
&& (platform.platformKind & Platform::Cxx11Support) == 0
- && platform.compilerPath.toString().contains(QLatin1String("clang"));
+ && platform.type == Platform::CLang;
}
static QList<Platform> handledPlatforms()
@@ -116,23 +117,31 @@ static QList<ClangToolChain *> autoDetectedIosToolChains()
});
}
-static ClangToolChain *findToolChainForPlatform(const Platform &platform, const QList<ClangToolChain *> &toolChains)
+static ToolChainPair 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();
- });
+ ToolChainPair platformToolChains;
+ auto toolchainMatch = [](ClangToolChain *toolChain, const Utils::FileName &compilerPath, const QStringList &flags) {
+ return compilerPath == toolChain->compilerCommand()
+ && flags == toolChain->platformCodeGenFlags()
+ && flags == toolChain->platformLinkerFlags();
+ };
+ platformToolChains.first = Utils::findOrDefault(toolChains, std::bind(toolchainMatch, std::placeholders::_1,
+ platform.cCompilerPath,
+ platform.backendFlags));
+ platformToolChains.second = Utils::findOrDefault(toolChains, std::bind(toolchainMatch, std::placeholders::_1,
+ platform.cxxCompilerPath,
+ platform.backendFlags));
+ return platformToolChains;
}
-static QHash<Platform, ClangToolChain *> findToolChains(const QList<Platform> &platforms)
+static QHash<Platform, ToolChainPair> findToolChains(const QList<Platform> &platforms)
{
- QHash<Platform, ClangToolChain *> platformToolChainHash;
+ QHash<Platform, ToolChainPair> platformToolChainHash;
const QList<ClangToolChain *> toolChains = autoDetectedIosToolChains();
foreach (const Platform &platform, platforms) {
- ClangToolChain *toolChain = findToolChainForPlatform(platform, toolChains);
- if (toolChain)
- platformToolChainHash.insert(platform, toolChain);
+ ToolChainPair platformToolchains = findToolChainForPlatform(platform, toolChains);
+ if (platformToolchains.first || platformToolchains.second)
+ platformToolChainHash.insert(platform, platformToolchains);
}
return platformToolChainHash;
}
@@ -173,11 +182,12 @@ static void printKits(const QSet<Kit *> &kits)
qCDebug(kitSetupLog) << " -" << kit->displayName();
}
-static void setupKit(Kit *kit, Core::Id pDeviceType, ClangToolChain *pToolchain,
+static void setupKit(Kit *kit, Core::Id pDeviceType, const ToolChainPair& toolChains,
const QVariant &debuggerId, const Utils::FileName &sdkPath, BaseQtVersion *qtVersion)
{
DeviceTypeKitInformation::setDeviceTypeId(kit, pDeviceType);
- ToolChainKitInformation::setToolChain(kit, pToolchain);
+ ToolChainKitInformation::setToolChain(kit, ToolChain::Language::C, toolChains.first);
+ ToolChainKitInformation::setToolChain(kit, ToolChain::Language::Cxx, toolChains.second);
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)
@@ -206,7 +216,7 @@ void IosConfigurations::updateAutomaticKitList()
qCDebug(kitSetupLog) << "Developer path:" << developerPath();
// platform name -> tool chain
- const QHash<Platform, ClangToolChain *> platformToolChainHash = findToolChains(platforms);
+ const QHash<Platform, ToolChainPair> platformToolChainHash = findToolChains(platforms);
const QHash<Abi::Architecture, QSet<BaseQtVersion *> > qtVersionsForArch = iosQtVersions();
qCDebug(kitSetupLog) << "iOS Qt versions:";
@@ -222,30 +232,32 @@ void IosConfigurations::updateAutomaticKitList()
// 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) {
+ const ToolChainPair &platformToolchains = platformToolChainHash.value(platform);
+ if (!platformToolchains.first && !platformToolchains.second) {
qCDebug(kitSetupLog) << " - No tool chain found";
continue;
}
Core::Id pDeviceType = deviceId(platform);
QTC_ASSERT(pDeviceType.isValid(), continue);
- Abi::Architecture arch = pToolchain->targetAbi().architecture();
+ Abi::Architecture arch = platformToolchains.second ? platformToolchains.second->targetAbi().architecture() :
+ platformToolchains.first->targetAbi().architecture();
QSet<BaseQtVersion *> 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) {
+ Kit *kit = Utils::findOrDefault(existingKits, [&pDeviceType, &platformToolchains, &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, ToolChain::Language::Cxx) == pToolchain
+ && ToolChainKitInformation::toolChain(kit, ToolChain::Language::Cxx) == platformToolchains.second
+ && ToolChainKitInformation::toolChain(kit, ToolChain::Language::C) == platformToolchains.first
&& 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);
+ setupKit(kit, pDeviceType, platformToolchains, debuggerId, platform.sdkPath, qtVersion);
kit->unblockNotification();
} else {
qCDebug(kitSetupLog) << " - Setting up new kit";
@@ -254,7 +266,7 @@ void IosConfigurations::updateAutomaticKitList()
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);
+ setupKit(kit, pDeviceType, platformToolchains, debuggerId, platform.sdkPath, qtVersion);
kit->unblockNotification();
KitManager::registerKit(kit);
}
@@ -350,14 +362,18 @@ void IosConfigurations::setDeveloperPath(const FileName &devPath)
}
}
-static ClangToolChain *createToolChain(const Platform &platform)
+static ClangToolChain *createToolChain(const Platform &platform, ToolChain::Language l)
{
+ if (l == ToolChain::Language::None)
+ return nullptr;
+
ClangToolChain *toolChain = new ClangToolChain(ToolChain::AutoDetection);
- toolChain->setLanguage(ToolChain::Language::Cxx);
- toolChain->setDisplayName(platform.name);
+ toolChain->setLanguage(l);
+ toolChain->setDisplayName(l == ToolChain::Language::Cxx ? platform.name + "++" : platform.name);
toolChain->setPlatformCodeGenFlags(platform.backendFlags);
toolChain->setPlatformLinkerFlags(platform.backendFlags);
- toolChain->resetToolChain(platform.compilerPath);
+ toolChain->resetToolChain(l == ToolChain::Language::Cxx ?
+ platform.cxxCompilerPath : platform.cCompilerPath);
return toolChain;
}
@@ -373,12 +389,17 @@ QList<ToolChain *> IosToolChainFactory::autoDetect(const QList<ToolChain *> &exi
QList<ClangToolChain *> toolChains;
toolChains.reserve(platforms.size());
foreach (const Platform &platform, platforms) {
- ClangToolChain *toolChain = findToolChainForPlatform(platform, existingClangToolChains);
- if (!toolChain) {
- toolChain = createToolChain(platform);
- existingClangToolChains.append(toolChain);
- }
- toolChains.append(toolChain);
+ ToolChainPair platformToolchains = findToolChainForPlatform(platform, existingClangToolChains);
+ auto createOrAdd = [&](ClangToolChain* toolChain, ToolChain::Language l) {
+ if (!toolChain) {
+ toolChain = createToolChain(platform, l);
+ existingClangToolChains.append(toolChain);
+ }
+ toolChains.append(toolChain);
+ };
+
+ createOrAdd(platformToolchains.first, ToolChain::Language::C);
+ createOrAdd(platformToolchains.second, ToolChain::Language::Cxx);
}
return Utils::transform(toolChains, [](ClangToolChain *tc) -> ToolChain * { return tc; });
}
diff --git a/src/plugins/ios/iosprobe.cpp b/src/plugins/ios/iosprobe.cpp
index a8be1f7b2a..291b43d550 100644
--- a/src/plugins/ios/iosprobe.cpp
+++ b/src/plugins/ios/iosprobe.cpp
@@ -116,17 +116,26 @@ void IosProbe::setupDefaultToolchains(const QString &devPath, const QString &xco
qCDebug(probeLog) << QString::fromLatin1("Setting up platform \"%1\".").arg(xcodeName);
QString indent = QLatin1String(" ");
+ auto getClangInfo = [devPath, indent](const QString &compiler) {
+ QFileInfo compilerInfo(devPath
+ + QLatin1String("/Toolchains/XcodeDefault.xctoolchain/usr/bin/")
+ + compiler);
+ if (!compilerInfo.exists())
+ qCWarning(probeLog) << indent << QString::fromLatin1("Default toolchain %1 not found.")
+ .arg(compilerInfo.canonicalFilePath());
+ return compilerInfo;
+ };
+
// detect clang (default toolchain)
- QFileInfo clangFileInfo(devPath
- + QLatin1String("/Toolchains/XcodeDefault.xctoolchain/usr/bin")
- + QLatin1String("/clang++"));
- bool hasClang = clangFileInfo.exists();
- if (!hasClang)
- qCWarning(probeLog) << indent << QString::fromLatin1("Default toolchain %1 not found.")
- .arg(clangFileInfo.canonicalFilePath());
+ const QFileInfo clangCppInfo = getClangInfo("clang++");
+ const bool hasClangCpp = clangCppInfo.exists();
+
+ const QFileInfo clangCInfo = getClangInfo("clang");
+ const bool hasClangC = clangCInfo.exists();
+
// Platforms
- QDir platformsDir(devPath + QLatin1String("/Platforms"));
- QFileInfoList platforms = platformsDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
+ const QDir platformsDir(devPath + QLatin1String("/Platforms"));
+ const QFileInfoList platforms = platformsDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
foreach (const QFileInfo &fInfo, platforms) {
if (fInfo.isDir() && fInfo.suffix() == QLatin1String("platform")) {
qCDebug(probeLog) << indent << QString::fromLatin1("Setting up %1").arg(fInfo.fileName());
@@ -159,14 +168,20 @@ void IosProbe::setupDefaultToolchains(const QString &devPath, const QString &xco
defaultProp[i.key()] = i.value();
}
- QString clangFullName = name + QLatin1String("-clang") + xcodeName;
- QString clang11FullName = name + QLatin1String("-clang11") + xcodeName;
+ const QString clangFullName = name + QLatin1String("-clang") + xcodeName;
+ const 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();
+ QFileInfo gccCppInfo(fInfo.absoluteFilePath() + QLatin1String("/Developer/usr/bin/g++"));
+ if (!gccCppInfo.exists())
+ gccCppInfo = QFileInfo(devPath + QLatin1String("/usr/bin/g++"));
+ const bool hasGccCppCompiler = gccCppInfo.exists();
+
+ QFileInfo gccCInfo(fInfo.absoluteFilePath() + QLatin1String("/Developer/usr/bin/gcc"));
+ if (!gccCInfo.exists())
+ gccCInfo = QFileInfo(devPath + QLatin1String("/usr/bin/gcc"));
+ const bool hasGccCCompiler = gccCInfo.exists();
+
+ const QString gccFullName = name + QLatin1String("-gcc") + xcodeName;
QStringList extraFlags;
if (defaultProp.contains(QLatin1String("NATIVE_ARCH"))) {
@@ -178,45 +193,58 @@ void IosProbe::setupDefaultToolchains(const QString &devPath, const QString &xco
// don't generate a toolchain for 64 bit (to fix when we support that)
extraFlags << QLatin1String("-arch") << QLatin1String("i386");
}
- if (hasClang) {
+
+ auto getArch = [extraFlags](const QFileInfo &compiler) {
+ QStringList flags = extraFlags;
+ flags << QLatin1String("-dumpmachine");
+ const QStringList compilerTriplet = qsystem(compiler.canonicalFilePath(), flags)
+ .simplified().split(QLatin1Char('-'));
+ return compilerTriplet.value(0);
+ };
+
+ if (hasClangCpp || hasClangC) {
Platform clangProfile;
+ clangProfile.type = Platform::CLang;
clangProfile.developerPath = Utils::FileName::fromString(devPath);
clangProfile.platformKind = 0;
- clangProfile.name = clangFullName;
clangProfile.platformPath = Utils::FileName(fInfo);
- clangProfile.compilerPath = Utils::FileName(clangFileInfo);
- QStringList flags = extraFlags;
- flags << QLatin1String("-dumpmachine");
- QString compilerTriplet = qsystem(clangFileInfo.canonicalFilePath(), flags)
- .simplified();
- QStringList compilerTripletl = compilerTriplet.split(QLatin1Char('-'));
- clangProfile.architecture = compilerTripletl.value(0);
+ clangProfile.architecture = getArch(hasClangCpp ? clangCppInfo : clangCInfo);
clangProfile.backendFlags = extraFlags;
qCDebug(probeLog) << indent << QString::fromLatin1("* adding profile %1").arg(clangProfile.name);
- 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;
- m_platforms[clangProfile.name] = clangProfile;
+ clangProfile.name = clangFullName;
+ if (hasClangC) {
+ clangProfile.cCompilerPath = Utils::FileName(clangCInfo);
+ m_platforms[clangFullName] = clangProfile;
+ }
+ if (hasClangCpp) {
+ clangProfile.cxxCompilerPath = Utils::FileName(clangCppInfo);
+ m_platforms[clangFullName] = clangProfile;
+ clangProfile.platformKind |= Platform::Cxx11Support;
+ clangProfile.backendFlags.append(QLatin1String("-std=c++11"));
+ clangProfile.backendFlags.append(QLatin1String("-stdlib=libc++"));
+ clangProfile.name = clang11FullName;
+ m_platforms[clang11FullName] = clangProfile;
+ }
}
- if (hasGcc) {
+
+ if (hasGccCppCompiler || hasGccCCompiler) {
Platform gccProfile;
+ gccProfile.type = Platform::GCC;
gccProfile.developerPath = Utils::FileName::fromString(devPath);
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.compilerPath = Utils::FileName(gccFileInfo);
- QStringList flags = extraFlags;
- flags << QLatin1String("-dumpmachine");
- QString compilerTriplet = qsystem(gccFileInfo.canonicalFilePath(), flags)
- .simplified();
- QStringList compilerTripletl = compilerTriplet.split(QLatin1Char('-'));
- gccProfile.architecture = compilerTripletl.value(0);
+ gccProfile.architecture = getArch(hasGccCppCompiler ? gccCppInfo : gccCInfo);
gccProfile.backendFlags = extraFlags;
qCDebug(probeLog) << indent << QString::fromLatin1("* adding profile %1").arg(gccProfile.name);
- m_platforms[gccProfile.name] = gccProfile;
+ if (hasGccCppCompiler) {
+ gccProfile.cxxCompilerPath = Utils::FileName(gccCppInfo);
+ }
+ if (hasGccCCompiler) {
+ gccProfile.cCompilerPath = Utils::FileName(gccCInfo);
+ }
+ m_platforms[gccFullName] = gccProfile;
}
// set SDKs/sysroot
@@ -262,15 +290,18 @@ void IosProbe::setupDefaultToolchains(const QString &devPath, const QString &xco
if (sysRoot.isEmpty() && !sdkName.isEmpty())
qCDebug(probeLog) << indent << QString::fromLatin1("Failed to find sysroot %1").arg(sdkName);
}
- if (hasClang && !sysRoot.isEmpty()) {
- m_platforms[clangFullName].platformKind |= Platform::BasePlatform;
- m_platforms[clangFullName].sdkPath = Utils::FileName::fromString(sysRoot);
- m_platforms[clang11FullName].platformKind |= Platform::BasePlatform;
- m_platforms[clang11FullName].sdkPath = Utils::FileName::fromString(sysRoot);
- }
- if (hasGcc && !sysRoot.isEmpty()) {
- m_platforms[gccFullName].platformKind |= Platform::BasePlatform;
- m_platforms[gccFullName].sdkPath = Utils::FileName::fromString(sysRoot);
+
+ if (!sysRoot.isEmpty()) {
+ auto itr = m_platforms.begin();
+ while (itr != m_platforms.end()) {
+ if (itr.key() == clangFullName ||
+ itr.key() == clang11FullName ||
+ itr.key() == gccFullName) {
+ itr.value().platformKind |= Platform::BasePlatform;
+ itr.value().sdkPath = Utils::FileName::fromString(sysRoot);
+ }
+ ++itr;
+ }
}
}
indent = QLatin1String(" ");
@@ -293,7 +324,8 @@ QDebug operator<<(QDebug debug, const Platform &platform)
{
QDebugStateSaver saver(debug); Q_UNUSED(saver)
debug.nospace() << "(name=" << platform.name
- << ", compiler=" << platform.compilerPath.toString()
+ << ", C++ compiler=" << platform.cxxCompilerPath.toString()
+ << ", C compiler=" << platform.cCompilerPath.toString()
<< ", flags=" << platform.backendFlags
<< ")";
return debug;
diff --git a/src/plugins/ios/iosprobe.h b/src/plugins/ios/iosprobe.h
index 8d192b9611..be4110e676 100644
--- a/src/plugins/ios/iosprobe.h
+++ b/src/plugins/ios/iosprobe.h
@@ -40,13 +40,20 @@ public:
Cxx11Support = 1 << 1
};
+ enum CompilerType {
+ CLang,
+ GCC
+ };
+
quint32 platformKind;
+ CompilerType type;
QString name;
Utils::FileName developerPath;
Utils::FileName platformPath;
Utils::FileName sdkPath;
Utils::FileName defaultToolchainPath;
- Utils::FileName compilerPath;
+ Utils::FileName cxxCompilerPath;
+ Utils::FileName cCompilerPath;
QString architecture;
QStringList backendFlags;