OSDN Git Service

Merge remote branch 'origin/1.3'
[qt-creator-jp/qt-creator-jp.git] / src / plugins / qt4projectmanager / qtversionmanager.cpp
index 4bfae83..333a25a 100644 (file)
@@ -35,6 +35,9 @@
 #ifdef QTCREATOR_WITH_S60
 #include "qt-s60/s60manager.h"
 #endif
+#ifdef QTCREATOR_WITH_MAEMO
+#include "qt-maemo/maemomanager.h"
+#endif
 
 #include <projectexplorer/debugginghelper.h>
 #include <projectexplorer/projectexplorer.h>
 #include <help/helpplugin.h>
 #include <utils/qtcassert.h>
 
-
 #include <QtCore/QProcess>
 #include <QtCore/QSettings>
 #include <QtCore/QTime>
 #include <QtCore/QTimer>
 #include <QtCore/QTextStream>
+#include <QtCore/QDir>
 #include <QtGui/QApplication>
 #include <QtGui/QDesktopServices>
 
@@ -178,8 +181,9 @@ void QtVersionManager::addVersion(QtVersion *version)
 {
     QTC_ASSERT(version != 0, return);
     m_versions.append(version);
-    m_uniqueIdToIndex.insert(version->uniqueId(), m_versions.count() - 1);
-    emit qtVersionsChanged();
+    int uniqueId = version->uniqueId();
+    m_uniqueIdToIndex.insert(uniqueId, m_versions.count() - 1);
+    emit qtVersionsChanged(QList<int>() << uniqueId);
     writeVersionsIntoSettings();
 }
 
@@ -187,8 +191,9 @@ void QtVersionManager::removeVersion(QtVersion *version)
 {
     QTC_ASSERT(version != 0, return);
     m_versions.removeAll(version);
-    m_uniqueIdToIndex.remove(version->uniqueId());
-    emit qtVersionsChanged();
+    int uniqueId = version->uniqueId();
+    m_uniqueIdToIndex.remove(uniqueId);
+    emit qtVersionsChanged(QList<int>() << uniqueId);
     writeVersionsIntoSettings();
     delete version;
 }
@@ -375,21 +380,80 @@ QtVersion *QtVersionManager::defaultVersion() const
         return m_emptyVersion;
 }
 
+class SortByUniqueId
+{
+public:
+    bool operator()(QtVersion *a, QtVersion *b)
+    {
+        return a->uniqueId() < b->uniqueId();
+    }
+};
+
+bool QtVersionManager::equals(QtVersion *a, QtVersion *b)
+{
+    if (a->m_qmakeCommand != b->m_qmakeCommand)
+        return false;
+    if (a->m_id != b->m_id)
+        return false;
+    if (a->m_mingwDirectory != b->m_mingwDirectory
+        || a->m_msvcVersion != b->m_msvcVersion
+        || a->m_mwcDirectory != b->m_mwcDirectory)
+        return false;
+    return true;
+}
+
 void QtVersionManager::setNewQtVersions(QList<QtVersion *> newVersions, int newDefaultVersion)
 {
-    bool versionPathsChanged = m_versions.size() != newVersions.size();
-    if (!versionPathsChanged) {
-        for (int i = 0; i < m_versions.size(); ++i) {
-            if (m_versions.at(i)->qmakeCommand() != newVersions.at(i)->qmakeCommand()) {
-                versionPathsChanged = true;
-                break;
-            }
+    // We want to preserve the same order as in the settings dialog
+    // so we sort a copy
+    QList<QtVersion *> sortedNewVersions = newVersions;
+    SortByUniqueId sortByUniqueId;
+    qSort(sortedNewVersions.begin(), sortedNewVersions.end(), sortByUniqueId);
+    qSort(m_versions.begin(), m_versions.end(), sortByUniqueId);
+
+    QList<int> changedVersions;
+    // So we trying to find the minimal set of changed versions,
+    // iterate over both sorted list
+
+    // newVersions and oldVersions iterator
+    QList<QtVersion *>::const_iterator nit, nend, oit, oend;
+    nit = sortedNewVersions.constBegin();
+    nend = sortedNewVersions.constEnd();
+    oit = m_versions.constBegin();
+    oend = m_versions.constEnd();
+
+    while (nit != nend && oit != oend) {
+        int nid = (*nit)->uniqueId();
+        int oid = (*oit)->uniqueId();
+        if (nid < oid) {
+            changedVersions.push_back(nid);
+            ++nit;
+        } else if (oid < nid) {
+            changedVersions.push_back(oid);
+            ++oit;
+        } else {
+            if (!equals(*oit, *nit))
+                changedVersions.push_back(oid);
+            ++oit;
+            ++nit;
         }
     }
+
+    while (nit != nend) {
+        changedVersions.push_back((*nit)->uniqueId());
+        ++nit;
+    }
+
+    while (oit != oend) {
+        changedVersions.push_back((*oit)->uniqueId());
+        ++oit;
+    }
+
     qDeleteAll(m_versions);
     m_versions.clear();
     m_versions = newVersions;
-    if (versionPathsChanged)
+
+    if (!changedVersions.isEmpty())
         updateDocumentation();
     updateUniqueIdToIndexMap();
 
@@ -399,13 +463,13 @@ void QtVersionManager::setNewQtVersions(QList<QtVersion *> newVersions, int newD
         emitDefaultChanged = true;
     }
 
-    emit qtVersionsChanged();
-    if (emitDefaultChanged) {
-        emit defaultQtVersionChanged();
-    }
-
     updateExamples();
     writeVersionsIntoSettings();
+
+    if (!changedVersions.isEmpty())
+        emit qtVersionsChanged(changedVersions);
+    if (emitDefaultChanged)
+        emit defaultQtVersionChanged();
 }
 
 ///
@@ -418,7 +482,7 @@ QtVersion::QtVersion(const QString &name, const QString &qmakeCommand, int id,
     m_isAutodetected(isAutodetected),
     m_autodetectionSource(autodetectionSource),
     m_hasDebuggingHelper(false),
-    m_mkspecUpToDate(false),
+    m_toolChainUpToDate(false),
     m_versionInfoUpToDate(false),
     m_notInstalled(false),
     m_defaultConfigIsDebug(true),
@@ -440,7 +504,7 @@ QtVersion::QtVersion(const QString &name, const QString &qmakeCommand,
     m_isAutodetected(isAutodetected),
     m_autodetectionSource(autodetectionSource),
     m_hasDebuggingHelper(false),
-    m_mkspecUpToDate(false),
+    m_toolChainUpToDate(false),
     m_versionInfoUpToDate(false),
     m_notInstalled(false),
     m_defaultConfigIsDebug(true),
@@ -458,7 +522,7 @@ QtVersion::QtVersion(const QString &qmakeCommand, bool isAutodetected, const QSt
     : m_isAutodetected(isAutodetected),
     m_autodetectionSource(autodetectionSource),
     m_hasDebuggingHelper(false),
-    m_mkspecUpToDate(false),
+    m_toolChainUpToDate(false),
     m_versionInfoUpToDate(false),
     m_notInstalled(false),
     m_defaultConfigIsDebug(true),
@@ -477,7 +541,7 @@ QtVersion::QtVersion()
     m_id(-1),
     m_isAutodetected(false),
     m_hasDebuggingHelper(false),
-    m_mkspecUpToDate(false),
+    m_toolChainUpToDate(false),
     m_versionInfoUpToDate(false),
     m_notInstalled(false),
     m_defaultConfigIsDebug(true),
@@ -508,7 +572,7 @@ QString QtVersion::toHtml() const
         << "</b></td><td>" << mkspec() << "</td></tr>";
     str << "<tr><td><b>" << QtVersionManager::tr("qmake:")
         << "</b></td><td>" << m_qmakeCommand << "</td></tr>";
-    updateVersionInfo();
+    updateToolChainAndMkspec();
     if (m_defaultConfigIsDebug || m_defaultConfigIsDebugAndRelease) {
         str << "<tr><td><b>" << QtVersionManager::tr("Default:") << "</b></td><td>"
             << (m_defaultConfigIsDebug ? "debug" : "release");
@@ -516,9 +580,6 @@ QString QtVersion::toHtml() const
             str << " debug_and_release";
         str << "</td></tr>";
     } // default config.
-    if (!qmakeCXX().isEmpty())
-        str << "<tr><td><b>" << QtVersionManager::tr("Compiler:")
-            << "</b></td><td>" << qmakeCXX() << "</td></tr>";
     str << "<tr><td><b>" << QtVersionManager::tr("Version:")
         << "</b></td><td>" << qtVersionString() << "</td></tr>";
     if (hasDebuggingHelper())
@@ -551,13 +612,13 @@ QString QtVersion::sourcePath() const
 
 QString QtVersion::mkspec() const
 {
-    updateMkSpec();
+    updateToolChainAndMkspec();
     return m_mkspec;
 }
 
 QString QtVersion::mkspecPath() const
 {
-    updateMkSpec();
+    updateToolChainAndMkspec();
     return m_mkspecFullPath;
 }
 
@@ -572,13 +633,6 @@ QHash<QString,QString> QtVersion::versionInfo() const
     return m_versionInfo;
 }
 
-QString QtVersion::qmakeCXX() const
-{
-    updateQMakeCXX();
-    return m_qmakeCXX;
-}
-
-
 void QtVersion::setName(const QString &name)
 {
     m_name = name;
@@ -591,9 +645,7 @@ void QtVersion::setQMakeCommand(const QString& qmakeCommand)
     m_qmakeCommand = m_qmakeCommand.toLower();
 #endif
     m_designerCommand = m_linguistCommand = m_uicCommand = QString::null;
-    m_mkspecUpToDate = false;
-    m_qmakeCXX = QString::null;
-    m_qmakeCXXUpToDate = false;
+    m_toolChainUpToDate = false;
     // TODO do i need to optimize this?
     m_versionInfoUpToDate = false;
     m_hasDebuggingHelper = !debuggingHelperLibrary().isEmpty();
@@ -629,6 +681,9 @@ void QtVersion::updateSourcePath()
         }
     }
     m_sourcePath = QDir::cleanPath(m_sourcePath);
+#ifdef Q_OS_WIN
+    m_sourcePath = m_sourcePath.toLower();
+#endif
 }
 
 // Returns the version that was used to build the project in that directory
@@ -641,9 +696,9 @@ QString QtVersionManager::findQMakeBinaryFromMakefile(const QString &directory)
     QFile makefile(directory + "/Makefile" );
     if (makefile.exists() && makefile.open(QFile::ReadOnly)) {
         QTextStream ts(&makefile);
+        QRegExp r1("QMAKE\\s*=(.*)");
         while (!ts.atEnd()) {
             QString line = ts.readLine();
-            QRegExp r1("QMAKE\\s*=(.*)");
             if (r1.exactMatch(line)) {
                 if (debugAdding)
                     qDebug()<<"#~~ QMAKE is:"<<r1.cap(1).trimmed();
@@ -678,11 +733,11 @@ void dumpQMakeAssignments(const QList<QMakeAssignment> &list)
     }
 }
 
-QPair<QtVersion::QmakeBuildConfig, QStringList> QtVersionManager::scanMakeFile(const QString &directory, QtVersion::QmakeBuildConfig defaultBuildConfig)
+QPair<QtVersion::QmakeBuildConfigs, QStringList> QtVersionManager::scanMakeFile(const QString &directory, QtVersion::QmakeBuildConfigs defaultBuildConfig)
 {
     if (debug)
         qDebug()<<"ScanMakeFile, the gory details:";
-    QtVersion::QmakeBuildConfig result = QtVersion::NoBuild;
+    QtVersion::QmakeBuildConfigs result = defaultBuildConfig;
     QStringList result2;
 
     QString line = findQMakeLine(directory);
@@ -835,11 +890,10 @@ void QtVersionManager::parseParts(const QStringList &parts, QList<QMakeAssignmen
 #endif
 }
 
-
 /// This function extracts all the CONFIG+=debug, CONFIG+=release
-QtVersion::QmakeBuildConfig QtVersionManager::qmakeBuildConfigFromCmdArgs(QList<QMakeAssignment> *assignments, QtVersion::QmakeBuildConfig defaultBuildConfig)
+QtVersion::QmakeBuildConfigs QtVersionManager::qmakeBuildConfigFromCmdArgs(QList<QMakeAssignment> *assignments, QtVersion::QmakeBuildConfigs defaultBuildConfig)
 {
-    QtVersion::QmakeBuildConfig result = defaultBuildConfig;
+    QtVersion::QmakeBuildConfigs result = defaultBuildConfig;
     QList<QMakeAssignment> oldAssignments = *assignments;
     assignments->clear();
     foreach(QMakeAssignment qa, oldAssignments) {
@@ -849,19 +903,19 @@ QtVersion::QmakeBuildConfig QtVersionManager::qmakeBuildConfigFromCmdArgs(QList<
             foreach(const QString &value, values) {
                 if (value == "debug") {
                     if (qa.op == "+=")
-                        result = QtVersion::QmakeBuildConfig(result  | QtVersion::DebugBuild);
+                        result = result  | QtVersion::DebugBuild;
                     else
-                        result = QtVersion::QmakeBuildConfig(result  & ~QtVersion::DebugBuild);
+                        result = result  & ~QtVersion::DebugBuild;
                 } else if (value == "release") {
                     if (qa.op == "+=")
-                        result = QtVersion::QmakeBuildConfig(result & ~QtVersion::DebugBuild);
+                        result = result & ~QtVersion::DebugBuild;
                     else
-                        result = QtVersion::QmakeBuildConfig(result | QtVersion::DebugBuild);
+                        result = result | QtVersion::DebugBuild;
                 } else if (value == "debug_and_release") {
                     if (qa.op == "+=")
-                        result = QtVersion::QmakeBuildConfig(result | QtVersion::BuildAll);
+                        result = result | QtVersion::BuildAll;
                     else
-                        result = QtVersion::QmakeBuildConfig(result & ~QtVersion::BuildAll);
+                        result = result & ~QtVersion::BuildAll;
                 } else {
                     newValues.append(value);
                 }
@@ -949,29 +1003,6 @@ void QtVersion::updateVersionInfo() const
             if (fi.exists())
                 m_hasDemos = true;
         }
-
-        // Parse qconfigpri
-        QString baseDir = m_versionInfo.value("QT_INSTALL_DATA");
-        QFile qconfigpri(baseDir + QLatin1String("/mkspecs/qconfig.pri"));
-        if (qconfigpri.exists()) {
-            qconfigpri.open(QIODevice::ReadOnly | QIODevice::Text);
-            QTextStream stream(&qconfigpri);
-            while (!stream.atEnd()) {
-                QString line = stream.readLine().trimmed();
-                if (line.startsWith(QLatin1String("CONFIG"))) {
-                    m_defaultConfigIsDebugAndRelease = false;
-                    QStringList values = line.split(QLatin1Char('=')).at(1).trimmed().split(" ");
-                    foreach(const QString &value, values) {
-                        if (value == "debug")
-                            m_defaultConfigIsDebug = true;
-                        else if (value == "release")
-                            m_defaultConfigIsDebug = false;
-                        else if (value == "build_all")
-                            m_defaultConfigIsDebugAndRelease = true;
-                    }
-                }
-            }
-        }
     }
     m_versionInfoUpToDate = true;
 }
@@ -982,141 +1013,6 @@ bool QtVersion::isInstalled() const
     return !m_notInstalled;
 }
 
-void QtVersion::updateMkSpec() const
-{
-    if (m_mkspecUpToDate)
-        return;
-    //qDebug()<<"Finding mkspec for"<<path();
-
-    QString mkspec;
-    // no .qmake.cache so look at the default mkspec
-    QString mkspecPath = versionInfo().value("QMAKE_MKSPECS");
-    if (mkspecPath.isEmpty())
-        mkspecPath = versionInfo().value("QT_INSTALL_DATA") + "/mkspecs/default";
-    else
-        mkspecPath = mkspecPath + "/default";
-//     qDebug() << "default mkspec is located at" << mkspecPath;
-#ifdef Q_OS_WIN
-    QFile f2(mkspecPath + "/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) {
-                    mkspec = temp.at(1).trimmed();
-                }
-                break;
-            }
-        }
-        f2.close();
-    }
-#elif defined(Q_OS_MAC)
-    QFile f2(mkspecPath + "/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++";
-                        mkspec = "macx-g++";
-                    } else {
-                        //resolve mkspec link
-                        QFileInfo f3(mkspecPath);
-                        if (f3.isSymLink()) {
-                            mkspec = f3.symLinkTarget();
-                        }
-                    }
-                }
-                break;
-            }
-        }
-        f2.close();
-    }
-#else
-    QFileInfo f2(mkspecPath);
-    if (f2.isSymLink()) {
-        mkspec = f2.symLinkTarget();
-    }
-#endif
-
-    m_mkspecFullPath = mkspec;
-    int index = mkspec.lastIndexOf('/');
-    if (index == -1)
-        index = mkspec.lastIndexOf('\\');
-    QString mkspecDir = QDir(versionInfo().value("QT_INSTALL_DATA") + "/mkspecs/").canonicalPath();
-    if (index >= 0 && QDir(mkspec.left(index)).canonicalPath() == mkspecDir)
-        mkspec = mkspec.mid(index+1).trimmed();
-
-    m_mkspec = mkspec;
-    m_mkspecUpToDate = true;
-//    qDebug()<<"mkspec for "<<versionInfo().value("QT_INSTALL_DATA")<<" is "<<mkspec;
-}
-
-void QtVersion::updateQMakeCXX() const
-{
-    if (m_qmakeCXXUpToDate)
-        return;
-    ProFileReader *reader = new ProFileReader();
-    reader->setCumulative(false);
-    reader->setParsePreAndPostFiles(false);
-    reader->readProFile(mkspecPath() + "/qmake.conf");
-    m_qmakeCXX = reader->value("QMAKE_CXX");
-
-    delete reader;
-    m_qmakeCXXUpToDate = true;
-}
-
-ProjectExplorer::ToolChain *QtVersion::createToolChain(ProjectExplorer::ToolChain::ToolChainType type) const
-{
-    ProjectExplorer::ToolChain *tempToolchain = 0;
-    if (type == ProjectExplorer::ToolChain::MinGW) {
-        QString qmake_cxx = qmakeCXX();
-        ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment();
-        //addToEnvironment(env);
-        env.prependOrSetPath(mingwDirectory()+"/bin");
-        qmake_cxx = env.searchInPath(qmake_cxx);
-        tempToolchain = ProjectExplorer::ToolChain::createMinGWToolChain(qmake_cxx, mingwDirectory());
-        //qDebug()<<"Mingw ToolChain";
-    } else if(type == ProjectExplorer::ToolChain::MSVC) {
-        tempToolchain = ProjectExplorer::ToolChain::createMSVCToolChain(msvcVersion(), isQt64Bit());
-        //qDebug()<<"MSVC ToolChain ("<<version->msvcVersion()<<")";
-    } else if(type == ProjectExplorer::ToolChain::WINCE) {
-        tempToolchain = ProjectExplorer::ToolChain::createWinCEToolChain(msvcVersion(), wincePlatform());
-        //qDebug()<<"WinCE ToolChain ("<<version->msvcVersion()<<","<<version->wincePlatform()<<")";
-    } else if(type == ProjectExplorer::ToolChain::GCC || type == ProjectExplorer::ToolChain::LinuxICC) {
-        QString qmake_cxx = qmakeCXX();
-        ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment();
-        //addToEnvironment(env);
-        qmake_cxx = env.searchInPath(qmake_cxx);
-        if (qmake_cxx.isEmpty()) {
-            // macx-xcode mkspec resets the value of QMAKE_CXX.
-            // Unfortunately, we need a valid QMAKE_CXX to configure the parser.
-            qmake_cxx = QLatin1String("cc");
-        }
-        tempToolchain = ProjectExplorer::ToolChain::createGccToolChain(qmake_cxx);
-        //qDebug()<<"GCC ToolChain ("<<qmake_cxx<<")";
-#ifdef QTCREATOR_WITH_S60
-    } else if (type == ProjectExplorer::ToolChain::WINSCW) {
-        tempToolchain = S60Manager::instance()->createWINSCWToolChain(this);
-    } else if (type == ProjectExplorer::ToolChain::GCCE) {
-        tempToolchain = S60Manager::instance()->createGCCEToolChain(this);
-    } else if (type == ProjectExplorer::ToolChain::RVCT_ARMV5
-               || type == ProjectExplorer::ToolChain::RVCT_ARMV6) {
-        tempToolchain = S60Manager::instance()->createRVCTToolChain(this, type);
-#endif
-    } else {
-        qDebug()<<"Could not create ToolChain for"<<mkspec();
-        qDebug()<<"Qt Creator doesn't know about the system includes, nor the systems defines.";
-    }
-    return tempToolchain;
-}
-
-
 QString QtVersion::findQtBinary(const QStringList &possibleCommands) const
 {
     const QString qtdirbin = versionInfo().value(QLatin1String("QT_INSTALL_BINS")) + QLatin1Char('/');
@@ -1180,37 +1076,211 @@ QString QtVersion::linguistCommand() const
     return m_linguistCommand;
 }
 
+QList<QSharedPointer<ProjectExplorer::ToolChain> > QtVersion::toolChains() const
+{
+    updateToolChainAndMkspec();
+    return m_toolChains;
+}
+
+ProjectExplorer::ToolChain *QtVersion::toolChain(ProjectExplorer::ToolChain::ToolChainType type) const
+{
+    foreach(QSharedPointer<ProjectExplorer::ToolChain> tcptr, toolChains())
+        if (tcptr->type() == type)
+            return tcptr.data();
+    return 0;
+}
+
 QList<ProjectExplorer::ToolChain::ToolChainType> QtVersion::possibleToolChainTypes() const
 {
-    QList<ProjectExplorer::ToolChain::ToolChainType> toolChains;
-    if (!isValid())
-        return toolChains << ProjectExplorer::ToolChain::INVALID;
-    const QString &spec = mkspec();
-    if (spec.contains("win32-msvc") || spec.contains(QLatin1String("win32-icc")))
-        toolChains << ProjectExplorer::ToolChain::MSVC;
-    else if (spec.contains("win32-g++"))
-        toolChains << ProjectExplorer::ToolChain::MinGW;
-    else if (spec == QString::null)
-        toolChains << ProjectExplorer::ToolChain::INVALID;
-    else if (spec.contains("wince"))
-        toolChains << ProjectExplorer::ToolChain::WINCE;
-    else if (spec.contains("linux-icc"))
-        toolChains << ProjectExplorer::ToolChain::LinuxICC;
-#ifdef QTCREATOR_WITH_S60
-    else if (spec.contains("symbian-abld"))
-        toolChains << ProjectExplorer::ToolChain::GCCE
-                << ProjectExplorer::ToolChain::RVCT_ARMV5
-                << ProjectExplorer::ToolChain::RVCT_ARMV6
-                << ProjectExplorer::ToolChain::WINSCW;
-#endif
-    else
-        toolChains << ProjectExplorer::ToolChain::GCC;
-    return toolChains;
+    QList<ProjectExplorer::ToolChain::ToolChainType> types;
+    foreach(QSharedPointer<ProjectExplorer::ToolChain> tc, toolChains())
+        types << tc->type();
+    return types;
 }
 
 ProjectExplorer::ToolChain::ToolChainType QtVersion::defaultToolchainType() const
 {
-    return possibleToolChainTypes().at(0);
+    const QList<ProjectExplorer::ToolChain::ToolChainType> & list = possibleToolChainTypes();
+    if (list.isEmpty())
+        return ProjectExplorer::ToolChain::INVALID;
+    return list.first();
+}
+
+// if none, then it's INVALID everywhere this function is called
+void QtVersion::updateToolChainAndMkspec() const
+{
+    typedef QSharedPointer<ProjectExplorer::ToolChain> ToolChainPtr;
+    if (m_toolChainUpToDate)
+        return;
+
+    if (!isValid())
+        return;
+
+    m_toolChains.clear();
+
+//    qDebug()<<"Finding mkspec for"<<qmakeCommand();
+
+    // 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";
+
+#ifdef Q_OS_WIN
+    baseMkspecDir = baseMkspecDir.toLower();
+#endif
+
+    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) {
+                    mkspecFullPath = temp.at(1).trimmed();
+                }
+                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
+    mkspecFullPath = mkspecFullPath.toLower();
+#endif
+
+    m_mkspecFullPath = mkspecFullPath;
+    QString mkspec = m_mkspecFullPath;
+
+    if (mkspec.startsWith(baseMkspecDir)) {
+        mkspec = mkspec.mid(baseMkspecDir.length() + 1);
+//        qDebug() << "Setting mkspec to"<<mkspec;
+    } else {
+        QString sourceMkSpecPath = sourcePath() + "/mkspecs";
+        if (mkspec.startsWith(sourceMkSpecPath)) {
+            mkspec = mkspec.mid(sourceMkSpecPath.length() + 1);
+        } else {
+            // Do nothing
+        }
+    }
+
+    m_mkspec = mkspec;
+
+//    qDebug()<<"mkspec for "<<qmakeCommand()<<" is "<<m_mkspec<<m_mkspecFullPath;
+
+    ProFileOption option;
+    option.properties = versionInfo();
+    option.cache = ProFileCacheManager::instance()->cache();
+    ProFileReader *reader = new ProFileReader(&option);
+    reader->setCumulative(false);
+    reader->setParsePreAndPostFiles(false);
+    reader->readProFile(m_mkspecFullPath + "/qmake.conf");
+    QString qmakeCXX = reader->value("QMAKE_CXX");
+    QString makefileGenerator = reader->value("MAKEFILE_GENERATOR");
+    QString ce_sdk = reader->values("CE_SDK").join(QLatin1String(" "));
+    QString ce_arch = reader->value("CE_ARCH");
+    QString qt_arch = reader->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));
+    } else if (makefileGenerator == QLatin1String("SYMBIAN_ABLD") ||
+               makefileGenerator == QLatin1String("SYMBIAN_SBSV2")) {
+#ifdef QTCREATOR_WITH_S60
+        if (S60Manager *s60mgr = S60Manager::instance()) {
+#    ifdef Q_OS_WIN
+            m_toolChains << ToolChainPtr(s60mgr->createGCCEToolChain(this))
+                         << ToolChainPtr(s60mgr->createRVCTToolChain(this, ProjectExplorer::ToolChain::RVCT_ARMV5))
+                         << ToolChainPtr(s60mgr->createRVCTToolChain(this, ProjectExplorer::ToolChain::RVCT_ARMV6))
+                         << ToolChainPtr(s60mgr->createWINSCWToolChain(this));
+#    else
+            m_toolChains << ToolChainPtr(s60mgr->createGCCE_GnuPocToolChain(this))
+                         << ToolChainPtr(s60mgr->createRVCTToolChain(this, ProjectExplorer::ToolChain::RVCT_ARMV6_GNUPOC));
+#    endif
+        }
+#endif
+    } else if (qt_arch == "arm") {
+#ifdef QTCREATOR_WITH_MAEMO
+        m_toolChains << ToolChainPtr(MaemoManager::instance()->maemoToolChain(this));
+#endif
+    } else if (qmakeCXX == "cl" || qmakeCXX == "icl") {
+        // TODO proper support for intel cl
+        m_toolChains << ToolChainPtr(
+                ProjectExplorer::ToolChain::createMSVCToolChain(msvcVersion(), isQt64Bit()));
+    } else if (qmakeCXX == "g++" && makefileGenerator == "MINGW") {
+        ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment();
+        //addToEnvironment(env);
+        env.prependOrSetPath(mingwDirectory() + "/bin");
+        qmakeCXX = env.searchInPath(qmakeCXX);
+        m_toolChains << ToolChainPtr(
+                ProjectExplorer::ToolChain::createMinGWToolChain(qmakeCXX, mingwDirectory()));
+    } else if (qmakeCXX == "g++" || qmakeCXX == "icc") {
+        ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment();
+        //addToEnvironment(env);
+        qmakeCXX = env.searchInPath(qmakeCXX);
+        if (qmakeCXX.isEmpty()) {
+            // macx-xcode mkspec resets the value of QMAKE_CXX.
+            // Unfortunately, we need a valid QMAKE_CXX to configure the parser.
+            qmakeCXX = QLatin1String("cc");
+        }
+        m_toolChains << ToolChainPtr(ProjectExplorer::ToolChain::createGccToolChain(qmakeCXX));
+    }
+
+    if (m_toolChains.isEmpty()) {
+        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 = reader->values("CONFIG");
+    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;
+    }
+
+    delete reader;
+    m_toolChainUpToDate = true;
 }
 
 QString QtVersion::mwcDirectory() const
@@ -1250,6 +1320,7 @@ QString QtVersion::mingwDirectory() const
 void QtVersion::setMingwDirectory(const QString &directory)
 {
     m_mingwDirectory = directory;
+    m_toolChainUpToDate = false;
 }
 
 QString QtVersion::msvcVersion() const
@@ -1257,22 +1328,16 @@ QString QtVersion::msvcVersion() const
     return m_msvcVersion;
 }
 
-QString QtVersion::wincePlatform() const
-{
-//    qDebug()<<"QtVersion::wincePlatform returning"<<ProjectExplorer::CeSdkHandler::platformName(mkspecPath() + "/qmake.conf");
-    return ProjectExplorer::CeSdkHandler::platformName(mkspecPath() + "/qmake.conf");
-}
-
 void QtVersion::setMsvcVersion(const QString &version)
 {
     m_msvcVersion = version;
+    m_toolChainUpToDate = false;
 }
 
 void QtVersion::addToEnvironment(ProjectExplorer::Environment &env) const
 {
-    env.set("QTDIR", versionInfo().value("QT_INSTALL_DATA"));
-    QString qtdirbin = versionInfo().value("QT_INSTALL_BINS");
-    env.prependOrSetPath(qtdirbin);
+    env.set("QTDIR", QDir::toNativeSeparators(versionInfo().value("QT_INSTALL_DATA")));
+    env.prependOrSetPath(versionInfo().value("QT_INSTALL_BINS"));
 }
 
 int QtVersion::uniqueId() const
@@ -1287,17 +1352,20 @@ int QtVersion::getUniqueId()
 
 bool QtVersion::isValid() const
 {
-    return (!(m_id == -1 || m_qmakeCommand == QString::null || m_name == QString::null || mkspec() == QString::null) && !m_notInstalled);
+    updateVersionInfo();
+    return (!(m_id == -1 || qmakeCommand() == QString::null
+        || name() == QString::null) && !m_notInstalled);
 }
 
-QtVersion::QmakeBuildConfig QtVersion::defaultBuildConfig() const
+QtVersion::QmakeBuildConfigs QtVersion::defaultBuildConfig() const
 {
-    updateVersionInfo();
-    QtVersion::QmakeBuildConfig result = QtVersion::QmakeBuildConfig(0);
+    updateToolChainAndMkspec();
+    QtVersion::QmakeBuildConfigs result = QtVersion::QmakeBuildConfig(0);
+
     if (m_defaultConfigIsDebugAndRelease)
         result = QtVersion::BuildAll;
     if (m_defaultConfigIsDebug)
-        result = QtVersion::QmakeBuildConfig(result | QtVersion::DebugBuild);
+        result = result | QtVersion::DebugBuild;
     return result;
 }
 
@@ -1388,8 +1456,8 @@ QString QtVersion::buildDebuggingHelperLibrary()
     addToEnvironment(env);
 
     // TODO: the debugging helper doesn't comply to actual tool chain yet
-
-    ProjectExplorer::ToolChain *tc = createToolChain(defaultToolchainType());
+    QList<QSharedPointer<ProjectExplorer::ToolChain> > alltc = toolChains();
+    ProjectExplorer::ToolChain *tc = alltc.isEmpty() ? 0 : alltc.first().data();
     if (!tc)
         return QApplication::tr("The Qt Version has no toolchain.");
     tc->addToEnvironment(env);
@@ -1398,7 +1466,6 @@ QString QtVersion::buildDebuggingHelperLibrary()
     if (!directory.isEmpty())
         output += DebuggingHelperLibrary::buildDebuggingHelperLibrary(directory, tc->makeCommand(), qmakeCommand(), mkspec(), env);
     m_hasDebuggingHelper = !debuggingHelperLibrary().isEmpty();
-    delete tc;
     return output;
 }