Example #1
0
void IosProbe::setupDefaultToolchains(const QString &devPath, const QString &xcodeName)
{
    qCDebug(probeLog) << 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();
    if (!hasClang)
        qCWarning(probeLog) << 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")) {
            qCDebug(probeLog) << indent << QString::fromLatin1("Setting up %1").arg(fInfo.fileName());
            QSettings infoSettings(fInfo.absoluteFilePath() + QLatin1String("/Info.plist"),
                                   QSettings::NativeFormat);
            if (!infoSettings.contains(QLatin1String("Name"))) {
                qCWarning(probeLog) << indent << QString::fromLatin1("Missing platform name in Info.plist of %1")
                             .arg(fInfo.absoluteFilePath());
                continue;
            }
            QString name = infoSettings.value(QLatin1String("Name")).toString();
            if (name != QLatin1String("macosx") && name != QLatin1String("iphoneos")
                    && name != QLatin1String("iphonesimulator"))
            {
                qCDebug(probeLog) << indent << QString::fromLatin1("Skipping unknown platform %1").arg(name);
                continue;
            }

            const QString platformSdkVersion = infoSettings.value(QLatin1String("Version")).toString();

            // prepare default platform properties
            QVariantMap defaultProp = infoSettings.value(QLatin1String("DefaultProperties"))
                    .toMap();
            QVariantMap overrideProp = infoSettings.value(QLatin1String("OverrideProperties"))
                    .toMap();
            QMapIterator<QString, QVariant> 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("NATIVE_ARCH"))) {
                QString arch = defaultProp.value(QLatin1String("NATIVE_ARCH")).toString();
                if (!arch.startsWith(QLatin1String("arm")))
                    qCWarning(probeLog) << indent << QString::fromLatin1("Expected arm architecture, not %1").arg(arch);
                extraFlags << QLatin1String("-arch") << arch;
            } else if (name == QLatin1String("iphonesimulator")) {
                // don't generate a toolchain for 64 bit (to fix when we support that)
                extraFlags << QLatin1String("-arch") << QLatin1String("i386");
            }
            if (hasClang) {
                Platform clangProfile;
                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.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;
            }
            if (hasGcc) {
                Platform gccProfile;
                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.backendFlags = extraFlags;
                qCDebug(probeLog) << indent << QString::fromLatin1("* adding profile %1").arg(gccProfile.name);
                m_platforms[gccProfile.name] = gccProfile;
            }

            // set SDKs/sysroot
            QString sysRoot;
            {
                QString sdkName;
                if (defaultProp.contains(QLatin1String("SDKROOT")))
                    sdkName = defaultProp.value(QLatin1String("SDKROOT")).toString();
                QString sdkPath;
                QString sdkPathWithSameVersion;
                QDir sdks(fInfo.absoluteFilePath() + QLatin1String("/Developer/SDKs"));
                QString maxVersion;
                foreach (const QFileInfo &sdkDirInfo, sdks.entryInfoList(QDir::Dirs
                                                                         | QDir::NoDotAndDotDot)) {
                    indent = QLatin1String("    ");
                    QSettings sdkInfo(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) {
                        qCDebug(probeLog) << indent << QString::fromLatin1("Skipping non base Sdk %1")
                                                .arg(currentSdkName.toString());
                        continue;
                    }
                    if (sdkName.isEmpty()) {
                        if (maxVersion.isEmpty() || compareVersions(maxVersion, versionStr) > 0) {
                            maxVersion = versionStr;
                            sdkPath = sdkDirInfo.canonicalFilePath();
                        }
                    } else if (currentSdkName == sdkName) {
                        sdkPath = sdkDirInfo.canonicalFilePath();
                    } else if (currentSdkName.toString().startsWith(sdkName) /*if sdkName doesn't contain version*/
                            && compareVersions(platformSdkVersion, versionStr) == 0)
                        sdkPathWithSameVersion = sdkDirInfo.canonicalFilePath();
                }
                if (sdkPath.isEmpty())
                    sysRoot = sdkPathWithSameVersion;
                else
                    sysRoot = sdkPath;
                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);
            }
        }
        indent = QLatin1String("  ");
    }
Example #2
0
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();
    if (!hasClang)
        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 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<QString, QVariant> 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.developerPath = Utils::FileName::fromString(devPath);
                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);
                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;
            }
            if (hasGcc) {
                Platform gccProfile;
                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.platformInfo = infoSettings;
                gccProfile.compilerPath = Utils::FileName(gccFileInfo);
                setArch(&gccProfile, gccFileInfo.canonicalFilePath(), extraFlags);
                if (debugProbe)
                    qDebug() << indent << QString::fromLatin1("* adding profile %1").arg(gccProfile.name);
                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 = 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);
                        m_platforms[pSdk.name] = pSdk;
                        pSdk.backendFlags.append(QLatin1String("-std=c++11"));
                        pSdk.backendFlags.append(QLatin1String("-stdlib=libc++"));
                        pSdk.name = safeName + QLatin1String("-clang11") + xcodeName;
                        m_platforms[pSdk.name] = pSdk;
                    }
                    if (hasGcc) {
                        Platform pSdk;
                        pSdk = 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);
                        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);
            }
            //m_platforms.remove(clangFullName);
            if (hasClang && !sysRoot.isEmpty()) {
                m_platforms[clangFullName].platformKind |= Platform::BasePlatform;
                m_platforms[clangFullName].sdkPath = Utils::FileName::fromString(sysRoot);
                m_platforms[clangFullName].sdkSettings = sdkSettings;
                m_platforms[clang11FullName].platformKind |= Platform::BasePlatform;
                m_platforms[clang11FullName].sdkPath = Utils::FileName::fromString(sysRoot);
                m_platforms[clang11FullName].sdkSettings = sdkSettings;
            }
            //m_platforms.remove(gccFullName);
            if (hasGcc && !sysRoot.isEmpty()) {
                m_platforms[gccFullName].platformKind |= Platform::BasePlatform;
                m_platforms[gccFullName].sdkPath = Utils::FileName::fromString(sysRoot);
                m_platforms[gccFullName].sdkSettings = sdkSettings;
            }
        }
        indent = QLatin1String("  ");
    }
}