OSDN Git Service

Actually delete CONFIG+=declarative from list of user arguments
[qt-creator-jp/qt-creator-jp.git] / src / plugins / qt4projectmanager / qt4buildconfiguration.cpp
index 4f01323..9d172ac 100644 (file)
@@ -2,28 +2,31 @@
 **
 ** This file is part of Qt Creator
 **
-** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
 **
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: Nokia Corporation (info@qt.nokia.com)
 **
-** Commercial Usage
-**
-** Licensees holding valid Qt Commercial licenses may use this file in
-** accordance with the Qt Commercial License Agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Nokia.
 **
 ** GNU Lesser General Public License Usage
 **
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
 **
-** If you are unsure which license is appropriate for your use, please
-** contact the sales department at http://qt.nokia.com/contact.
+** If you have questions regarding the use of this file, please contact
+** Nokia at info@qt.nokia.com.
 **
 **************************************************************************/
 
 #include "qt4nodes.h"
 #include "qmakestep.h"
 #include "makestep.h"
+#include "qt4basetargetfactory.h"
 
 #include <utils/qtcassert.h>
+#include <utils/qtcprocess.h>
 #include <limits>
 #include <projectexplorer/buildsteplist.h>
 #include <projectexplorer/projectexplorerconstants.h>
-
+#include <projectexplorer/toolchain.h>
+#include <projectexplorer/toolchainmanager.h>
+#include <qtsupport/qtversionfactory.h>
+#include <qtsupport/baseqtversion.h>
+#include <qtsupport/qtversionmanager.h>
 #include <QtCore/QDebug>
 
 #include <QtGui/QInputDialog>
@@ -55,41 +64,40 @@ const char * const QT4_BC_ID("Qt4ProjectManager.Qt4BuildConfiguration");
 
 const char * const USE_SHADOW_BUILD_KEY("Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild");
 const char * const BUILD_DIRECTORY_KEY("Qt4ProjectManager.Qt4BuildConfiguration.BuildDirectory");
-const char * const TOOLCHAIN_KEY("Qt4ProjectManager.Qt4BuildConfiguration.ToolChain");
 const char * const BUILD_CONFIGURATION_KEY("Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration");
 const char * const QT_VERSION_ID_KEY("Qt4ProjectManager.Qt4BuildConfiguration.QtVersionId");
 
 enum { debug = 0 };
 }
 
-Qt4BuildConfiguration::Qt4BuildConfiguration(Qt4Target *target) :
+Qt4BuildConfiguration::Qt4BuildConfiguration(Qt4BaseTarget *target) :
     BuildConfiguration(target, QLatin1String(QT4_BC_ID)),
     m_shadowBuild(true),
+    m_isEnabled(false),
     m_qtVersionId(-1),
-    m_toolChainType(-1), // toolChainType() makes sure to return the default toolchainType
     m_qmakeBuildConfiguration(0),
     m_subNodeBuild(0)
 {
     ctor();
 }
 
-Qt4BuildConfiguration::Qt4BuildConfiguration(Qt4Target *target, const QString &id) :
+Qt4BuildConfiguration::Qt4BuildConfiguration(Qt4BaseTarget *target, const QString &id) :
     BuildConfiguration(target, id),
     m_shadowBuild(true),
+    m_isEnabled(false),
     m_qtVersionId(-1),
-    m_toolChainType(-1), // toolChainType() makes sure to return the default toolchainType
     m_qmakeBuildConfiguration(0),
     m_subNodeBuild(0)
 {
     ctor();
 }
 
-Qt4BuildConfiguration::Qt4BuildConfiguration(Qt4Target *target, Qt4BuildConfiguration *source) :
+Qt4BuildConfiguration::Qt4BuildConfiguration(Qt4BaseTarget *target, Qt4BuildConfiguration *source) :
     BuildConfiguration(target, source),
     m_shadowBuild(source->m_shadowBuild),
+    m_isEnabled(false),
     m_buildDirectory(source->m_buildDirectory),
     m_qtVersionId(source->m_qtVersionId),
-    m_toolChainType(source->m_toolChainType),
     m_qmakeBuildConfiguration(source->m_qmakeBuildConfiguration),
     m_subNodeBuild(0) // temporary value, so not copied
 {
@@ -107,63 +115,68 @@ QVariantMap Qt4BuildConfiguration::toMap() const
     map.insert(QLatin1String(USE_SHADOW_BUILD_KEY), m_shadowBuild);
     map.insert(QLatin1String(BUILD_DIRECTORY_KEY), m_buildDirectory);
     map.insert(QLatin1String(QT_VERSION_ID_KEY), m_qtVersionId);
-    map.insert(QLatin1String(TOOLCHAIN_KEY), m_toolChainType);
     map.insert(QLatin1String(BUILD_CONFIGURATION_KEY), int(m_qmakeBuildConfiguration));
     return map;
 }
 
+static inline QString msgBuildConfigNotApplicable(const QString &d, const QtSupport::BaseQtVersion *qtVersion,
+                                                  const Target *target)
+{
+    return QString::fromLatin1("Warning: Buildconfiguration '%1' : Qt '%2' from %3 not supported by target '%4'").
+            arg(d, qtVersion->displayName(), qtVersion->qmakeCommand(), target->id());
+}
 
 bool Qt4BuildConfiguration::fromMap(const QVariantMap &map)
 {
     if (!BuildConfiguration::fromMap(map))
         return false;
 
-    int fileVersion = map.value(ProjectExplorer::Constants::USERFILE_PREVIOUS_VERSION_KEY,
-                                std::numeric_limits<int>::max()).toInt();
     m_shadowBuild = map.value(QLatin1String(USE_SHADOW_BUILD_KEY), true).toBool();
-    m_buildDirectory = map.value(QLatin1String(BUILD_DIRECTORY_KEY), qt4Target()->defaultBuildDirectory()).toString();
     m_qtVersionId = map.value(QLatin1String(QT_VERSION_ID_KEY)).toInt();
-    m_toolChainType = map.value(QLatin1String(TOOLCHAIN_KEY)).toInt();
-    m_qmakeBuildConfiguration = QtVersion::QmakeBuildConfigs(map.value(QLatin1String(BUILD_CONFIGURATION_KEY)).toInt());
+    ProjectExplorer::ToolChain *tc = toolChain();
+    m_qmakeBuildConfiguration = QtSupport::BaseQtVersion::QmakeBuildConfigs(map.value(QLatin1String(BUILD_CONFIGURATION_KEY)).toInt());
+    m_buildDirectory = map.value(QLatin1String(BUILD_DIRECTORY_KEY), defaultShadowBuildDirectory()).toString();
 
     // Pick a Qt version if the default version is used:
     // We assume that the default Qt version was used in earlier versions of Qt creator.
-    // Pick a Qt version that is supporting a desktop.
+    // Pick a Qt version that supports this target (usually desktop)
     if (m_qtVersionId == 0) {
-        QList<QtVersion *> versions = QtVersionManager::instance()->versions();
-        foreach (QtVersion *v, versions) {
-            if (v->isValid() && v->supportsTargetId(QLatin1String(Constants::DESKTOP_TARGET_ID))) {
+        QList<QtSupport::BaseQtVersion *> versions = QtSupport::QtVersionManager::instance()->versionsForTargetId(target()->id());
+        foreach (QtSupport::BaseQtVersion *v, versions) {
+            if (v->isValid()) {
                 m_qtVersionId = v->uniqueId();
                 break;
             }
         }
         if (m_qtVersionId == 0)
-            m_qtVersionId = versions.at(0)->uniqueId();
+            m_qtVersionId = -1;
     }
 
-    QtVersion *version = qtVersion();
-    if (fileVersion >= 1) { // we are not upgrading from pre-targets!
-        if (version->isValid() && !version->supportedTargetIds().contains(target()->id())) {
-            qWarning() << "Buildconfiguration" << displayName() << ": Qt" << version->displayName() << "not supported by target" << target()->id();
-            return false;
-        }
-    } else {
-        if (!version->isValid() || !version->supportedTargetIds().contains(target()->id())) {
-            qWarning() << "Buildconfiguration" << displayName() << ": Qt" << version->displayName() << "not supported by target" << target()->id();
-            return false;
-        }
+    QtSupport::BaseQtVersion *version = QtSupport::QtVersionManager::instance()->version(m_qtVersionId);
+    if (!version || !version->supportsTargetId(target()->id())) {
+        m_qtVersionId = -1;
+        version = 0;
     }
 
-    if (version->isValid())
-        m_shadowBuild = (m_shadowBuild && version->supportsShadowBuilds());
+    m_lastEmmitedBuildDirectory = buildDirectory();
 
-    QList<ToolChain::ToolChainType> possibleTcs(qt4Target()->filterToolChainTypes(qtVersion()->possibleToolChainTypes()));
-    if (!possibleTcs.contains(toolChainType()))
-        setToolChainType(qt4Target()->preferredToolChainType(possibleTcs));
+    if (version && version->isValid()) {
+        if (tc && !qt4Target()->possibleToolChains(this).contains(tc))
+            setToolChain(0);
+        if (!toolChain())
+            setToolChain(qt4Target()->preferredToolChain(this));
+        m_shadowBuild = (m_shadowBuild && version->supportsShadowBuilds());
+    }
 
-    if (toolChainType() == ToolChain::INVALID) {
-        qWarning() << "No toolchain available for" << qtVersion()->displayName() << "used in" << target()->id() << "!";
-        return false;
+    if (!toolChain()) {
+        if (version && version->isValid()) {
+            qWarning("Warning: No tool chain available for '%s' from %s used in '%s'.",
+                    qPrintable(version->displayName()), qPrintable(version->qmakeCommand()),
+                    qPrintable(target()->id()));
+        } else {
+            qWarning("Warning: No tool chain available for invalid Qt version used in '%s'.",
+                     qPrintable(target()->id()));
+        }
     }
 
     return true;
@@ -171,16 +184,14 @@ bool Qt4BuildConfiguration::fromMap(const QVariantMap &map)
 
 void Qt4BuildConfiguration::ctor()
 {
-    m_buildDirectory = qt4Target()->defaultBuildDirectory();
-    if (m_buildDirectory == target()->project()->projectDirectory())
-        m_shadowBuild = false;
-
-    m_lastEmmitedBuildDirectory = buildDirectory();
-
     connect(this, SIGNAL(environmentChanged()),
             this, SLOT(emitBuildDirectoryChanged()));
+    connect(this, SIGNAL(environmentChanged()),
+            this, SLOT(emitProFileEvaluateNeeded()));
+    connect(qt4Target()->qt4Project(), SIGNAL(proFileUpdated(Qt4ProjectManager::Qt4ProFileNode*,bool,bool)),
+            this, SLOT(proFileUpdated()));
 
-    QtVersionManager *vm = QtVersionManager::instance();
+    QtSupport::QtVersionManager *vm = QtSupport::QtVersionManager::instance();
     connect(vm, SIGNAL(qtVersionsChanged(QList<int>)),
             this, SLOT(qtVersionsChanged(QList<int>)));
 }
@@ -193,28 +204,24 @@ void Qt4BuildConfiguration::emitBuildDirectoryChanged()
     }
 }
 
-void Qt4BuildConfiguration::pickValidQtVersion()
+void Qt4BuildConfiguration::proFileUpdated()
 {
-    QList<QtVersion *> versions = QtVersionManager::instance()->versionsForTargetId(qt4Target()->id());
-    if (!versions.isEmpty())
-        setQtVersion(versions.at(0));
-    else
-        setQtVersion(QtVersionManager::instance()->emptyVersion());
+    // Changing the included Qt modules from 0 to at least one might have caused the
+    // tool chain to become invalid.
+    if (!qt4Target()->possibleToolChains(this).contains(toolChain()))
+        setToolChain(qt4Target()->preferredToolChain(this));
 }
 
-Qt4Target *Qt4BuildConfiguration::qt4Target() const
+Qt4BaseTarget *Qt4BuildConfiguration::qt4Target() const
 {
-    return static_cast<Qt4Target *>(target());
+    return static_cast<Qt4BaseTarget *>(target());
 }
 
 Utils::Environment Qt4BuildConfiguration::baseEnvironment() const
 {
     Utils::Environment env = BuildConfiguration::baseEnvironment();
-    qtVersion()->addToEnvironment(env);
-
-    // We can't call buildDirectory() since that uses environment() to expand,
-    // thus calling baseEnvironment() again
-    env.set(QLatin1String("BUILDDIR"), QDir::toNativeSeparators(env.expandVariables(rawBuildDirectory())));
+    if (qtVersion())
+        qtVersion()->addToEnvironment(env);
 
     ToolChain *tc = toolChain();
     if (tc)
@@ -222,6 +229,13 @@ Utils::Environment Qt4BuildConfiguration::baseEnvironment() const
     return env;
 }
 
+QString Qt4BuildConfiguration::defaultShadowBuildDirectory() const
+{
+    Qt4BaseTargetFactory *factory = Qt4BaseTargetFactory::qt4BaseTargetFactoryForId(qt4Target()->id());
+    // todo displayName isn't ideal
+    return factory->shadowBuildDirectory(qt4Target()->qt4Project()->file()->fileName(), qt4Target()->id(), displayName());
+}
+
 /// returns the unexpanded build directory
 QString Qt4BuildConfiguration::rawBuildDirectory() const
 {
@@ -230,7 +244,7 @@ QString Qt4BuildConfiguration::rawBuildDirectory() const
         if (!m_buildDirectory.isEmpty())
             workingDirectory = m_buildDirectory;
         else
-            workingDirectory = qt4Target()->defaultBuildDirectory();
+            workingDirectory = defaultShadowBuildDirectory();
     }
     if (workingDirectory.isEmpty())
         workingDirectory = target()->project()->projectDirectory();
@@ -246,7 +260,7 @@ QString Qt4BuildConfiguration::buildDirectory() const
 /// If only a sub tree should be build this function returns which sub node
 /// should be build
 /// \see Qt4BuildConfiguration::setSubNodeBuild
-Qt4ProjectManager::Internal::Qt4ProFileNode *Qt4BuildConfiguration::subNodeBuild() const
+Qt4ProjectManager::Qt4ProFileNode *Qt4BuildConfiguration::subNodeBuild() const
 {
     return m_subNodeBuild;
 }
@@ -257,7 +271,7 @@ Qt4ProjectManager::Internal::Qt4ProFileNode *Qt4BuildConfiguration::subNodeBuild
 /// calling BuildManager::buildProject( BuildConfiguration * )
 /// and reset immediately afterwards
 /// That is m_subNodesBuild is set only temporarly
-void Qt4BuildConfiguration::setSubNodeBuild(Qt4ProjectManager::Internal::Qt4ProFileNode *node)
+void Qt4BuildConfiguration::setSubNodeBuild(Qt4ProjectManager::Qt4ProFileNode *node)
 {
     m_subNodeBuild = node;
 }
@@ -276,15 +290,15 @@ bool Qt4BuildConfiguration::shadowBuild() const
 QString Qt4BuildConfiguration::shadowBuildDirectory() const
 {
     if (m_buildDirectory.isEmpty())
-        return qt4Target()->defaultBuildDirectory();
+        return defaultShadowBuildDirectory();
     return m_buildDirectory;
 }
 
 void Qt4BuildConfiguration::setShadowBuildAndDirectory(bool shadowBuild, const QString &buildDirectory)
 {
-    QtVersion *version = qtVersion();
+    QtSupport::BaseQtVersion *version = qtVersion();
     QString directoryToSet = buildDirectory;
-    bool toSet = (shadowBuild && version->isValid() && version->supportsShadowBuilds());
+    bool toSet = (shadowBuild && version && version->isValid() && version->supportsShadowBuilds());
     if (m_shadowBuild == toSet && m_buildDirectory == directoryToSet)
         return;
 
@@ -296,22 +310,16 @@ void Qt4BuildConfiguration::setShadowBuildAndDirectory(bool shadowBuild, const Q
     emit proFileEvaluateNeeded(this);
 }
 
-ProjectExplorer::ToolChain *Qt4BuildConfiguration::toolChain() const
-{
-    ToolChain::ToolChainType tct = toolChainType();
-    return qtVersion()->toolChain(tct);
-}
-
 QString Qt4BuildConfiguration::makeCommand() const
 {
     ToolChain *tc = toolChain();
     return tc ? tc->makeCommand() : "make";
 }
 
-static inline QString symbianMakeTarget(QtVersion::QmakeBuildConfigs buildConfig,
+static inline QString symbianMakeTarget(QtSupport::BaseQtVersion::QmakeBuildConfigs buildConfig,
                                         const QString &type)
 {
-    QString rc = (buildConfig & QtVersion::DebugBuild) ?
+    QString rc = (buildConfig & QtSupport::BaseQtVersion::DebugBuild) ?
                  QLatin1String("debug-") : QLatin1String("release-");
     rc += type;
     return rc;
@@ -320,56 +328,43 @@ static inline QString symbianMakeTarget(QtVersion::QmakeBuildConfigs buildConfig
 QString Qt4BuildConfiguration::defaultMakeTarget() const
 {
     ToolChain *tc = toolChain();
-    if (!tc)
+    if (!tc || target()->id() != Constants::S60_DEVICE_TARGET_ID)
         return QString();
-    const QtVersion::QmakeBuildConfigs buildConfig = qmakeBuildConfiguration();
-
-    switch (tc->type()) {
-    case ToolChain::GCCE:
-        return symbianMakeTarget(buildConfig, QLatin1String("gcce"));
-    case ToolChain::RVCT_ARMV5:
-        return symbianMakeTarget(buildConfig, QLatin1String("armv5"));
-    case ToolChain::RVCT_ARMV6:
-        return symbianMakeTarget(buildConfig, QLatin1String("armv6"));
-    case ToolChain::RVCT_ARMV5_GNUPOC:
-    case ToolChain::GCCE_GNUPOC:
-    default:
-        break;
-    }
-    return QString();
+    const QtSupport::BaseQtVersion::QmakeBuildConfigs buildConfig = qmakeBuildConfiguration();
+
+    return symbianMakeTarget(buildConfig, tc->defaultMakeTarget());
 }
 
 QString Qt4BuildConfiguration::makefile() const
 {
-    if (qt4Target()->id() == Constants::S60_DEVICE_TARGET_ID)
-        return QString();
-    return qt4Target()->qt4Project()->rootProjectNode()->makefile();
+    return qt4Target()->qt4Project()->rootQt4ProjectNode()->makefile();
 }
 
-QtVersion *Qt4BuildConfiguration::qtVersion() const
+QtSupport::BaseQtVersion *Qt4BuildConfiguration::qtVersion() const
 {
-    QtVersionManager *vm = QtVersionManager::instance();
+    QtSupport::QtVersionManager *vm = QtSupport::QtVersionManager::instance();
     return vm->version(m_qtVersionId);
 }
 
-void Qt4BuildConfiguration::setQtVersion(QtVersion *version)
+void Qt4BuildConfiguration::setQtVersion(QtSupport::BaseQtVersion *version)
 {
-    Q_ASSERT(version);
-
-    if (m_qtVersionId == version->uniqueId())
+    if (version == 0) {
+        m_qtVersionId = -1;
+        m_shadowBuild = false;
+        setToolChain(0);
+        emit proFileEvaluateNeeded(this);
+        emit qtVersionChanged();
+        emit environmentChanged();
+        emitBuildDirectoryChanged();
         return;
+    }
+    if (m_qtVersionId == version->uniqueId())
+            return;
 
     m_qtVersionId = version->uniqueId();
 
-    if (!version->possibleToolChainTypes().contains(ProjectExplorer::ToolChain::ToolChainType(m_toolChainType))) {
-        QList<ToolChain::ToolChainType> candidates =
-                qt4Target()->filterToolChainTypes(qtVersion()->possibleToolChainTypes());
-        if (candidates.isEmpty())
-            m_toolChainType = ToolChain::INVALID;
-        else
-            m_toolChainType = candidates.first();
-    }
-
+    if (!qt4Target()->possibleToolChains(this).contains(toolChain()))
+        setToolChain(qt4Target()->preferredToolChain(this));
     m_shadowBuild = m_shadowBuild && qtVersion()->supportsShadowBuilds();
 
     emit proFileEvaluateNeeded(this);
@@ -378,31 +373,26 @@ void Qt4BuildConfiguration::setQtVersion(QtVersion *version)
     emitBuildDirectoryChanged();
 }
 
-void Qt4BuildConfiguration::setToolChainType(ProjectExplorer::ToolChain::ToolChainType type)
+void Qt4BuildConfiguration::setToolChain(ProjectExplorer::ToolChain *tc)
 {
-    if (!qt4Target()->filterToolChainTypes(qtVersion()->possibleToolChainTypes()).contains(type)
-        || m_toolChainType == type)
+    if (tc != 0 && !qt4Target()->possibleToolChains(this).contains(tc))
         return;
 
-    m_toolChainType = type;
+    if (toolChain() == tc)
+        return;
+
+    BuildConfiguration::setToolChain(tc);
 
     emit proFileEvaluateNeeded(this);
-    emit toolChainTypeChanged();
-    emit environmentChanged();
     emitBuildDirectoryChanged();
 }
 
-ProjectExplorer::ToolChain::ToolChainType Qt4BuildConfiguration::toolChainType() const
-{
-    return ToolChain::ToolChainType(m_toolChainType);
-}
-
-QtVersion::QmakeBuildConfigs Qt4BuildConfiguration::qmakeBuildConfiguration() const
+QtSupport::BaseQtVersion::QmakeBuildConfigs Qt4BuildConfiguration::qmakeBuildConfiguration() const
 {
     return m_qmakeBuildConfiguration;
 }
 
-void Qt4BuildConfiguration::setQMakeBuildConfiguration(QtVersion::QmakeBuildConfigs config)
+void Qt4BuildConfiguration::setQMakeBuildConfiguration(QtSupport::BaseQtVersion::QmakeBuildConfigs config)
 {
     if (m_qmakeBuildConfiguration == config)
         return;
@@ -410,9 +400,10 @@ void Qt4BuildConfiguration::setQMakeBuildConfiguration(QtVersion::QmakeBuildConf
 
     emit proFileEvaluateNeeded(this);
     emit qmakeBuildConfigurationChanged();
+    emitBuildDirectoryChanged();
 }
 
-void Qt4BuildConfiguration::emitProFileEvaluteNeeded()
+void Qt4BuildConfiguration::emitProFileEvaluateNeeded()
 {
     emit proFileEvaluateNeeded(this);
 }
@@ -436,20 +427,16 @@ void Qt4BuildConfiguration::emitS60CreatesSmartInstallerChanged()
 QStringList Qt4BuildConfiguration::configCommandLineArguments() const
 {
     QStringList result;
-    QtVersion::QmakeBuildConfigs defaultBuildConfiguration = qtVersion()->defaultBuildConfig();
-    QtVersion::QmakeBuildConfigs userBuildConfiguration = m_qmakeBuildConfiguration;
-    if ((defaultBuildConfiguration & QtVersion::BuildAll) && !(userBuildConfiguration & QtVersion::BuildAll))
+    QtSupport::BaseQtVersion::QmakeBuildConfigs defaultBuildConfiguration =  qtVersion() ? qtVersion()->defaultBuildConfig() : (QtSupport::BaseQtVersion::DebugBuild | QtSupport::BaseQtVersion::BuildAll);
+    QtSupport::BaseQtVersion::QmakeBuildConfigs userBuildConfiguration = m_qmakeBuildConfiguration;
+    if ((defaultBuildConfiguration & QtSupport::BaseQtVersion::BuildAll) && !(userBuildConfiguration & QtSupport::BaseQtVersion::BuildAll))
         result << "CONFIG-=debug_and_release";
 
-    if (!(defaultBuildConfiguration & QtVersion::BuildAll) && (userBuildConfiguration & QtVersion::BuildAll))
+    if (!(defaultBuildConfiguration & QtSupport::BaseQtVersion::BuildAll) && (userBuildConfiguration & QtSupport::BaseQtVersion::BuildAll))
         result << "CONFIG+=debug_and_release";
-    if ((defaultBuildConfiguration & QtVersion::DebugBuild)
-            && !(userBuildConfiguration & QtVersion::DebugBuild)
-            && !(userBuildConfiguration & QtVersion::BuildAll))
+    if ((defaultBuildConfiguration & QtSupport::BaseQtVersion::DebugBuild) && !(userBuildConfiguration & QtSupport::BaseQtVersion::DebugBuild))
         result << "CONFIG+=release";
-    if (!(defaultBuildConfiguration & QtVersion::DebugBuild)
-            && (userBuildConfiguration & QtVersion::DebugBuild)
-            && !(userBuildConfiguration & QtVersion::BuildAll))
+    if (!(defaultBuildConfiguration & QtSupport::BaseQtVersion::DebugBuild) && (userBuildConfiguration & QtSupport::BaseQtVersion::DebugBuild))
         result << "CONFIG+=debug";
     return result;
 }
@@ -478,11 +465,9 @@ MakeStep *Qt4BuildConfiguration::makeStep() const
 
 void Qt4BuildConfiguration::qtVersionsChanged(const QList<int> &changedVersions)
 {
-    if (!changedVersions.contains(m_qtVersionId) ||
-        qtVersion()->isValid())
+    if (!changedVersions.contains(m_qtVersionId))
         return;
-
-    pickValidQtVersion();
+    emit environmentChanged(); // Our qt version changed, that might have changed the environment
 }
 
 // returns true if both are equal
@@ -490,30 +475,31 @@ bool Qt4BuildConfiguration::compareToImportFrom(const QString &makefile)
 {
     QMakeStep *qs = qmakeStep();
     if (QFileInfo(makefile).exists() && qs) {
-        QString qmakePath = QtVersionManager::findQMakeBinaryFromMakefile(makefile);
-        QtVersion *version = qtVersion();
+        QString qmakePath = QtSupport::QtVersionManager::findQMakeBinaryFromMakefile(makefile);
+        QtSupport::BaseQtVersion *version = qtVersion();
+        if (!version)
+            return false;
         if (version->qmakeCommand() == qmakePath) {
             // same qtversion
-            QPair<QtVersion::QmakeBuildConfigs, QStringList> result =
-                    QtVersionManager::scanMakeFile(makefile, version->defaultBuildConfig());
+            QPair<QtSupport::BaseQtVersion::QmakeBuildConfigs, QString> result =
+                    QtSupport::QtVersionManager::scanMakeFile(makefile, version->defaultBuildConfig());
             if (qmakeBuildConfiguration() == result.first) {
                 // The qmake Build Configuration are the same,
                 // now compare arguments lists
                 // we have to compare without the spec/platform cmd argument
                 // and compare that on its own
                 QString workingDirectory = QFileInfo(makefile).absolutePath();
-                QString actualSpec = extractSpecFromArgumentList(qs->userArguments(), workingDirectory, version);
-                if (actualSpec.isEmpty()) {
-                    // Easy one: the user has chosen not to override the settings
-                    actualSpec = version->mkspec();
-                }
-
-
-                QString parsedSpec = extractSpecFromArgumentList(result.second, workingDirectory, version);
-                QStringList actualArgs = qs->moreArguments();
-                actualArgs << qs->userArguments();
-                actualArgs = removeSpecFromArgumentList(actualArgs);
-                QStringList parsedArgs = removeSpecFromArgumentList(result.second);
+                QStringList actualArgs;
+                QString userArgs = qs->userArguments();
+                // This copies the settings from userArgs to actualArgs (minus some we
+                // are not interested in), splitting them up into individual strings:
+                extractSpecFromArguments(&userArgs, workingDirectory, version, &actualArgs),
+                actualArgs += qs->moreArguments();
+                QString actualSpec = qs->mkspec();
+
+                QString qmakeArgs = result.second;
+                QStringList parsedArgs;
+                QString parsedSpec = extractSpecFromArguments(&qmakeArgs, workingDirectory, version, &parsedArgs);
 
                 if (debug) {
                     qDebug()<<"Actual args:"<<actualArgs;
@@ -558,59 +544,60 @@ bool Qt4BuildConfiguration::compareToImportFrom(const QString &makefile)
     return false;
 }
 
-QStringList Qt4BuildConfiguration::removeQMLInspectorFromArgumentList(const QStringList &old)
+bool Qt4BuildConfiguration::removeQMLInspectorFromArguments(QString *args)
 {
-    QStringList result;
-    foreach (const QString &str, old)
-        if (!str.startsWith(QLatin1String(Constants::QMAKEVAR_QMLJSDEBUGGER_PATH)))
-            result << str;
-    return result;
+    bool removedArgument = false;
+    for (Utils::QtcProcess::ArgIterator ait(args); ait.next(); ) {
+        const QString arg = ait.value();
+        if (arg.contains(QLatin1String(Constants::QMAKEVAR_QMLJSDEBUGGER_PATH))
+                || arg.contains(Constants::QMAKEVAR_DECLARATIVE_DEBUG)) {
+            ait.deleteArg();
+            removedArgument = true;
+        }
+    }
+    return removedArgument;
 }
 
-// We match -spec and -platfrom separetly
-// We ignore -cache, because qmake contained a bug that it didn't
-// mention the -cache in the Makefile
-// That means changing the -cache option in the additional arguments
-// does not automatically rerun qmake. Alas, we could try more
-// intelligent matching for -cache, but i guess people rarely
-// do use that.
-
-QStringList Qt4BuildConfiguration::removeSpecFromArgumentList(const QStringList &old)
+QString Qt4BuildConfiguration::extractSpecFromArguments(QString *args,
+                                                        const QString &directory, const QtSupport::BaseQtVersion *version,
+                                                        QStringList *outArgs)
 {
-    if (!old.contains("-spec") && !old.contains("-platform") && !old.contains("-cache"))
-        return old;
-    QStringList newList;
+    QString parsedSpec;
+
     bool ignoreNext = false;
-    foreach(const QString &item, old) {
+    bool nextIsSpec = false;
+    for (Utils::QtcProcess::ArgIterator ait(args); ait.next(); ) {
         if (ignoreNext) {
             ignoreNext = false;
-        } else if (item == "-spec" || item == "-platform" || item == "-cache") {
+            ait.deleteArg();
+        } else if (nextIsSpec) {
+            nextIsSpec = false;
+            parsedSpec = QDir::cleanPath(ait.value());
+            ait.deleteArg();
+        } else if (ait.value() == QLatin1String("-spec") || ait.value() == QLatin1String("-platform")) {
+            nextIsSpec = true;
+            ait.deleteArg();
+        } else if (ait.value() == QLatin1String("-cache")) {
+            // We ignore -cache, because qmake contained a bug that it didn't
+            // mention the -cache in the Makefile.
+            // That means changing the -cache option in the additional arguments
+            // does not automatically rerun qmake. Alas, we could try more
+            // intelligent matching for -cache, but i guess people rarely
+            // do use that.
             ignoreNext = true;
-        } else {
-            newList << item;
+            ait.deleteArg();
+        } else if (outArgs && ait.isSimple()) {
+            outArgs->append(ait.value());
         }
     }
-    return newList;
-}
 
-QString Qt4BuildConfiguration::extractSpecFromArgumentList(const QStringList &list, QString directory, QtVersion *version)
-{
-    int index = list.indexOf("-spec");
-    if (index == -1)
-        index = list.indexOf("-platform");
-    if (index == -1)
-        return QString();
-
-    ++index;
-
-    if (index >= list.length())
+    if (parsedSpec.isEmpty())
         return QString();
 
     QString baseMkspecDir = version->versionInfo().value("QMAKE_MKSPECS");
     if (baseMkspecDir.isEmpty())
         baseMkspecDir = version->versionInfo().value("QT_INSTALL_DATA") + "/mkspecs";
 
-    QString parsedSpec = QDir::cleanPath(list.at(index));
 #ifdef Q_OS_WIN
     baseMkspecDir = baseMkspecDir.toLower();
     parsedSpec = parsedSpec.toLower();
@@ -659,6 +646,26 @@ ProjectExplorer::IOutputParser *Qt4BuildConfiguration::createOutputParser() cons
     return 0;
 }
 
+bool Qt4BuildConfiguration::isEnabled() const
+{
+    return m_isEnabled;
+}
+
+QString Qt4BuildConfiguration::disabledReason() const
+{
+    if (!m_isEnabled)
+        return tr("Parsing the .pro file");
+    return QString();
+}
+
+void Qt4BuildConfiguration::setEnabled(bool enabled)
+{
+    if (m_isEnabled == enabled)
+        return;
+    m_isEnabled = enabled;
+    emit enabledChanged();
+}
+
 /*!
   \class Qt4BuildConfigurationFactory
 */
@@ -668,7 +675,7 @@ Qt4BuildConfigurationFactory::Qt4BuildConfigurationFactory(QObject *parent) :
 {
     update();
 
-    QtVersionManager *vm = QtVersionManager::instance();
+    QtSupport::QtVersionManager *vm = QtSupport::QtVersionManager::instance();
     connect(vm, SIGNAL(qtVersionsChanged(QList<int>)),
             this, SLOT(update()));
 }
@@ -680,28 +687,27 @@ Qt4BuildConfigurationFactory::~Qt4BuildConfigurationFactory()
 void Qt4BuildConfigurationFactory::update()
 {
     m_versions.clear();
-    QtVersionManager *vm = QtVersionManager::instance();
-    foreach (const QtVersion *version, vm->versions()) {
-        if (version->isValid()) {
-            QString key = QString::fromLatin1(QT4_BC_ID_PREFIX)
-                    + QString::fromLatin1("Qt%1").arg(version->uniqueId());
-            VersionInfo info(tr("Using Qt Version \"%1\"").arg(version->displayName()), version->uniqueId());
-            m_versions.insert(key, info);
-        }
+    QtSupport::QtVersionManager *vm = QtSupport::QtVersionManager::instance();
+    foreach (QtSupport::BaseQtVersion *version, vm->validVersions()) {
+        QString key = QString::fromLatin1(QT4_BC_ID_PREFIX)
+                + QString::fromLatin1("Qt%1").arg(version->uniqueId());
+        VersionInfo info(tr("Using Qt Version \"%1\"").arg(version->displayName()), version->uniqueId());
+        m_versions.insert(key, info);
     }
     emit availableCreationIdsChanged();
 }
 
 QStringList Qt4BuildConfigurationFactory::availableCreationIds(ProjectExplorer::Target *parent) const
 {
-    if (!qobject_cast<Qt4Target *>(parent))
+    if (!qobject_cast<Qt4BaseTarget *>(parent))
         return QStringList();
 
     QStringList results;
-    QtVersionManager *vm = QtVersionManager::instance();
+    QtSupport::QtVersionManager *vm = QtSupport::QtVersionManager::instance();
     for (QMap<QString, VersionInfo>::const_iterator i = m_versions.constBegin();
          i != m_versions.constEnd(); ++i) {
-        if (vm->version(i.value().versionId)->supportsTargetId(parent->id()))
+        if (vm->version(i.value().versionId)->supportsTargetId(parent->id())
+                && vm->version(i.value().versionId)->toolChainAvailable(parent->id()))
             results.append(i.key());
     }
     return results;
@@ -716,12 +722,12 @@ QString Qt4BuildConfigurationFactory::displayNameForId(const QString &id) const
 
 bool Qt4BuildConfigurationFactory::canCreate(ProjectExplorer::Target *parent, const QString &id) const
 {
-    if (!qobject_cast<Qt4Target *>(parent))
+    if (!qobject_cast<Qt4BaseTarget *>(parent))
         return false;
     if (!m_versions.contains(id))
         return false;
     const VersionInfo &info = m_versions.value(id);
-    QtVersion *version = QtVersionManager::instance()->version(info.versionId);
+    QtSupport::BaseQtVersion *version = QtSupport::QtVersionManager::instance()->version(info.versionId);
     if (!version ||
         !version->supportsTargetId(parent->id()))
         return false;
@@ -734,10 +740,10 @@ BuildConfiguration *Qt4BuildConfigurationFactory::create(ProjectExplorer::Target
         return 0;
 
     const VersionInfo &info = m_versions.value(id);
-    QtVersion *version = QtVersionManager::instance()->version(info.versionId);
+    QtSupport::BaseQtVersion *version = QtSupport::QtVersionManager::instance()->version(info.versionId);
     Q_ASSERT(version);
 
-    Qt4Target *qt4Target(static_cast<Qt4Target *>(parent));
+    Qt4BaseTarget *qt4Target = static_cast<Qt4BaseTarget *>(parent);
 
     bool ok;
     QString buildConfigurationName = QInputDialog::getText(0,
@@ -750,27 +756,41 @@ BuildConfiguration *Qt4BuildConfigurationFactory::create(ProjectExplorer::Target
     if (!ok || buildConfigurationName.isEmpty())
         return 0;
 
-    qt4Target->addQt4BuildConfiguration(tr("%1 Debug").arg(buildConfigurationName),
-                                        version,
-                                        (version->defaultBuildConfig() | QtVersion::DebugBuild),
-                                        QStringList(), QString());
-    BuildConfiguration *bc =
-    qt4Target->addQt4BuildConfiguration(tr("%1 Release").arg(buildConfigurationName),
+    //: Debug build configuration. We recommend not translating it.
+    QString defaultDebugName = tr("%1 Debug").arg(version->displayName());
+    QString customDebugName;
+    if (buildConfigurationName != version->displayName())
+        customDebugName = tr("%1 Debug").arg(buildConfigurationName);
+
+    BuildConfiguration *bc = qt4Target->addQt4BuildConfiguration(defaultDebugName, customDebugName,
                                         version,
-                                        (version->defaultBuildConfig() & ~QtVersion::DebugBuild),
-                                        QStringList(), QString());
+                                        (version->defaultBuildConfig() | QtSupport::BaseQtVersion::DebugBuild),
+                                        QString(), QString(), false);
+
+    if (qt4Target->id() != Constants::S60_EMULATOR_TARGET_ID) {
+        //: Release build configuration. We recommend not translating it.
+        QString defaultReleaseName = tr("%1 Release").arg(version->displayName());
+        QString customReleaseName;
+        if (buildConfigurationName != version->displayName())
+            customReleaseName = tr("%1 Release").arg(buildConfigurationName);
+
+        bc = qt4Target->addQt4BuildConfiguration(defaultReleaseName, customReleaseName,
+                                                 version,
+                                                 (version->defaultBuildConfig() & ~QtSupport::BaseQtVersion::DebugBuild),
+                                                 QString(), QString(), false);
+    }
     return bc;
 }
 
 bool Qt4BuildConfigurationFactory::canClone(ProjectExplorer::Target *parent, ProjectExplorer::BuildConfiguration *source) const
 {
-    if (!qobject_cast<Qt4Target *>(parent))
+    if (!qobject_cast<Qt4BaseTarget *>(parent))
         return false;
     Qt4BuildConfiguration *qt4bc(qobject_cast<Qt4BuildConfiguration *>(source));
     if (!qt4bc)
         return false;
 
-    QtVersion *version = qt4bc->qtVersion();
+    QtSupport::BaseQtVersion *version = qt4bc->qtVersion();
     if (!version ||
         !version->supportsTargetId(parent->id()))
         return false;
@@ -781,15 +801,15 @@ BuildConfiguration *Qt4BuildConfigurationFactory::clone(Target *parent, BuildCon
 {
     if (!canClone(parent, source))
         return 0;
-    Qt4Target *target(static_cast<Qt4Target *>(parent));
+    Qt4BaseTarget *target = static_cast<Qt4BaseTarget *>(parent);
     Qt4BuildConfiguration *oldbc(static_cast<Qt4BuildConfiguration *>(source));
     return new Qt4BuildConfiguration(target, oldbc);
 }
 
 bool Qt4BuildConfigurationFactory::canRestore(Target *parent, const QVariantMap &map) const
 {
-    QString id(ProjectExplorer::idFromMap(map));
-    if (!qobject_cast<Qt4Target *>(parent))
+    QString id = ProjectExplorer::idFromMap(map);
+    if (!qobject_cast<Qt4BaseTarget *>(parent))
         return false;
     return id.startsWith(QLatin1String(QT4_BC_ID_PREFIX)) ||
            id == QLatin1String(QT4_BC_ID);
@@ -799,10 +819,86 @@ BuildConfiguration *Qt4BuildConfigurationFactory::restore(Target *parent, const
 {
     if (!canRestore(parent, map))
         return 0;
-    Qt4Target *target(static_cast<Qt4Target *>(parent));
-    Qt4BuildConfiguration *bc(new Qt4BuildConfiguration(target));
+    Qt4BaseTarget *target = static_cast<Qt4BaseTarget *>(parent);
+    Qt4BuildConfiguration *bc = new Qt4BuildConfiguration(target);
     if (bc->fromMap(map))
         return bc;
     delete bc;
     return 0;
 }
+
+void Qt4BuildConfiguration::importFromBuildDirectory()
+{
+    QString directory = buildDirectory();
+    if (!directory.isEmpty()) {
+        QString mkfile = directory;
+        if (makefile().isEmpty())
+            mkfile.append("/Makefile");
+        else
+            mkfile.append(makefile());
+
+        QString qmakePath = QtSupport::QtVersionManager::findQMakeBinaryFromMakefile(mkfile);
+        if (!qmakePath.isEmpty()) {
+            QtSupport::QtVersionManager *vm = QtSupport::QtVersionManager::instance();
+            QtSupport::BaseQtVersion *version = vm->qtVersionForQMakeBinary(qmakePath);
+            if (!version) {
+                version = QtSupport::QtVersionFactory::createQtVersionFromQMakePath(qmakePath);
+                vm->addVersion(version);
+            }
+
+            QPair<QtSupport::BaseQtVersion::QmakeBuildConfigs, QString> result =
+                    QtSupport::QtVersionManager::scanMakeFile(mkfile, version->defaultBuildConfig());
+            QtSupport::BaseQtVersion::QmakeBuildConfigs qmakeBuildConfig = result.first;
+
+            QString additionalArguments = result.second;
+            QString parsedSpec = Qt4BuildConfiguration::extractSpecFromArguments(&additionalArguments, directory, version);
+            const bool enableQmlDebugger =
+                    Qt4BuildConfiguration::removeQMLInspectorFromArguments(&additionalArguments);
+
+            // So we got all the information now apply it...
+            setQtVersion(version);
+
+            QMakeStep *qs = qmakeStep();
+            qs->setUserArguments(additionalArguments);
+            qs->setLinkQmlDebuggingLibrary(enableQmlDebugger);
+            if (!parsedSpec.isEmpty() && parsedSpec != QLatin1String("default") && qs->mkspec() != parsedSpec) {
+                Utils::QtcProcess::addArgs(&additionalArguments, (QStringList() << "-spec" << parsedSpec));
+                qs->setUserArguments(additionalArguments);
+            }
+
+            setQMakeBuildConfiguration(qmakeBuildConfig);
+            // Adjust command line arguments, this is ugly as hell
+            // If we are switching to BuildAll we want "release" in there and no "debug"
+            // or "debug" in there and no "release"
+            // If we are switching to not BuildAll we want neither "release" nor "debug" in there
+            bool debug = qmakeBuildConfig & QtSupport::BaseQtVersion::DebugBuild;
+            bool haveTag = !(qmakeBuildConfig & QtSupport::BaseQtVersion::BuildAll);
+            QString makeCmdArguments = makeStep()->userArguments();
+            Utils::QtcProcess::ArgIterator ait(&makeCmdArguments);
+            while (ait.next()) {
+                if (ait.value() == QLatin1String("debug")) {
+                    if (!haveTag && debug)
+                        haveTag = true;
+                    else
+                        ait.deleteArg();
+                } else if (ait.value() == QLatin1String("release")) {
+                    if (!haveTag && !debug)
+                        haveTag = true;
+                    else
+                        ait.deleteArg();
+                }
+            }
+            if (!haveTag)
+                ait.appendArg(QLatin1String(debug ? "debug" : "release"));
+            makeStep()->setUserArguments(makeCmdArguments);
+        }
+    }
+}
+
+BuildConfiguration::BuildType Qt4BuildConfiguration::buildType() const
+{
+    if (qmakeBuildConfiguration() & QtSupport::BaseQtVersion::DebugBuild)
+        return Debug;
+    else
+        return Release;
+}