1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights. These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
32 **************************************************************************/
34 #include "qt4buildconfiguration.h"
36 #include "qt4project.h"
37 #include "qt4target.h"
38 #include "qt4projectmanagerconstants.h"
40 #include "qmakestep.h"
43 #include <utils/qtcassert.h>
44 #include <utils/qtcprocess.h>
46 #include <projectexplorer/buildsteplist.h>
47 #include <projectexplorer/projectexplorerconstants.h>
49 #include <QtCore/QDebug>
51 #include <QtGui/QInputDialog>
53 using namespace Qt4ProjectManager;
54 using namespace Qt4ProjectManager::Internal;
55 using namespace ProjectExplorer;
58 const char * const QT4_BC_ID_PREFIX("Qt4ProjectManager.Qt4BuildConfiguration.");
59 const char * const QT4_BC_ID("Qt4ProjectManager.Qt4BuildConfiguration");
61 const char * const USE_SHADOW_BUILD_KEY("Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild");
62 const char * const BUILD_DIRECTORY_KEY("Qt4ProjectManager.Qt4BuildConfiguration.BuildDirectory");
63 const char * const TOOLCHAIN_KEY("Qt4ProjectManager.Qt4BuildConfiguration.ToolChain");
64 const char * const BUILD_CONFIGURATION_KEY("Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration");
65 const char * const QT_VERSION_ID_KEY("Qt4ProjectManager.Qt4BuildConfiguration.QtVersionId");
70 Qt4BuildConfiguration::Qt4BuildConfiguration(Qt4BaseTarget *target) :
71 BuildConfiguration(target, QLatin1String(QT4_BC_ID)),
74 m_toolChainType(-1), // toolChainType() makes sure to return the default toolchainType
75 m_qmakeBuildConfiguration(0),
81 Qt4BuildConfiguration::Qt4BuildConfiguration(Qt4BaseTarget *target, const QString &id) :
82 BuildConfiguration(target, id),
85 m_toolChainType(-1), // toolChainType() makes sure to return the default toolchainType
86 m_qmakeBuildConfiguration(0),
92 Qt4BuildConfiguration::Qt4BuildConfiguration(Qt4BaseTarget *target, Qt4BuildConfiguration *source) :
93 BuildConfiguration(target, source),
94 m_shadowBuild(source->m_shadowBuild),
95 m_buildDirectory(source->m_buildDirectory),
96 m_qtVersionId(source->m_qtVersionId),
97 m_toolChainType(source->m_toolChainType),
98 m_qmakeBuildConfiguration(source->m_qmakeBuildConfiguration),
99 m_subNodeBuild(0) // temporary value, so not copied
105 Qt4BuildConfiguration::~Qt4BuildConfiguration()
109 QVariantMap Qt4BuildConfiguration::toMap() const
111 QVariantMap map(BuildConfiguration::toMap());
112 map.insert(QLatin1String(USE_SHADOW_BUILD_KEY), m_shadowBuild);
113 map.insert(QLatin1String(BUILD_DIRECTORY_KEY), m_buildDirectory);
114 map.insert(QLatin1String(QT_VERSION_ID_KEY), m_qtVersionId);
115 map.insert(QLatin1String(TOOLCHAIN_KEY), m_toolChainType);
116 map.insert(QLatin1String(BUILD_CONFIGURATION_KEY), int(m_qmakeBuildConfiguration));
121 bool Qt4BuildConfiguration::fromMap(const QVariantMap &map)
123 if (!BuildConfiguration::fromMap(map))
126 m_shadowBuild = map.value(QLatin1String(USE_SHADOW_BUILD_KEY), true).toBool();
127 m_buildDirectory = map.value(QLatin1String(BUILD_DIRECTORY_KEY), qt4Target()->defaultBuildDirectory()).toString();
128 m_qtVersionId = map.value(QLatin1String(QT_VERSION_ID_KEY)).toInt();
129 m_toolChainType = map.value(QLatin1String(TOOLCHAIN_KEY)).toInt();
130 m_qmakeBuildConfiguration = QtVersion::QmakeBuildConfigs(map.value(QLatin1String(BUILD_CONFIGURATION_KEY)).toInt());
132 // Pick a Qt version if the default version is used:
133 // We assume that the default Qt version was used in earlier versions of Qt creator.
134 // Pick a Qt version that is supporting a desktop.
135 if (m_qtVersionId == 0) {
136 QList<QtVersion *> versions = QtVersionManager::instance()->versions();
137 foreach (QtVersion *v, versions) {
138 if (v->isValid() && v->supportsTargetId(QLatin1String(Constants::DESKTOP_TARGET_ID))) {
139 m_qtVersionId = v->uniqueId();
143 if (m_qtVersionId == 0)
144 m_qtVersionId = versions.at(0)->uniqueId();
147 QtVersion *version = qtVersion();
148 if (!map.contains(QLatin1String("Qt4ProjectManager.Qt4BuildConfiguration.NeedsV0Update"))) { // we are not upgrading from pre-targets!
149 if (version->isValid() && !version->supportedTargetIds().contains(target()->id())) {
150 qWarning() << "Buildconfiguration" << displayName() << ": Qt" << version->displayName() << "not supported by target" << target()->id();
154 if (!version->isValid() || !version->supportedTargetIds().contains(target()->id())) {
155 qWarning() << "Buildconfiguration" << displayName() << ": Qt" << version->displayName() << "not supported by target" << target()->id();
160 if (version->isValid())
161 m_shadowBuild = (m_shadowBuild && version->supportsShadowBuilds());
163 QList<ProjectExplorer::ToolChainType> possibleTcs(qt4Target()->filterToolChainTypes(qtVersion()->possibleToolChainTypes()));
164 if (!possibleTcs.contains(toolChainType()))
165 setToolChainType(qt4Target()->preferredToolChainType(possibleTcs));
167 if (toolChainType() == ProjectExplorer::ToolChain_INVALID) {
168 qWarning() << "No toolchain available for" << qtVersion()->displayName() << "used in" << target()->id() << "!";
175 void Qt4BuildConfiguration::ctor()
177 m_buildDirectory = qt4Target()->defaultBuildDirectory();
178 if (m_buildDirectory == target()->project()->projectDirectory())
179 m_shadowBuild = false;
181 m_lastEmmitedBuildDirectory = buildDirectory();
183 connect(this, SIGNAL(environmentChanged()),
184 this, SLOT(emitBuildDirectoryChanged()));
186 QtVersionManager *vm = QtVersionManager::instance();
187 connect(vm, SIGNAL(qtVersionsChanged(QList<int>)),
188 this, SLOT(qtVersionsChanged(QList<int>)));
191 void Qt4BuildConfiguration::emitBuildDirectoryChanged()
193 if (buildDirectory() != m_lastEmmitedBuildDirectory) {
194 m_lastEmmitedBuildDirectory = buildDirectory();
195 emit buildDirectoryChanged();
199 void Qt4BuildConfiguration::pickValidQtVersion()
201 QList<QtVersion *> versions = QtVersionManager::instance()->versionsForTargetId(qt4Target()->id());
202 if (!versions.isEmpty())
203 setQtVersion(versions.at(0));
205 setQtVersion(QtVersionManager::instance()->emptyVersion());
208 Qt4BaseTarget *Qt4BuildConfiguration::qt4Target() const
210 return static_cast<Qt4BaseTarget *>(target());
213 Utils::Environment Qt4BuildConfiguration::baseEnvironment() const
215 Utils::Environment env = BuildConfiguration::baseEnvironment();
216 qtVersion()->addToEnvironment(env);
218 ToolChain *tc = toolChain();
220 tc->addToEnvironment(env);
224 /// returns the unexpanded build directory
225 QString Qt4BuildConfiguration::rawBuildDirectory() const
227 QString workingDirectory;
229 if (!m_buildDirectory.isEmpty())
230 workingDirectory = m_buildDirectory;
232 workingDirectory = qt4Target()->defaultBuildDirectory();
234 if (workingDirectory.isEmpty())
235 workingDirectory = target()->project()->projectDirectory();
236 return workingDirectory;
239 /// returns the build directory
240 QString Qt4BuildConfiguration::buildDirectory() const
242 return QDir::cleanPath(environment().expandVariables(rawBuildDirectory()));
245 /// If only a sub tree should be build this function returns which sub node
247 /// \see Qt4BuildConfiguration::setSubNodeBuild
248 Qt4ProjectManager::Internal::Qt4ProFileNode *Qt4BuildConfiguration::subNodeBuild() const
250 return m_subNodeBuild;
253 /// A sub node build on builds a sub node of the project
254 /// That is triggered by a right click in the project explorer tree
255 /// The sub node to be build is set via this function immediately before
256 /// calling BuildManager::buildProject( BuildConfiguration * )
257 /// and reset immediately afterwards
258 /// That is m_subNodesBuild is set only temporarly
259 void Qt4BuildConfiguration::setSubNodeBuild(Qt4ProjectManager::Internal::Qt4ProFileNode *node)
261 m_subNodeBuild = node;
264 /// returns whether this is a shadow build configuration or not
265 /// note, even if shadowBuild() returns true, it might be using the
266 /// source directory as the shadow build directory, thus it
267 /// still is a in-source build
268 bool Qt4BuildConfiguration::shadowBuild() const
270 return m_shadowBuild;
273 /// returns the shadow build directory if set
274 /// \note buildDirectory() is probably the function you want to call
275 QString Qt4BuildConfiguration::shadowBuildDirectory() const
277 if (m_buildDirectory.isEmpty())
278 return qt4Target()->defaultBuildDirectory();
279 return m_buildDirectory;
282 void Qt4BuildConfiguration::setShadowBuildAndDirectory(bool shadowBuild, const QString &buildDirectory)
284 QtVersion *version = qtVersion();
285 QString directoryToSet = buildDirectory;
286 bool toSet = (shadowBuild && version->isValid() && version->supportsShadowBuilds());
287 if (m_shadowBuild == toSet && m_buildDirectory == directoryToSet)
290 m_shadowBuild = toSet;
291 m_buildDirectory = directoryToSet;
293 emit environmentChanged();
294 emitBuildDirectoryChanged();
295 emit proFileEvaluateNeeded(this);
298 ProjectExplorer::ToolChain *Qt4BuildConfiguration::toolChain() const
300 const ProjectExplorer::ToolChainType tct = toolChainType();
301 return qtVersion()->toolChain(tct);
304 QString Qt4BuildConfiguration::makeCommand() const
306 ToolChain *tc = toolChain();
307 return tc ? tc->makeCommand() : "make";
310 static inline QString symbianMakeTarget(QtVersion::QmakeBuildConfigs buildConfig,
313 QString rc = (buildConfig & QtVersion::DebugBuild) ?
314 QLatin1String("debug-") : QLatin1String("release-");
319 QString Qt4BuildConfiguration::defaultMakeTarget() const
321 ToolChain *tc = toolChain();
324 const QtVersion::QmakeBuildConfigs buildConfig = qmakeBuildConfiguration();
326 switch (tc->type()) {
327 case ProjectExplorer::ToolChain_GCCE:
328 return symbianMakeTarget(buildConfig, QLatin1String("gcce"));
329 case ProjectExplorer::ToolChain_RVCT2_ARMV5:
330 case ProjectExplorer::ToolChain_RVCT4_ARMV5:
331 return symbianMakeTarget(buildConfig, QLatin1String("armv5"));
332 case ProjectExplorer::ToolChain_RVCT2_ARMV6:
333 case ProjectExplorer::ToolChain_RVCT4_ARMV6:
334 return symbianMakeTarget(buildConfig, QLatin1String("armv6"));
335 case ProjectExplorer::ToolChain_RVCT_ARMV5_GNUPOC:
336 case ProjectExplorer::ToolChain_GCCE_GNUPOC:
343 QString Qt4BuildConfiguration::makefile() const
345 return qt4Target()->qt4Project()->rootProjectNode()->makefile();
348 QtVersion *Qt4BuildConfiguration::qtVersion() const
350 QtVersionManager *vm = QtVersionManager::instance();
351 return vm->version(m_qtVersionId);
354 void Qt4BuildConfiguration::setQtVersion(QtVersion *version)
358 if (m_qtVersionId == version->uniqueId())
361 m_qtVersionId = version->uniqueId();
363 if (!version->possibleToolChainTypes().contains(ProjectExplorer::ToolChainType(m_toolChainType))) {
364 QList<ProjectExplorer::ToolChainType> candidates =
365 qt4Target()->filterToolChainTypes(qtVersion()->possibleToolChainTypes());
366 if (candidates.isEmpty())
367 m_toolChainType = ProjectExplorer::ToolChain_INVALID;
369 m_toolChainType = candidates.first();
372 m_shadowBuild = m_shadowBuild && qtVersion()->supportsShadowBuilds();
374 emit proFileEvaluateNeeded(this);
375 emit qtVersionChanged();
376 emit environmentChanged();
377 emitBuildDirectoryChanged();
380 void Qt4BuildConfiguration::setToolChainType(ProjectExplorer::ToolChainType type)
382 if (!qt4Target()->filterToolChainTypes(qtVersion()->possibleToolChainTypes()).contains(type)
383 || m_toolChainType == type)
386 m_toolChainType = type;
388 emit proFileEvaluateNeeded(this);
389 emit toolChainTypeChanged();
390 emit environmentChanged();
391 emitBuildDirectoryChanged();
394 ProjectExplorer::ToolChainType Qt4BuildConfiguration::toolChainType() const
396 return ProjectExplorer::ToolChainType(m_toolChainType);
399 QtVersion::QmakeBuildConfigs Qt4BuildConfiguration::qmakeBuildConfiguration() const
401 return m_qmakeBuildConfiguration;
404 void Qt4BuildConfiguration::setQMakeBuildConfiguration(QtVersion::QmakeBuildConfigs config)
406 if (m_qmakeBuildConfiguration == config)
408 m_qmakeBuildConfiguration = config;
410 emit proFileEvaluateNeeded(this);
411 emit qmakeBuildConfigurationChanged();
414 void Qt4BuildConfiguration::emitProFileEvaluteNeeded()
416 emit proFileEvaluateNeeded(this);
419 void Qt4BuildConfiguration::emitQMakeBuildConfigurationChanged()
421 emit qmakeBuildConfigurationChanged();
424 void Qt4BuildConfiguration::emitBuildDirectoryInitialized()
426 emit buildDirectoryInitialized();
429 void Qt4BuildConfiguration::emitS60CreatesSmartInstallerChanged()
431 emit s60CreatesSmartInstallerChanged();
435 QStringList Qt4BuildConfiguration::configCommandLineArguments() const
438 QtVersion::QmakeBuildConfigs defaultBuildConfiguration = qtVersion()->defaultBuildConfig();
439 QtVersion::QmakeBuildConfigs userBuildConfiguration = m_qmakeBuildConfiguration;
440 if ((defaultBuildConfiguration & QtVersion::BuildAll) && !(userBuildConfiguration & QtVersion::BuildAll))
441 result << "CONFIG-=debug_and_release";
443 if (!(defaultBuildConfiguration & QtVersion::BuildAll) && (userBuildConfiguration & QtVersion::BuildAll))
444 result << "CONFIG+=debug_and_release";
445 if ((defaultBuildConfiguration & QtVersion::DebugBuild)
446 && !(userBuildConfiguration & QtVersion::DebugBuild)
447 && !(userBuildConfiguration & QtVersion::BuildAll))
448 result << "CONFIG+=release";
449 if (!(defaultBuildConfiguration & QtVersion::DebugBuild)
450 && (userBuildConfiguration & QtVersion::DebugBuild)
451 && !(userBuildConfiguration & QtVersion::BuildAll))
452 result << "CONFIG+=debug";
456 QMakeStep *Qt4BuildConfiguration::qmakeStep() const
459 BuildStepList *bsl = stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
461 for (int i = 0; i < bsl->count(); ++i)
462 if ((qs = qobject_cast<QMakeStep *>(bsl->at(i))) != 0)
467 MakeStep *Qt4BuildConfiguration::makeStep() const
470 BuildStepList *bsl = stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
472 for (int i = 0; i < bsl->count(); ++i)
473 if ((ms = qobject_cast<MakeStep *>(bsl->at(i))) != 0)
478 void Qt4BuildConfiguration::qtVersionsChanged(const QList<int> &changedVersions)
480 if (!changedVersions.contains(m_qtVersionId) ||
481 qtVersion()->isValid())
484 pickValidQtVersion();
487 // returns true if both are equal
488 bool Qt4BuildConfiguration::compareToImportFrom(const QString &makefile)
490 QMakeStep *qs = qmakeStep();
491 if (QFileInfo(makefile).exists() && qs) {
492 QString qmakePath = QtVersionManager::findQMakeBinaryFromMakefile(makefile);
493 QtVersion *version = qtVersion();
494 if (version->qmakeCommand() == qmakePath) {
496 QPair<QtVersion::QmakeBuildConfigs, QString> result =
497 QtVersionManager::scanMakeFile(makefile, version->defaultBuildConfig());
498 if (qmakeBuildConfiguration() == result.first) {
499 // The qmake Build Configuration are the same,
500 // now compare arguments lists
501 // we have to compare without the spec/platform cmd argument
502 // and compare that on its own
503 QString workingDirectory = QFileInfo(makefile).absolutePath();
504 QString userArgs = qs->userArguments();
505 QStringList actualArgs;
506 QString actualSpec = extractSpecFromArguments(&userArgs, workingDirectory, version, &actualArgs);
507 if (actualSpec.isEmpty()) {
508 // Easy one: the user has chosen not to override the settings
509 actualSpec = version->mkspec();
511 actualArgs += qs->moreArguments();
513 QString qmakeArgs = result.second;
514 QStringList parsedArgs;
515 QString parsedSpec = extractSpecFromArguments(&qmakeArgs, workingDirectory, version, &parsedArgs);
518 qDebug()<<"Actual args:"<<actualArgs;
519 qDebug()<<"Parsed args:"<<parsedArgs;
520 qDebug()<<"Actual spec:"<<actualSpec;
521 qDebug()<<"Parsed spec:"<<parsedSpec;
524 // Comparing the sorted list is obviously wrong
525 // Though haven written a more complete version
526 // that managed had around 200 lines and yet faild
527 // to be actually foolproof at all, I think it's
528 // not feasible without actually taking the qmake
529 // command line parsing code
531 // Things, sorting gets wrong:
532 // parameters to positional parameters matter
533 // e.g. -o -spec is different from -spec -o
534 // -o 1 -spec 2 is diffrent from -spec 1 -o 2
535 // variable assignment order matters
536 // variable assignment vs -after
537 // -norecursive vs. recursive
540 if (actualArgs == parsedArgs) {
541 // Specs match exactly
542 if (actualSpec == parsedSpec)
544 // Actual spec is the default one
545 // qDebug()<<"AS vs VS"<<actualSpec<<version->mkspec();
546 if ((actualSpec == version->mkspec() || actualSpec == "default")
547 && (parsedSpec == version->mkspec() || parsedSpec == "default" || parsedSpec.isEmpty()))
551 qDebug()<<"different qmake buildconfigurations buildconfiguration:"<<qmakeBuildConfiguration()<<" Makefile:"<<result.first;
554 qDebug()<<"diffrent qt versions, buildconfiguration:"<<version->qmakeCommand()<<" Makefile:"<<qmakePath;
560 void Qt4BuildConfiguration::removeQMLInspectorFromArguments(QString *args)
562 for (Utils::QtcProcess::ArgIterator ait(args); ait.next(); )
563 if (ait.value().startsWith(QLatin1String(Constants::QMAKEVAR_QMLJSDEBUGGER_PATH)))
567 QString Qt4BuildConfiguration::extractSpecFromArguments(QString *args,
568 const QString &directory, const QtVersion *version,
569 QStringList *outArgs)
573 bool ignoreNext = false;
574 bool nextIsSpec = false;
575 for (Utils::QtcProcess::ArgIterator ait(args); ait.next(); ) {
579 } else if (nextIsSpec) {
581 parsedSpec = QDir::cleanPath(ait.value());
583 } else if (ait.value() == QLatin1String("-spec") || ait.value() == QLatin1String("-platform")) {
586 } else if (ait.value() == QLatin1String("-cache")) {
587 // We ignore -cache, because qmake contained a bug that it didn't
588 // mention the -cache in the Makefile.
589 // That means changing the -cache option in the additional arguments
590 // does not automatically rerun qmake. Alas, we could try more
591 // intelligent matching for -cache, but i guess people rarely
595 } else if (outArgs && ait.isSimple()) {
596 outArgs->append(ait.value());
600 if (parsedSpec.isEmpty())
603 QString baseMkspecDir = version->versionInfo().value("QMAKE_MKSPECS");
604 if (baseMkspecDir.isEmpty())
605 baseMkspecDir = version->versionInfo().value("QT_INSTALL_DATA") + "/mkspecs";
608 baseMkspecDir = baseMkspecDir.toLower();
609 parsedSpec = parsedSpec.toLower();
611 // if the path is relative it can be
612 // relative to the working directory (as found in the Makefiles)
613 // or relatively to the mkspec directory
614 // if it is the former we need to get the canonical form
615 // for the other one we don't need to do anything
616 if (QFileInfo(parsedSpec).isRelative()) {
617 if(QFileInfo(directory + QLatin1Char('/') + parsedSpec).exists()) {
618 parsedSpec = QDir::cleanPath(directory + QLatin1Char('/') + parsedSpec);
620 parsedSpec = parsedSpec.toLower();
623 parsedSpec = baseMkspecDir + QLatin1Char('/') + parsedSpec;
627 QFileInfo f2(parsedSpec);
628 while (f2.isSymLink()) {
629 parsedSpec = f2.symLinkTarget();
630 f2.setFile(parsedSpec);
633 if (parsedSpec.startsWith(baseMkspecDir)) {
634 parsedSpec = parsedSpec.mid(baseMkspecDir.length() + 1);
636 QString sourceMkSpecPath = version->sourcePath() + "/mkspecs";
637 if (parsedSpec.startsWith(sourceMkSpecPath)) {
638 parsedSpec = parsedSpec.mid(sourceMkSpecPath.length() + 1);
642 parsedSpec = parsedSpec.toLower();
647 ProjectExplorer::IOutputParser *Qt4BuildConfiguration::createOutputParser() const
649 ToolChain *tc = toolChain();
651 return toolChain()->outputParser();
656 \class Qt4BuildConfigurationFactory
659 Qt4BuildConfigurationFactory::Qt4BuildConfigurationFactory(QObject *parent) :
660 ProjectExplorer::IBuildConfigurationFactory(parent)
664 QtVersionManager *vm = QtVersionManager::instance();
665 connect(vm, SIGNAL(qtVersionsChanged(QList<int>)),
666 this, SLOT(update()));
669 Qt4BuildConfigurationFactory::~Qt4BuildConfigurationFactory()
673 void Qt4BuildConfigurationFactory::update()
676 QtVersionManager *vm = QtVersionManager::instance();
677 foreach (const QtVersion *version, vm->versions()) {
678 if (version->isValid()) {
679 QString key = QString::fromLatin1(QT4_BC_ID_PREFIX)
680 + QString::fromLatin1("Qt%1").arg(version->uniqueId());
681 VersionInfo info(tr("Using Qt Version \"%1\"").arg(version->displayName()), version->uniqueId());
682 m_versions.insert(key, info);
685 emit availableCreationIdsChanged();
688 QStringList Qt4BuildConfigurationFactory::availableCreationIds(ProjectExplorer::Target *parent) const
690 if (!qobject_cast<Qt4BaseTarget *>(parent))
691 return QStringList();
694 QtVersionManager *vm = QtVersionManager::instance();
695 for (QMap<QString, VersionInfo>::const_iterator i = m_versions.constBegin();
696 i != m_versions.constEnd(); ++i) {
697 if (vm->version(i.value().versionId)->supportsTargetId(parent->id()))
698 results.append(i.key());
703 QString Qt4BuildConfigurationFactory::displayNameForId(const QString &id) const
705 if (!m_versions.contains(id))
707 return m_versions.value(id).displayName;
710 bool Qt4BuildConfigurationFactory::canCreate(ProjectExplorer::Target *parent, const QString &id) const
712 if (!qobject_cast<Qt4BaseTarget *>(parent))
714 if (!m_versions.contains(id))
716 const VersionInfo &info = m_versions.value(id);
717 QtVersion *version = QtVersionManager::instance()->version(info.versionId);
719 !version->supportsTargetId(parent->id()))
724 BuildConfiguration *Qt4BuildConfigurationFactory::create(ProjectExplorer::Target *parent, const QString &id)
726 if (!canCreate(parent, id))
729 const VersionInfo &info = m_versions.value(id);
730 QtVersion *version = QtVersionManager::instance()->version(info.versionId);
733 Qt4BaseTarget *qt4Target = static_cast<Qt4BaseTarget *>(parent);
736 QString buildConfigurationName = QInputDialog::getText(0,
737 tr("New Configuration"),
738 tr("New configuration name:"),
740 version->displayName(),
742 buildConfigurationName = buildConfigurationName.trimmed();
743 if (!ok || buildConfigurationName.isEmpty())
746 qt4Target->addQt4BuildConfiguration(tr("%1 Debug").arg(buildConfigurationName),
748 (version->defaultBuildConfig() | QtVersion::DebugBuild),
749 QString(), QString());
750 BuildConfiguration *bc =
751 qt4Target->addQt4BuildConfiguration(tr("%1 Release").arg(buildConfigurationName),
753 (version->defaultBuildConfig() & ~QtVersion::DebugBuild),
754 QString(), QString());
758 bool Qt4BuildConfigurationFactory::canClone(ProjectExplorer::Target *parent, ProjectExplorer::BuildConfiguration *source) const
760 if (!qobject_cast<Qt4BaseTarget *>(parent))
762 Qt4BuildConfiguration *qt4bc(qobject_cast<Qt4BuildConfiguration *>(source));
766 QtVersion *version = qt4bc->qtVersion();
768 !version->supportsTargetId(parent->id()))
773 BuildConfiguration *Qt4BuildConfigurationFactory::clone(Target *parent, BuildConfiguration *source)
775 if (!canClone(parent, source))
777 Qt4BaseTarget *target = static_cast<Qt4BaseTarget *>(parent);
778 Qt4BuildConfiguration *oldbc(static_cast<Qt4BuildConfiguration *>(source));
779 return new Qt4BuildConfiguration(target, oldbc);
782 bool Qt4BuildConfigurationFactory::canRestore(Target *parent, const QVariantMap &map) const
784 QString id = ProjectExplorer::idFromMap(map);
785 if (!qobject_cast<Qt4BaseTarget *>(parent))
787 return id.startsWith(QLatin1String(QT4_BC_ID_PREFIX)) ||
788 id == QLatin1String(QT4_BC_ID);
791 BuildConfiguration *Qt4BuildConfigurationFactory::restore(Target *parent, const QVariantMap &map)
793 if (!canRestore(parent, map))
795 Qt4BaseTarget *target = static_cast<Qt4BaseTarget *>(parent);
796 Qt4BuildConfiguration *bc = new Qt4BuildConfiguration(target);
797 if (bc->fromMap(map))
803 void Qt4BuildConfiguration::importFromBuildDirectory()
805 QString directory = buildDirectory();
806 if (!directory.isEmpty()) {
807 QString mkfile = directory;
808 if (makefile().isEmpty())
809 mkfile.append("/Makefile");
811 mkfile.append(makefile());
813 QString qmakePath = QtVersionManager::findQMakeBinaryFromMakefile(mkfile);
814 if (!qmakePath.isEmpty()) {
815 QtVersionManager *vm = QtVersionManager::instance();
816 QtVersion *version = vm->qtVersionForQMakeBinary(qmakePath);
818 version = new QtVersion(qmakePath);
819 vm->addVersion(version);
822 QPair<QtVersion::QmakeBuildConfigs, QString> result =
823 QtVersionManager::scanMakeFile(directory, version->defaultBuildConfig());
824 QtVersion::QmakeBuildConfigs qmakeBuildConfig = result.first;
826 QString aa = result.second;
827 QString parsedSpec = Qt4BuildConfiguration::extractSpecFromArguments(&aa, directory, version);
828 QString versionSpec = version->mkspec();
829 QString additionalArguments;
830 if (parsedSpec.isEmpty() || parsedSpec == versionSpec || parsedSpec == "default") {
831 // using the default spec, don't modify additional arguments
833 additionalArguments = "-spec " + Utils::QtcProcess::quoteArg(parsedSpec);
835 Utils::QtcProcess::addArgs(&additionalArguments, aa);
837 Qt4BuildConfiguration::removeQMLInspectorFromArguments(&additionalArguments);
839 // So we got all the information now apply it...
840 setQtVersion(version);
842 qmakeStep()->setUserArguments(additionalArguments);
844 setQMakeBuildConfiguration(qmakeBuildConfig);
845 // Adjust command line arguments, this is ugly as hell
846 // If we are switching to BuildAll we want "release" in there and no "debug"
847 // or "debug" in there and no "release"
848 // If we are switching to not BuildAl we want neither "release" nor "debug" in there
849 bool debug = qmakeBuildConfig & QtVersion::DebugBuild;
850 bool haveTag = !(qmakeBuildConfig & QtVersion::BuildAll);
851 QString makeCmdArguments = makeStep()->userArguments();
852 Utils::QtcProcess::ArgIterator ait(&makeCmdArguments);
854 if (ait.value() == QLatin1String("debug")) {
855 if (!haveTag && debug)
859 } else if (ait.value() == QLatin1String("release")) {
860 if (!haveTag && !debug)
867 ait.appendArg(QLatin1String(debug ? "debug" : "release"));
868 makeStep()->setUserArguments(makeCmdArguments);