Skip to content
Snippets Groups Projects
qtversionmanager.cpp 60 KiB
Newer Older
        } else if (part == "-after") {
            after = true;
        } else if(part.contains('=')) {
            if (regExp.exactMatch(part)) {
                QMakeAssignment qa;
                qa.variable = regExp.cap(1);
                qa.op = regExp.cap(2);
                qa.value = regExp.cap(3).trimmed();
                if (after)
                    afterAssignments->append(qa);
                else
                    assignments->append(qa);
            } else {
                qDebug()<<"regexp did not match";
            }
        } else if (part == "-o") {
            ignoreNext = true;
        } else {
            additionalArguments->append(part);
        }
    }
#if defined(Q_OS_WIN32)
    additionalArguments->removeAll("-win32");
#elif defined(Q_OS_MAC)
    additionalArguments->removeAll("-macx");
#elif defined(Q_OS_QNX6)
    additionalArguments->removeAll("-qnx6");
#else
    additionalArguments->removeAll("-unix");
#endif
}

/// This function extracts all the CONFIG+=debug, CONFIG+=release
QtVersion::QmakeBuildConfigs QtVersionManager::qmakeBuildConfigFromCmdArgs(QList<QMakeAssignment> *assignments, QtVersion::QmakeBuildConfigs defaultBuildConfig)
    QtVersion::QmakeBuildConfigs result = defaultBuildConfig;
    QList<QMakeAssignment> oldAssignments = *assignments;
    assignments->clear();
    foreach(const QMakeAssignment &qa, oldAssignments) {
        if (qa.variable == "CONFIG") {
            QStringList values = qa.value.split(' ');
            QStringList newValues;
            foreach(const QString &value, values) {
                if (value == "debug") {
                    if (qa.op == "+=")
                        result = result  | QtVersion::DebugBuild;
                        result = result  & ~QtVersion::DebugBuild;
                } else if (value == "release") {
                    if (qa.op == "+=")
                        result = result & ~QtVersion::DebugBuild;
                        result = result | QtVersion::DebugBuild;
                } else if (value == "debug_and_release") {
                    if (qa.op == "+=")
                        result = result | QtVersion::BuildAll;
                        result = result & ~QtVersion::BuildAll;
                } else {
                    newValues.append(value);
con's avatar
con committed
                }
                QMakeAssignment newQA = qa;
                newQA.value = newValues.join(" ");
                if (!newValues.isEmpty())
                    assignments->append(newQA);
con's avatar
con committed
            }
        } else {
            assignments->append(qa);
con's avatar
con committed
        }
    }
    return result;
}

static bool queryQMakeVariables(const QString &binary, QHash<QString, QString> *versionInfo)
con's avatar
con committed
{
    const int timeOutMS = 30000; // Might be slow on some machines.
    QFileInfo qmake(binary);
    if (!qmake.exists() || !qmake.isExecutable())
        return false;
    static const char * const variables[] = {
             "QT_INSTALL_DATA",
             "QT_INSTALL_LIBS",
             "QT_INSTALL_HEADERS",
             "QT_INSTALL_DEMOS",
             "QT_INSTALL_EXAMPLES",
             "QT_INSTALL_CONFIGURATION",
             "QT_INSTALL_TRANSLATIONS",
             "QT_INSTALL_PLUGINS",
             "QT_INSTALL_BINS",
             "QT_INSTALL_DOCS",
dt's avatar
dt committed
             "QT_INSTALL_PREFIX",
             "QMAKEFEATURES"
    QStringList args;
    for (uint i = 0; i < sizeof variables / sizeof variables[0]; ++i)
        args << "-query" << variables[i];
    QProcess process;
    process.start(qmake.absoluteFilePath(), args, QIODevice::ReadOnly);
    if (!process.waitForStarted()) {
        qWarning("Cannot start '%s': %s", qPrintable(binary), qPrintable(process.errorString()));
        return false;
    }
    if (!process.waitForFinished(timeOutMS)) {
        Utils::SynchronousProcess::stopProcess(process);
        qWarning("Timeout running '%s' (%dms).", qPrintable(binary), timeOutMS);
        return false;
    }
    if (process.exitStatus() != QProcess::NormalExit) {
        qWarning("'%s' crashed.", qPrintable(binary));
        return false;
    }
    QByteArray output = process.readAllStandardOutput();
    QTextStream stream(&output);
    while (!stream.atEnd()) {
        const QString line = stream.readLine();
        const int index = line.indexOf(QLatin1Char(':'));
        if (index != -1) {
            const QString value = QDir::fromNativeSeparators(line.mid(index+1));
            if (value != "**Unknown**")
                versionInfo->insert(line.left(index), value);
con's avatar
con committed
        }
    }
    return true;
}

void QtVersion::updateVersionInfo() const
{
    if (m_versionInfoUpToDate)
        return;
con's avatar
con committed

    // extract data from qmake executable
    m_versionInfo.clear();
    m_notInstalled = false;
    m_hasExamples = false;
    m_hasDocumentation = false;
    m_hasDebuggingHelper = false;
    m_hasQmlDump = false;
    m_hasQmlObserver = false;
    if (!queryQMakeVariables(qmakeCommand(), &m_versionInfo))
        return;
con's avatar
con committed

    if (m_versionInfo.contains("QT_INSTALL_DATA")) {
        QString qtInstallData = m_versionInfo.value("QT_INSTALL_DATA");
        m_versionInfo.insert("QMAKE_MKSPECS", QDir::cleanPath(qtInstallData+"/mkspecs"));

        if (!qtInstallData.isEmpty()) {
            m_hasDebuggingHelper = !DebuggingHelperLibrary::debuggingHelperLibraryByInstallData(qtInstallData).isEmpty();
            m_hasQmlDump = !QmlDumpTool::toolByInstallData(qtInstallData).isEmpty();
            m_hasQmlObserver = !QmlObserverTool::toolByInstallData(qtInstallData).isEmpty();
    }

    // Now check for a qt that is configured with a prefix but not installed
    if (m_versionInfo.contains("QT_INSTALL_BINS")) {
        QFileInfo fi(m_versionInfo.value("QT_INSTALL_BINS"));
        if (!fi.exists())
            m_notInstalled = true;
    }
    if (m_versionInfo.contains("QT_INSTALL_HEADERS")){
        QFileInfo fi(m_versionInfo.value("QT_INSTALL_HEADERS"));
        if (!fi.exists())
            m_notInstalled = true;
    }
    if (m_versionInfo.contains("QT_INSTALL_DOCS")){
        QFileInfo fi(m_versionInfo.value("QT_INSTALL_DOCS"));
        if (fi.exists())
            m_hasDocumentation = true;
    }
    if (m_versionInfo.contains("QT_INSTALL_EXAMPLES")){
        QFileInfo fi(m_versionInfo.value("QT_INSTALL_EXAMPLES"));
        if (fi.exists())
            m_hasExamples = true;
    }
    if (m_versionInfo.contains("QT_INSTALL_DEMOS")){
        QFileInfo fi(m_versionInfo.value("QT_INSTALL_DEMOS"));
        if (fi.exists())
            m_hasDemos = true;
con's avatar
con committed
    }
con's avatar
con committed
    m_versionInfoUpToDate = true;
}

QString QtVersion::findQtBinary(const QStringList &possibleCommands) const
{
    const QString qtdirbin = versionInfo().value(QLatin1String("QT_INSTALL_BINS")) + QLatin1Char('/');
    foreach (const QString &possibleCommand, possibleCommands) {
        const QString fullPath = qtdirbin + possibleCommand;
        if (QFileInfo(fullPath).isFile())
            return QDir::cleanPath(fullPath);
    }
    return QString();
dt's avatar
dt committed
QString QtVersion::uicCommand() const
{
    if (!isValid())
        return QString();
dt's avatar
dt committed
    if (!m_uicCommand.isNull())
        return m_uicCommand;
#ifdef Q_OS_WIN
    const QStringList possibleCommands(QLatin1String("uic.exe"));
#else
dt's avatar
dt committed
    QStringList possibleCommands;
    possibleCommands << QLatin1String("uic-qt4") << QLatin1String("uic4") << QLatin1String("uic");
#endif
    m_uicCommand = findQtBinary(possibleCommands);
    return m_uicCommand;
}

// Return a list of GUI binary names
// 'foo', 'foo.exe', 'Foo.app/Contents/MacOS/Foo'
static inline QStringList possibleGuiBinaries(const QString &name)
{
dt's avatar
dt committed
#ifdef Q_OS_WIN
    return QStringList(name + QLatin1String(".exe"));
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
#elif defined(Q_OS_MAC) // 'Foo.app/Contents/MacOS/Foo'
    QString upCaseName = name;
    upCaseName[0] = upCaseName.at(0).toUpper();
    QString macBinary = upCaseName;
    macBinary += QLatin1String(".app/Contents/MacOS/");
    macBinary += upCaseName;
    return QStringList(macBinary);
dt's avatar
dt committed
#else
    return QStringList(name);
dt's avatar
dt committed
#endif
}

QString QtVersion::designerCommand() const
{
    if (!isValid())
        return QString();
    if (m_designerCommand.isNull())
        m_designerCommand = findQtBinary(possibleGuiBinaries(QLatin1String("designer")));
    return m_designerCommand;
}

QString QtVersion::linguistCommand() const
{
    if (!isValid())
        return QString();
    if (m_linguistCommand.isNull())
        m_linguistCommand = findQtBinary(possibleGuiBinaries(QLatin1String("linguist")));
    return m_linguistCommand;
QString QtVersion::qmlviewerCommand() const
{
    if (!isValid())
        return QString();
    if (m_qmlviewerCommand.isNull()) {
#ifdef Q_OS_MAC
        const QString qmlViewerName = QLatin1String("QMLViewer");
#else
        const QString qmlViewerName = QLatin1String("qmlviewer");
#endif

        m_qmlviewerCommand = findQtBinary(possibleGuiBinaries(qmlViewerName));
    }
    return m_qmlviewerCommand;
}

Tobias Hunger's avatar
Tobias Hunger committed
bool QtVersion::supportsTargetId(const QString &id) const
{
    updateToolChainAndMkspec();
    return m_targetIds.contains(id);
Tobias Hunger's avatar
Tobias Hunger committed
}

QSet<QString> QtVersion::supportedTargetIds() const
{
    updateToolChainAndMkspec();
    return m_targetIds;
bool QtVersion::supportsMobileTarget() const
{
    return supportsTargetId(Constants::S60_DEVICE_TARGET_ID) ||
           supportsTargetId(Constants::S60_EMULATOR_TARGET_ID) ||
           supportsTargetId(Constants::MAEMO_DEVICE_TARGET_ID) ||
	   supportsTargetId(Constants::QT_SIMULATOR_TARGET_ID);
QList<QSharedPointer<ProjectExplorer::ToolChain> > QtVersion::toolChains() const
dt's avatar
dt committed
    updateToolChainAndMkspec();
ProjectExplorer::ToolChain *QtVersion::toolChain(ProjectExplorer::ToolChain::ToolChainType type) const
{
    foreach(const QSharedPointer<ProjectExplorer::ToolChain> &tcptr, toolChains())
        if (tcptr->type() == type)
            return tcptr.data();
    return 0;
}

QList<ProjectExplorer::ToolChain::ToolChainType> QtVersion::possibleToolChainTypes() const
con's avatar
con committed
{
    QList<ProjectExplorer::ToolChain::ToolChainType> types;
    foreach(const QSharedPointer<ProjectExplorer::ToolChain> &tc, toolChains())
        types << tc->type();
    return types;
}

// if none, then it's INVALID everywhere this function is called
dt's avatar
dt committed
void QtVersion::updateToolChainAndMkspec() const
    typedef QSharedPointer<ProjectExplorer::ToolChain> ToolChainPtr;
Tobias Hunger's avatar
Tobias Hunger committed
    m_toolChains.clear();
    m_targetIds.clear();
    if (!isValid()) {
        m_targetIds.insert(Constants::DESKTOP_TARGET_ID);
dt's avatar
dt committed
        return;
dt's avatar
dt committed

dt's avatar
dt committed
//    qDebug()<<"Finding mkspec for"<<qmakeCommand();
dt's avatar
dt committed

    // no .qmake.cache so look at the default mkspec

    QString baseMkspecDir = versionInfo().value("QMAKE_MKSPECS");
    if (baseMkspecDir.isEmpty())
        baseMkspecDir = versionInfo().value("QT_INSTALL_DATA") + "/mkspecs";

dt's avatar
dt committed
#ifdef Q_OS_WIN
    baseMkspecDir = baseMkspecDir.toLower();
#endif

dt's avatar
dt committed
    QString mkspecFullPath = baseMkspecDir + "/default";

    // qDebug() << "default mkspec is located at" << mkspecFullPath;

#ifdef Q_OS_WIN
    QFile f2(mkspecFullPath + "/qmake.conf");
    if (f2.exists() && f2.open(QIODevice::ReadOnly)) {
        while (!f2.atEnd()) {
            QByteArray line = f2.readLine();
            if (line.startsWith("QMAKESPEC_ORIGINAL")) {
                const QList<QByteArray> &temp = line.split('=');
                if (temp.size() == 2) {
                    QString possibleFullPath = temp.at(1).trimmed();
                    // We sometimes get a mix of different slash styles here...
                    possibleFullPath = possibleFullPath.replace('\\', '/');
                    if (QFileInfo(possibleFullPath).exists()) // Only if the path exists
Robert Loehning's avatar
Robert Loehning committed
                        mkspecFullPath = possibleFullPath;
dt's avatar
dt committed
                }
                break;
            }
        }
        f2.close();
    }
#elif defined(Q_OS_MAC)
    QFile f2(mkspecFullPath + "/qmake.conf");
    if (f2.exists() && f2.open(QIODevice::ReadOnly)) {
        while (!f2.atEnd()) {
            QByteArray line = f2.readLine();
            if (line.startsWith("MAKEFILE_GENERATOR")) {
                const QList<QByteArray> &temp = line.split('=');
                if (temp.size() == 2) {
                    const QByteArray &value = temp.at(1);
                    if (value.contains("XCODE")) {
                        // we don't want to generate xcode projects...
//                      qDebug() << "default mkspec is xcode, falling back to g++";
                        mkspecFullPath = baseMkspecDir + "/macx-g++";
                    }
                    //resolve mkspec link
                    QFileInfo f3(mkspecFullPath);
                    while (f3.isSymLink()) {
                        mkspecFullPath = f3.symLinkTarget();
                        f3.setFile(mkspecFullPath);
                    }
                }
                break;
            }
        }
        f2.close();
    }
#else
    QFileInfo f2(mkspecFullPath);
    while (f2.isSymLink()) {
        mkspecFullPath = f2.symLinkTarget();
        f2.setFile(mkspecFullPath);
    }
#endif

#ifdef Q_OS_WIN
dt's avatar
dt committed
    mkspecFullPath = mkspecFullPath.toLower();
dt's avatar
dt committed
#endif

    m_mkspecFullPath = mkspecFullPath;
    QString mkspec = m_mkspecFullPath;

    if (mkspec.startsWith(baseMkspecDir)) {
        mkspec = mkspec.mid(baseMkspecDir.length() + 1);
dt's avatar
dt committed
//        qDebug() << "Setting mkspec to"<<mkspec;
dt's avatar
dt committed
    } else {
        QString sourceMkSpecPath = sourcePath() + "/mkspecs";
        if (mkspec.startsWith(sourceMkSpecPath)) {
            mkspec = mkspec.mid(sourceMkSpecPath.length() + 1);
        } else {
            // Do nothing
        }
    }

    m_mkspec = mkspec;

    m_isBuildUsingSbsV2 = false;

dt's avatar
dt committed
//    qDebug()<<"mkspec for "<<qmakeCommand()<<" is "<<m_mkspec<<m_mkspecFullPath;
    ProFileOption option;
    option.properties = versionInfo();
    ProMessageHandler msgHandler(true);
    ProFileCacheManager::instance()->incRefCount();
    ProFileParser parser(ProFileCacheManager::instance()->cache(), &msgHandler);
    ProFileEvaluator evaluator(&option, &parser, &msgHandler);
    if (ProFile *pro = parser.parsedProFile(m_mkspecFullPath + "/qmake.conf")) {
        evaluator.setCumulative(false);
        evaluator.accept(pro, ProFileEvaluator::LoadProOnly);
    QString qmakeCXX = evaluator.values("QMAKE_CXX").join(" ");
    QString makefileGenerator = evaluator.value("MAKEFILE_GENERATOR");
    QString ce_sdk = evaluator.values("CE_SDK").join(QLatin1String(" "));
    QString ce_arch = evaluator.value("CE_ARCH");
    QString qt_arch = evaluator.value("QT_ARCH");
    if (!ce_sdk.isEmpty() && !ce_arch.isEmpty()) {
        QString wincePlatformName = ce_sdk + " (" + ce_arch + QLatin1Char(')');
        m_toolChains << ToolChainPtr(ProjectExplorer::ToolChain::createWinCEToolChain(msvcVersion(), wincePlatformName));
        m_targetIds.insert(Constants::DESKTOP_TARGET_ID);
    } else if (makefileGenerator == QLatin1String("SYMBIAN_ABLD") ||
               makefileGenerator == QLatin1String("SYMBIAN_SBSV2") ||
               makefileGenerator == QLatin1String("SYMBIAN_UNIX")) {
        m_isBuildUsingSbsV2 = (makefileGenerator == QLatin1String("SYMBIAN_SBSV2"));
        if (S60Manager *s60mgr = S60Manager::instance()) {
#    ifdef Q_OS_WIN
            m_targetIds.insert(QLatin1String(Constants::S60_DEVICE_TARGET_ID));
            m_toolChains << ToolChainPtr(s60mgr->createGCCEToolChain(this));
            if (S60Manager::hasRvctCompiler())
Tobias Hunger's avatar
Tobias Hunger committed
                m_toolChains << ToolChainPtr(s60mgr->createRVCTToolChain(this, ProjectExplorer::ToolChain::RVCT_ARMV5))
                             << ToolChainPtr(s60mgr->createRVCTToolChain(this, ProjectExplorer::ToolChain::RVCT_ARMV6));
            if (!mwcDirectory().isEmpty()) {
Tobias Hunger's avatar
Tobias Hunger committed
                m_toolChains << ToolChainPtr(s60mgr->createWINSCWToolChain(this));
                m_targetIds.insert(QLatin1String(Constants::S60_EMULATOR_TARGET_ID));
            if (S60Manager::hasRvctCompiler())
                m_toolChains << ToolChainPtr(s60mgr->createRVCTToolChain(this, ProjectExplorer::ToolChain::RVCT_ARMV5_GNUPOC));
            m_toolChains << ToolChainPtr(s60mgr->createGCCE_GnuPocToolChain(this));
            m_targetIds.insert(QLatin1String(Constants::S60_DEVICE_TARGET_ID));
    } else if (qt_arch.startsWith(QLatin1String("arm"))
               && MaemoManager::instance().isValidMaemoQtVersion(this)) {
        m_toolChains << ToolChainPtr(MaemoManager::instance().maemoToolChain(this));
        m_targetIds.insert(QLatin1String(Constants::MAEMO_DEVICE_TARGET_ID));
    } else if (qmakeCXX == "cl" || qmakeCXX == "icl") {
        // TODO proper support for intel cl. Detect matching VC version unless set.
        if (m_msvcVersion.isEmpty())
            m_msvcVersion = ProjectExplorer::MSVCToolChain::findInstallationByMkSpec(isQt64Bit(), mkspec).name;
        m_toolChains << ToolChainPtr(
                ProjectExplorer::ToolChain::createMSVCToolChain(m_msvcVersion, isQt64Bit()));
        m_targetIds.insert(QLatin1String(Constants::DESKTOP_TARGET_ID));
    } else if (qmakeCXX == "g++" && makefileGenerator == "MINGW") {
        Utils::Environment env = Utils::Environment::systemEnvironment();
        //addToEnvironment(env);
        env.prependOrSetPath(mingwDirectory() + "/bin");
        qmakeCXX = env.searchInPath(qmakeCXX);
        m_toolChains << ToolChainPtr(
                ProjectExplorer::ToolChain::createMinGWToolChain(qmakeCXX, mingwDirectory()));
        m_targetIds.insert(QLatin1String(Constants::DESKTOP_TARGET_ID));
dt's avatar
dt committed
    } else if (qmakeCXX.contains("g++")) { // All g++ variants are treated as desktop g++
                                           // we should try to do a better job, but for now that's good enough
        Utils::Environment env = Utils::Environment::systemEnvironment();
dt's avatar
dt committed
        qmakeCXX = env.searchInPath(qmakeCXX);
        m_toolChains << ToolChainPtr(ProjectExplorer::ToolChain::createGccToolChain(qmakeCXX));
        m_targetIds.insert(QLatin1String(Constants::DESKTOP_TARGET_ID));
dt's avatar
dt committed
    } else if (qmakeCXX == QLatin1String("icpc")) {
        m_toolChains << ToolChainPtr(ProjectExplorer::ToolChain::createLinuxIccToolChain());
        m_targetIds.insert(QLatin1String(Constants::DESKTOP_TARGET_ID));
ck's avatar
ck committed
    }
    if (m_toolChains.isEmpty()) {
dt's avatar
dt committed
        qDebug()<<"Could not create ToolChain for"<<m_mkspecFullPath<<qmakeCXX;
        qDebug()<<"Qt Creator doesn't know about the system includes, nor the systems defines.";
    }

    QStringList configValues = evaluator.values("CONFIG");
dt's avatar
dt committed
    m_defaultConfigIsDebugAndRelease = false;
    foreach(const QString &value, configValues) {
        if (value == "debug")
            m_defaultConfigIsDebug = true;
        else if (value == "release")
            m_defaultConfigIsDebug = false;
        else if (value == "build_all")
            m_defaultConfigIsDebugAndRelease = true;
    }
    // Is this actually a simulator Qt?
    if (configValues.contains(QLatin1String("simulator"))) {
        m_targetIds.clear();
        m_targetIds.insert(QLatin1String(Constants::QT_SIMULATOR_TARGET_ID));
    }
dt's avatar
dt committed

    ProFileCacheManager::instance()->decRefCount();
con's avatar
con committed
}

con's avatar
con committed
QString QtVersion::mwcDirectory() const
{
    return m_mwcDirectory;
}

void QtVersion::setMwcDirectory(const QString &directory)
{
    m_mwcDirectory = directory;
Tobias Hunger's avatar
Tobias Hunger committed
    m_toolChainUpToDate = false;
QString QtVersion::s60SDKDirectory() const
{
    return m_s60SDKDirectory;
}

void QtVersion::setS60SDKDirectory(const QString &directory)
{
    m_s60SDKDirectory = directory;
Tobias Hunger's avatar
Tobias Hunger committed
    m_toolChainUpToDate = false;

QString QtVersion::gcceDirectory() const
{
    return m_gcceDirectory;
}

void QtVersion::setGcceDirectory(const QString &directory)
{
    m_gcceDirectory = directory;
Tobias Hunger's avatar
Tobias Hunger committed
    m_toolChainUpToDate = false;
con's avatar
con committed
QString QtVersion::mingwDirectory() const
{
    return m_mingwDirectory;
}

void QtVersion::setMingwDirectory(const QString &directory)
{
    m_mingwDirectory = directory;
    m_toolChainUpToDate = false;
con's avatar
con committed
}

QString QtVersion::msvcVersion() const
{
    return m_msvcVersion;
}

void QtVersion::setMsvcVersion(const QString &version)
{
    m_msvcVersion = version;
    m_toolChainUpToDate = false;
con's avatar
con committed
}

void QtVersion::addToEnvironment(Utils::Environment &env) const
con's avatar
con committed
{
    env.set("QTDIR", QDir::toNativeSeparators(versionInfo().value("QT_INSTALL_DATA")));
    env.prependOrSetPath(versionInfo().value("QT_INSTALL_BINS"));
con's avatar
con committed
}

int QtVersion::uniqueId() const
{
    return m_id;
}

int QtVersion::getUniqueId()
{
    return QtVersionManager::instance()->getUniqueId();
con's avatar
con committed
}

bool QtVersion::isValid() const
{
dt's avatar
dt committed
    updateVersionInfo();
            && !qmakeCommand().isEmpty()
            && !displayName().isEmpty()
            && !m_notInstalled
            && m_versionInfo.contains("QT_INSTALL_BINS");
}

QString QtVersion::invalidReason() const
{
    if (isValid())
        return QString();
    if (qmakeCommand().isEmpty())
Friedemann Kleint's avatar
Friedemann Kleint committed
        return QCoreApplication::translate("QtVersion", "No qmake path set");
    if (displayName().isEmpty())
Friedemann Kleint's avatar
Friedemann Kleint committed
        return QCoreApplication::translate("QtVersion", "Qt version has no name");
Friedemann Kleint's avatar
Friedemann Kleint committed
        return QCoreApplication::translate("QtVersion", "Qt version is not properly installed, please run make install");
    if (!m_versionInfo.contains("QT_INSTALL_BINS"))
Friedemann Kleint's avatar
Friedemann Kleint committed
        return QCoreApplication::translate("QtVersion",
					   "Could not determine the path to the binaries of the Qt installation, maybe the qmake path is wrong?");
con's avatar
con committed
}

QtVersion::QmakeBuildConfigs QtVersion::defaultBuildConfig() const
con's avatar
con committed
{
dt's avatar
dt committed
    updateToolChainAndMkspec();
    QtVersion::QmakeBuildConfigs result = QtVersion::QmakeBuildConfig(0);

con's avatar
con committed
    if (m_defaultConfigIsDebugAndRelease)
        result = QtVersion::BuildAll;
    if (m_defaultConfigIsDebug)
        result = result | QtVersion::DebugBuild;
con's avatar
con committed
    return result;
}

bool QtVersion::hasDebuggingHelper() const
{
    updateVersionInfo();
bool QtVersion::hasQmlDump() const
{
    updateVersionInfo();
    return m_hasQmlDump;
}

bool QtVersion::hasQmlObserver() const
{
    updateVersionInfo();
    return m_hasQmlObserver;
}

QString QtVersion::debuggingHelperLibrary() const
{
    QString qtInstallData = versionInfo().value("QT_INSTALL_DATA");
    if (qtInstallData.isEmpty())
        return QString();
    return DebuggingHelperLibrary::debuggingHelperLibraryByInstallData(qtInstallData);
QString QtVersion::qmlDumpTool() const
{
    QString qtInstallData = versionInfo().value("QT_INSTALL_DATA");
    if (qtInstallData.isEmpty())
        return QString();
    return QmlDumpTool::toolByInstallData(qtInstallData);
}

QString QtVersion::qmlObserverTool() const
{
    QString qtInstallData = versionInfo().value("QT_INSTALL_DATA");
    if (qtInstallData.isEmpty())
        return QString();
    return QmlObserverTool::toolByInstallData(qtInstallData);
}

QStringList QtVersion::debuggingHelperLibraryLocations() const
{
    QString qtInstallData = versionInfo().value("QT_INSTALL_DATA");
    if (qtInstallData.isEmpty())
con's avatar
con committed
        return QStringList();
    return DebuggingHelperLibrary::locationsByInstallData(qtInstallData);
bool QtVersion::supportsBinaryDebuggingHelper() const
{
    QList<ProjectExplorer::ToolChain::ToolChainType> types = possibleToolChainTypes();
    if (types.contains(ProjectExplorer::ToolChain::GCC)
            || types.contains(ProjectExplorer::ToolChain::LINUX_ICC)
            || types.contains(ProjectExplorer::ToolChain::MSVC)
            || types.contains(ProjectExplorer::ToolChain::WINCE)
            || types.contains(ProjectExplorer::ToolChain::GCC_MAEMO)
            || types.contains(ProjectExplorer::ToolChain::OTHER)
            || types.contains(ProjectExplorer::ToolChain::UNKNOWN))
        return true;
    return false;
}

bool QtVersion::hasDocumentation() const
{
    updateVersionInfo();
    return m_hasDocumentation;
}

QString QtVersion::documentationPath() const
{
    updateVersionInfo();
    return m_versionInfo["QT_INSTALL_DOCS"];
}

bool QtVersion::hasDemos() const
{
    updateVersionInfo();
    return m_hasDemos;
}

QString QtVersion::demosPath() const
{
    updateVersionInfo();
    return m_versionInfo["QT_INSTALL_DEMOS"];
}

QString QtVersion::headerInstallPath() const
{
    updateVersionInfo();
    return m_versionInfo["QT_INSTALL_HEADERS"];
}

bool QtVersion::hasExamples() const
{
    updateVersionInfo();
    return m_hasExamples;
}

QString QtVersion::examplesPath() const
{
    updateVersionInfo();
    return m_versionInfo["QT_INSTALL_EXAMPLES"];
}
con's avatar
con committed
bool QtVersion::isQt64Bit() const
{
        const QString make = qmakeCommand();
Daniel Molkentin's avatar
Daniel Molkentin committed
//        qDebug() << make;
        bool isAmd64 = false;
#ifdef Q_OS_WIN32
#  ifdef __GNUC__   // MinGW lacking some definitions/winbase.h
#    define SCS_64BIT_BINARY 6
        DWORD binaryType = 0;
        bool success = GetBinaryTypeW(reinterpret_cast<const TCHAR*>(make.utf16()), &binaryType) != 0;
        if (success && binaryType == SCS_64BIT_BINARY)
            isAmd64=true;
//        qDebug() << "isAmd64:" << isAmd64 << binaryType;
        return isAmd64;
#else
        Q_UNUSED(isAmd64)
        return false;
QString QtVersion::buildDebuggingHelperLibrary(QFutureInterface<void> &future)
    QString qtInstallHeaders = versionInfo().value("QT_INSTALL_HEADERS");
    QString qtInstallData = versionInfo().value("QT_INSTALL_DATA");
    if (qtInstallData.isEmpty())
        return QString();
    Utils::Environment env = Utils::Environment::systemEnvironment();
    // TODO: the debugging helper doesn't comply to actual tool chain yet
    QList<QSharedPointer<ProjectExplorer::ToolChain> > alltc = toolChains();
    ProjectExplorer::ToolChain *tc = alltc.isEmpty() ? 0 : alltc.first().data();
dt's avatar
dt committed
    if (!tc)
Friedemann Kleint's avatar
Friedemann Kleint committed
        return QCoreApplication::translate("QtVersion", "The Qt Version has no toolchain.");
    tc->addToEnvironment(env);
    QString gdbHelperDirectory = DebuggingHelperLibrary::copy(qtInstallData, &output);
    if (!gdbHelperDirectory.isEmpty()) {
        output += DebuggingHelperLibrary::build(gdbHelperDirectory, tc->makeCommand(),
            qmakeCommand(), mkspec(), env,
            (tc->type() == ToolChain::GCC_MAEMO ? QLatin1String("-unix") : QLatin1String("")));
    }
    if (QmlDumpTool::canBuild(qtInstallHeaders)) {
        QString toolDirectory = QmlDumpTool::copy(qtInstallData, &output);
        if (!toolDirectory.isEmpty()) {
            output += QmlDumpTool::build(toolDirectory, tc->makeCommand(),
                qmakeCommand(), mkspec(), env,
                (tc->type() == ToolChain::GCC_MAEMO ? QLatin1String("-unix") : QLatin1String("")));
        }
    } else {
        output += QCoreApplication::tr("Cannot build qmldump; Qt version must be 4.7.1 or higher.");
    }
    future.setProgressValue(3);

    if (QmlObserverTool::canBuild(qtInstallHeaders)) {
        QString toolDirectory = QmlObserverTool::copy(qtInstallData, &output);
        if (!toolDirectory.isEmpty()) {
            output += QmlObserverTool::build(toolDirectory, tc->makeCommand(),
                qmakeCommand(), mkspec(), env,
                (tc->type() == ToolChain::GCC_MAEMO ? QLatin1String("-unix") : QLatin1String("")));
        }
    } else {
        output += QCoreApplication::tr("Cannot build QMLObserver; Qt version must be 4.7.1 or higher.");
    }
    future.setProgressValue(4);
    m_hasDebuggingHelper = !debuggingHelperLibrary().isEmpty();
    m_hasQmlDump = !qmlDumpTool().isEmpty();
    m_hasQmlObserver = !qmlObserverTool().isEmpty();