1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
10 ** GNU Lesser General Public License Usage
12 ** This file may be used under the terms of the GNU Lesser General Public
13 ** License version 2.1 as published by the Free Software Foundation and
14 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
15 ** Please review the following information to ensure the GNU Lesser General
16 ** Public License version 2.1 requirements will be met:
17 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
19 ** In addition, as a special exception, Nokia gives you certain additional
20 ** rights. These rights are described in the Nokia Qt LGPL Exception
21 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
25 ** Alternatively, this file may be used in accordance with the terms and
26 ** conditions contained in a signed written agreement between you and Nokia.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at info@qt.nokia.com.
31 **************************************************************************/
33 #include "qt4buildconfiguration.h"
35 #include "qt4project.h"
36 #include "qt4target.h"
37 #include "qt4projectmanagerconstants.h"
39 #include "qmakestep.h"
41 #include "qt4basetargetfactory.h"
43 #include <utils/qtcassert.h>
44 #include <utils/qtcprocess.h>
46 #include <projectexplorer/buildsteplist.h>
47 #include <projectexplorer/projectexplorerconstants.h>
48 #include <projectexplorer/toolchain.h>
49 #include <projectexplorer/toolchainmanager.h>
50 #include <qtsupport/qtversionfactory.h>
51 #include <qtsupport/baseqtversion.h>
52 #include <qtsupport/qtversionmanager.h>
53 #include <QtCore/QDebug>
55 #include <QtGui/QInputDialog>
57 using namespace Qt4ProjectManager;
58 using namespace Qt4ProjectManager::Internal;
59 using namespace ProjectExplorer;
62 const char * const QT4_BC_ID_PREFIX("Qt4ProjectManager.Qt4BuildConfiguration.");
63 const char * const QT4_BC_ID("Qt4ProjectManager.Qt4BuildConfiguration");
65 const char * const USE_SHADOW_BUILD_KEY("Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild");
66 const char * const BUILD_DIRECTORY_KEY("Qt4ProjectManager.Qt4BuildConfiguration.BuildDirectory");
67 const char * const BUILD_CONFIGURATION_KEY("Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration");
68 const char * const QT_VERSION_ID_KEY("Qt4ProjectManager.Qt4BuildConfiguration.QtVersionId");
73 Qt4BuildConfiguration::Qt4BuildConfiguration(Qt4BaseTarget *target) :
74 BuildConfiguration(target, QLatin1String(QT4_BC_ID)),
78 m_qmakeBuildConfiguration(0),
84 Qt4BuildConfiguration::Qt4BuildConfiguration(Qt4BaseTarget *target, const QString &id) :
85 BuildConfiguration(target, id),
89 m_qmakeBuildConfiguration(0),
95 Qt4BuildConfiguration::Qt4BuildConfiguration(Qt4BaseTarget *target, Qt4BuildConfiguration *source) :
96 BuildConfiguration(target, source),
97 m_shadowBuild(source->m_shadowBuild),
99 m_buildDirectory(source->m_buildDirectory),
100 m_qtVersionId(source->m_qtVersionId),
101 m_qmakeBuildConfiguration(source->m_qmakeBuildConfiguration),
102 m_subNodeBuild(0) // temporary value, so not copied
108 Qt4BuildConfiguration::~Qt4BuildConfiguration()
112 QVariantMap Qt4BuildConfiguration::toMap() const
114 QVariantMap map(BuildConfiguration::toMap());
115 map.insert(QLatin1String(USE_SHADOW_BUILD_KEY), m_shadowBuild);
116 map.insert(QLatin1String(BUILD_DIRECTORY_KEY), m_buildDirectory);
117 map.insert(QLatin1String(QT_VERSION_ID_KEY), m_qtVersionId);
118 map.insert(QLatin1String(BUILD_CONFIGURATION_KEY), int(m_qmakeBuildConfiguration));
122 static inline QString msgBuildConfigNotApplicable(const QString &d, const QtSupport::BaseQtVersion *qtVersion,
123 const Target *target)
125 return QString::fromLatin1("Warning: Buildconfiguration '%1' : Qt '%2' from %3 not supported by target '%4'").
126 arg(d, qtVersion->displayName(), qtVersion->qmakeCommand(), target->id());
129 bool Qt4BuildConfiguration::fromMap(const QVariantMap &map)
131 if (!BuildConfiguration::fromMap(map))
134 m_shadowBuild = map.value(QLatin1String(USE_SHADOW_BUILD_KEY), true).toBool();
135 m_qtVersionId = map.value(QLatin1String(QT_VERSION_ID_KEY)).toInt();
136 ProjectExplorer::ToolChain *tc = toolChain();
137 m_qmakeBuildConfiguration = QtSupport::BaseQtVersion::QmakeBuildConfigs(map.value(QLatin1String(BUILD_CONFIGURATION_KEY)).toInt());
138 m_buildDirectory = map.value(QLatin1String(BUILD_DIRECTORY_KEY), defaultShadowBuildDirectory()).toString();
140 // Pick a Qt version if the default version is used:
141 // We assume that the default Qt version was used in earlier versions of Qt creator.
142 // Pick a Qt version that supports this target (usually desktop)
143 if (m_qtVersionId == 0) {
144 QList<QtSupport::BaseQtVersion *> versions = QtSupport::QtVersionManager::instance()->versionsForTargetId(target()->id());
145 foreach (QtSupport::BaseQtVersion *v, versions) {
147 m_qtVersionId = v->uniqueId();
151 if (m_qtVersionId == 0)
155 QtSupport::BaseQtVersion *version = QtSupport::QtVersionManager::instance()->version(m_qtVersionId);
156 if (!version || !version->supportsTargetId(target()->id())) {
161 m_lastEmmitedBuildDirectory = buildDirectory();
163 if (version && version->isValid()) {
164 if (tc && !qt4Target()->possibleToolChains(this).contains(tc))
167 setToolChain(qt4Target()->preferredToolChain(this));
168 m_shadowBuild = (m_shadowBuild && version->supportsShadowBuilds());
172 if (version && version->isValid()) {
173 qWarning("Warning: No tool chain available for '%s' from %s used in '%s'.",
174 qPrintable(version->displayName()), qPrintable(version->qmakeCommand()),
175 qPrintable(target()->id()));
177 qWarning("Warning: No tool chain available for invalid Qt version used in '%s'.",
178 qPrintable(target()->id()));
185 void Qt4BuildConfiguration::ctor()
187 connect(this, SIGNAL(environmentChanged()),
188 this, SLOT(emitBuildDirectoryChanged()));
189 connect(this, SIGNAL(environmentChanged()),
190 this, SLOT(emitProFileEvaluateNeeded()));
192 QtSupport::QtVersionManager *vm = QtSupport::QtVersionManager::instance();
193 connect(vm, SIGNAL(qtVersionsChanged(QList<int>)),
194 this, SLOT(qtVersionsChanged(QList<int>)));
197 void Qt4BuildConfiguration::emitBuildDirectoryChanged()
199 if (buildDirectory() != m_lastEmmitedBuildDirectory) {
200 m_lastEmmitedBuildDirectory = buildDirectory();
201 emit buildDirectoryChanged();
205 Qt4BaseTarget *Qt4BuildConfiguration::qt4Target() const
207 return static_cast<Qt4BaseTarget *>(target());
210 Utils::Environment Qt4BuildConfiguration::baseEnvironment() const
212 Utils::Environment env = BuildConfiguration::baseEnvironment();
214 qtVersion()->addToEnvironment(env);
216 ToolChain *tc = toolChain();
218 tc->addToEnvironment(env);
222 QString Qt4BuildConfiguration::defaultShadowBuildDirectory() const
224 Qt4BaseTargetFactory *factory = Qt4BaseTargetFactory::qt4BaseTargetFactoryForId(qt4Target()->id());
225 // todo displayName isn't ideal
226 return factory->shadowBuildDirectory(qt4Target()->qt4Project()->file()->fileName(), qt4Target()->id(), displayName());
229 /// returns the unexpanded build directory
230 QString Qt4BuildConfiguration::rawBuildDirectory() const
232 QString workingDirectory;
234 if (!m_buildDirectory.isEmpty())
235 workingDirectory = m_buildDirectory;
237 workingDirectory = defaultShadowBuildDirectory();
239 if (workingDirectory.isEmpty())
240 workingDirectory = target()->project()->projectDirectory();
241 return workingDirectory;
244 /// returns the build directory
245 QString Qt4BuildConfiguration::buildDirectory() const
247 return QDir::cleanPath(environment().expandVariables(rawBuildDirectory()));
250 /// If only a sub tree should be build this function returns which sub node
252 /// \see Qt4BuildConfiguration::setSubNodeBuild
253 Qt4ProjectManager::Qt4ProFileNode *Qt4BuildConfiguration::subNodeBuild() const
255 return m_subNodeBuild;
258 /// A sub node build on builds a sub node of the project
259 /// That is triggered by a right click in the project explorer tree
260 /// The sub node to be build is set via this function immediately before
261 /// calling BuildManager::buildProject( BuildConfiguration * )
262 /// and reset immediately afterwards
263 /// That is m_subNodesBuild is set only temporarly
264 void Qt4BuildConfiguration::setSubNodeBuild(Qt4ProjectManager::Qt4ProFileNode *node)
266 m_subNodeBuild = node;
269 /// returns whether this is a shadow build configuration or not
270 /// note, even if shadowBuild() returns true, it might be using the
271 /// source directory as the shadow build directory, thus it
272 /// still is a in-source build
273 bool Qt4BuildConfiguration::shadowBuild() const
275 return m_shadowBuild;
278 /// returns the shadow build directory if set
279 /// \note buildDirectory() is probably the function you want to call
280 QString Qt4BuildConfiguration::shadowBuildDirectory() const
282 if (m_buildDirectory.isEmpty())
283 return defaultShadowBuildDirectory();
284 return m_buildDirectory;
287 void Qt4BuildConfiguration::setShadowBuildAndDirectory(bool shadowBuild, const QString &buildDirectory)
289 QtSupport::BaseQtVersion *version = qtVersion();
290 QString directoryToSet = buildDirectory;
291 bool toSet = (shadowBuild && version && version->isValid() && version->supportsShadowBuilds());
292 if (m_shadowBuild == toSet && m_buildDirectory == directoryToSet)
295 m_shadowBuild = toSet;
296 m_buildDirectory = directoryToSet;
298 emit environmentChanged();
299 emitBuildDirectoryChanged();
300 emit proFileEvaluateNeeded(this);
303 QString Qt4BuildConfiguration::makeCommand() const
305 ToolChain *tc = toolChain();
306 return tc ? tc->makeCommand() : "make";
309 static inline QString symbianMakeTarget(QtSupport::BaseQtVersion::QmakeBuildConfigs buildConfig,
312 QString rc = (buildConfig & QtSupport::BaseQtVersion::DebugBuild) ?
313 QLatin1String("debug-") : QLatin1String("release-");
318 QString Qt4BuildConfiguration::defaultMakeTarget() const
320 ToolChain *tc = toolChain();
321 if (!tc || target()->id() != Constants::S60_DEVICE_TARGET_ID)
323 const QtSupport::BaseQtVersion::QmakeBuildConfigs buildConfig = qmakeBuildConfiguration();
325 return symbianMakeTarget(buildConfig, tc->defaultMakeTarget());
328 QString Qt4BuildConfiguration::makefile() const
330 return qt4Target()->qt4Project()->rootQt4ProjectNode()->makefile();
333 QtSupport::BaseQtVersion *Qt4BuildConfiguration::qtVersion() const
335 QtSupport::QtVersionManager *vm = QtSupport::QtVersionManager::instance();
336 return vm->version(m_qtVersionId);
339 void Qt4BuildConfiguration::setQtVersion(QtSupport::BaseQtVersion *version)
343 m_shadowBuild = false;
345 emit proFileEvaluateNeeded(this);
346 emit qtVersionChanged();
347 emit environmentChanged();
348 emitBuildDirectoryChanged();
351 if (m_qtVersionId == version->uniqueId())
354 m_qtVersionId = version->uniqueId();
356 if (!qt4Target()->possibleToolChains(this).contains(toolChain()))
357 setToolChain(qt4Target()->preferredToolChain(this));
358 m_shadowBuild = m_shadowBuild && qtVersion()->supportsShadowBuilds();
360 emit proFileEvaluateNeeded(this);
361 emit qtVersionChanged();
362 emit environmentChanged();
363 emitBuildDirectoryChanged();
366 void Qt4BuildConfiguration::setToolChain(ProjectExplorer::ToolChain *tc)
368 if (tc != 0 && !qt4Target()->possibleToolChains(this).contains(tc))
371 BuildConfiguration::setToolChain(tc);
373 emit proFileEvaluateNeeded(this);
374 emitBuildDirectoryChanged();
377 QtSupport::BaseQtVersion::QmakeBuildConfigs Qt4BuildConfiguration::qmakeBuildConfiguration() const
379 return m_qmakeBuildConfiguration;
382 void Qt4BuildConfiguration::setQMakeBuildConfiguration(QtSupport::BaseQtVersion::QmakeBuildConfigs config)
384 if (m_qmakeBuildConfiguration == config)
386 m_qmakeBuildConfiguration = config;
388 emit proFileEvaluateNeeded(this);
389 emit qmakeBuildConfigurationChanged();
390 emitBuildDirectoryChanged();
393 void Qt4BuildConfiguration::emitProFileEvaluateNeeded()
395 emit proFileEvaluateNeeded(this);
398 void Qt4BuildConfiguration::emitQMakeBuildConfigurationChanged()
400 emit qmakeBuildConfigurationChanged();
403 void Qt4BuildConfiguration::emitBuildDirectoryInitialized()
405 emit buildDirectoryInitialized();
408 void Qt4BuildConfiguration::emitS60CreatesSmartInstallerChanged()
410 emit s60CreatesSmartInstallerChanged();
414 QStringList Qt4BuildConfiguration::configCommandLineArguments() const
417 QtSupport::BaseQtVersion::QmakeBuildConfigs defaultBuildConfiguration = qtVersion() ? qtVersion()->defaultBuildConfig() : (QtSupport::BaseQtVersion::DebugBuild | QtSupport::BaseQtVersion::BuildAll);
418 QtSupport::BaseQtVersion::QmakeBuildConfigs userBuildConfiguration = m_qmakeBuildConfiguration;
419 if ((defaultBuildConfiguration & QtSupport::BaseQtVersion::BuildAll) && !(userBuildConfiguration & QtSupport::BaseQtVersion::BuildAll))
420 result << "CONFIG-=debug_and_release";
422 if (!(defaultBuildConfiguration & QtSupport::BaseQtVersion::BuildAll) && (userBuildConfiguration & QtSupport::BaseQtVersion::BuildAll))
423 result << "CONFIG+=debug_and_release";
424 if ((defaultBuildConfiguration & QtSupport::BaseQtVersion::DebugBuild) && !(userBuildConfiguration & QtSupport::BaseQtVersion::DebugBuild))
425 result << "CONFIG+=release";
426 if (!(defaultBuildConfiguration & QtSupport::BaseQtVersion::DebugBuild) && (userBuildConfiguration & QtSupport::BaseQtVersion::DebugBuild))
427 result << "CONFIG+=debug";
431 QMakeStep *Qt4BuildConfiguration::qmakeStep() const
434 BuildStepList *bsl = stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
436 for (int i = 0; i < bsl->count(); ++i)
437 if ((qs = qobject_cast<QMakeStep *>(bsl->at(i))) != 0)
442 MakeStep *Qt4BuildConfiguration::makeStep() const
445 BuildStepList *bsl = stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
447 for (int i = 0; i < bsl->count(); ++i)
448 if ((ms = qobject_cast<MakeStep *>(bsl->at(i))) != 0)
453 void Qt4BuildConfiguration::qtVersionsChanged(const QList<int> &changedVersions)
455 if (!changedVersions.contains(m_qtVersionId))
457 emit environmentChanged(); // Our qt version changed, that might have changed the environment
460 // returns true if both are equal
461 bool Qt4BuildConfiguration::compareToImportFrom(const QString &makefile)
463 QMakeStep *qs = qmakeStep();
464 if (QFileInfo(makefile).exists() && qs) {
465 QString qmakePath = QtSupport::QtVersionManager::findQMakeBinaryFromMakefile(makefile);
466 QtSupport::BaseQtVersion *version = qtVersion();
469 if (version->qmakeCommand() == qmakePath) {
471 QPair<QtSupport::BaseQtVersion::QmakeBuildConfigs, QString> result =
472 QtSupport::QtVersionManager::scanMakeFile(makefile, version->defaultBuildConfig());
473 if (qmakeBuildConfiguration() == result.first) {
474 // The qmake Build Configuration are the same,
475 // now compare arguments lists
476 // we have to compare without the spec/platform cmd argument
477 // and compare that on its own
478 QString workingDirectory = QFileInfo(makefile).absolutePath();
479 QStringList actualArgs;
480 QString userArgs = qs->userArguments();
481 // This copies the settings from userArgs to actualArgs (minus some we
482 // are not interested in), splitting them up into individual strings:
483 extractSpecFromArguments(&userArgs, workingDirectory, version, &actualArgs),
484 actualArgs += qs->moreArguments();
485 QString actualSpec = qs->mkspec();
487 QString qmakeArgs = result.second;
488 QStringList parsedArgs;
489 QString parsedSpec = extractSpecFromArguments(&qmakeArgs, workingDirectory, version, &parsedArgs);
492 qDebug()<<"Actual args:"<<actualArgs;
493 qDebug()<<"Parsed args:"<<parsedArgs;
494 qDebug()<<"Actual spec:"<<actualSpec;
495 qDebug()<<"Parsed spec:"<<parsedSpec;
498 // Comparing the sorted list is obviously wrong
499 // Though haven written a more complete version
500 // that managed had around 200 lines and yet faild
501 // to be actually foolproof at all, I think it's
502 // not feasible without actually taking the qmake
503 // command line parsing code
505 // Things, sorting gets wrong:
506 // parameters to positional parameters matter
507 // e.g. -o -spec is different from -spec -o
508 // -o 1 -spec 2 is diffrent from -spec 1 -o 2
509 // variable assignment order matters
510 // variable assignment vs -after
511 // -norecursive vs. recursive
514 if (actualArgs == parsedArgs) {
515 // Specs match exactly
516 if (actualSpec == parsedSpec)
518 // Actual spec is the default one
519 // qDebug()<<"AS vs VS"<<actualSpec<<version->mkspec();
520 if ((actualSpec == version->mkspec() || actualSpec == "default")
521 && (parsedSpec == version->mkspec() || parsedSpec == "default" || parsedSpec.isEmpty()))
525 qDebug()<<"different qmake buildconfigurations buildconfiguration:"<<qmakeBuildConfiguration()<<" Makefile:"<<result.first;
528 qDebug()<<"diffrent qt versions, buildconfiguration:"<<version->qmakeCommand()<<" Makefile:"<<qmakePath;
534 bool Qt4BuildConfiguration::removeQMLInspectorFromArguments(QString *args)
536 bool removedArgument = false;
537 for (Utils::QtcProcess::ArgIterator ait(args); ait.next(); ) {
538 const QString arg = ait.value();
539 if (arg.contains(QLatin1String(Constants::QMAKEVAR_QMLJSDEBUGGER_PATH))
540 || arg.contains(Constants::QMAKEVAR_DECLARATIVE_DEBUG)) {
541 removedArgument = true;
544 return removedArgument;
547 QString Qt4BuildConfiguration::extractSpecFromArguments(QString *args,
548 const QString &directory, const QtSupport::BaseQtVersion *version,
549 QStringList *outArgs)
553 bool ignoreNext = false;
554 bool nextIsSpec = false;
555 for (Utils::QtcProcess::ArgIterator ait(args); ait.next(); ) {
559 } else if (nextIsSpec) {
561 parsedSpec = QDir::cleanPath(ait.value());
563 } else if (ait.value() == QLatin1String("-spec") || ait.value() == QLatin1String("-platform")) {
566 } else if (ait.value() == QLatin1String("-cache")) {
567 // We ignore -cache, because qmake contained a bug that it didn't
568 // mention the -cache in the Makefile.
569 // That means changing the -cache option in the additional arguments
570 // does not automatically rerun qmake. Alas, we could try more
571 // intelligent matching for -cache, but i guess people rarely
575 } else if (outArgs && ait.isSimple()) {
576 outArgs->append(ait.value());
580 if (parsedSpec.isEmpty())
583 QString baseMkspecDir = version->versionInfo().value("QMAKE_MKSPECS");
584 if (baseMkspecDir.isEmpty())
585 baseMkspecDir = version->versionInfo().value("QT_INSTALL_DATA") + "/mkspecs";
588 baseMkspecDir = baseMkspecDir.toLower();
589 parsedSpec = parsedSpec.toLower();
591 // if the path is relative it can be
592 // relative to the working directory (as found in the Makefiles)
593 // or relatively to the mkspec directory
594 // if it is the former we need to get the canonical form
595 // for the other one we don't need to do anything
596 if (QFileInfo(parsedSpec).isRelative()) {
597 if(QFileInfo(directory + QLatin1Char('/') + parsedSpec).exists()) {
598 parsedSpec = QDir::cleanPath(directory + QLatin1Char('/') + parsedSpec);
600 parsedSpec = parsedSpec.toLower();
603 parsedSpec = baseMkspecDir + QLatin1Char('/') + parsedSpec;
607 QFileInfo f2(parsedSpec);
608 while (f2.isSymLink()) {
609 parsedSpec = f2.symLinkTarget();
610 f2.setFile(parsedSpec);
613 if (parsedSpec.startsWith(baseMkspecDir)) {
614 parsedSpec = parsedSpec.mid(baseMkspecDir.length() + 1);
616 QString sourceMkSpecPath = version->sourcePath() + "/mkspecs";
617 if (parsedSpec.startsWith(sourceMkSpecPath)) {
618 parsedSpec = parsedSpec.mid(sourceMkSpecPath.length() + 1);
622 parsedSpec = parsedSpec.toLower();
627 ProjectExplorer::IOutputParser *Qt4BuildConfiguration::createOutputParser() const
629 ToolChain *tc = toolChain();
631 return toolChain()->outputParser();
635 bool Qt4BuildConfiguration::isEnabled() const
640 QString Qt4BuildConfiguration::disabledReason() const
643 return tr("Parsing the .pro file");
647 void Qt4BuildConfiguration::setEnabled(bool enabled)
649 if (m_isEnabled == enabled)
651 m_isEnabled = enabled;
652 emit enabledChanged();
656 \class Qt4BuildConfigurationFactory
659 Qt4BuildConfigurationFactory::Qt4BuildConfigurationFactory(QObject *parent) :
660 ProjectExplorer::IBuildConfigurationFactory(parent)
664 QtSupport::QtVersionManager *vm = QtSupport::QtVersionManager::instance();
665 connect(vm, SIGNAL(qtVersionsChanged(QList<int>)),
666 this, SLOT(update()));
669 Qt4BuildConfigurationFactory::~Qt4BuildConfigurationFactory()
673 void Qt4BuildConfigurationFactory::update()
676 QtSupport::QtVersionManager *vm = QtSupport::QtVersionManager::instance();
677 foreach (QtSupport::BaseQtVersion *version, vm->validVersions()) {
678 QString key = QString::fromLatin1(QT4_BC_ID_PREFIX)
679 + QString::fromLatin1("Qt%1").arg(version->uniqueId());
680 VersionInfo info(tr("Using Qt Version \"%1\"").arg(version->displayName()), version->uniqueId());
681 m_versions.insert(key, info);
683 emit availableCreationIdsChanged();
686 QStringList Qt4BuildConfigurationFactory::availableCreationIds(ProjectExplorer::Target *parent) const
688 if (!qobject_cast<Qt4BaseTarget *>(parent))
689 return QStringList();
692 QtSupport::QtVersionManager *vm = QtSupport::QtVersionManager::instance();
693 for (QMap<QString, VersionInfo>::const_iterator i = m_versions.constBegin();
694 i != m_versions.constEnd(); ++i) {
695 if (vm->version(i.value().versionId)->supportsTargetId(parent->id())
696 && vm->version(i.value().versionId)->toolChainAvailable(parent->id()))
697 results.append(i.key());
702 QString Qt4BuildConfigurationFactory::displayNameForId(const QString &id) const
704 if (!m_versions.contains(id))
706 return m_versions.value(id).displayName;
709 bool Qt4BuildConfigurationFactory::canCreate(ProjectExplorer::Target *parent, const QString &id) const
711 if (!qobject_cast<Qt4BaseTarget *>(parent))
713 if (!m_versions.contains(id))
715 const VersionInfo &info = m_versions.value(id);
716 QtSupport::BaseQtVersion *version = QtSupport::QtVersionManager::instance()->version(info.versionId);
718 !version->supportsTargetId(parent->id()))
723 BuildConfiguration *Qt4BuildConfigurationFactory::create(ProjectExplorer::Target *parent, const QString &id)
725 if (!canCreate(parent, id))
728 const VersionInfo &info = m_versions.value(id);
729 QtSupport::BaseQtVersion *version = QtSupport::QtVersionManager::instance()->version(info.versionId);
732 Qt4BaseTarget *qt4Target = static_cast<Qt4BaseTarget *>(parent);
735 QString buildConfigurationName = QInputDialog::getText(0,
736 tr("New Configuration"),
737 tr("New configuration name:"),
739 version->displayName(),
741 buildConfigurationName = buildConfigurationName.trimmed();
742 if (!ok || buildConfigurationName.isEmpty())
745 //: Debug build configuration. We recommend not translating it.
746 QString defaultDebugName = tr("%1 Debug").arg(version->displayName());
747 QString customDebugName;
748 if (buildConfigurationName != version->displayName())
749 customDebugName = tr("%1 Debug").arg(buildConfigurationName);
751 BuildConfiguration *bc = qt4Target->addQt4BuildConfiguration(defaultDebugName, customDebugName,
753 (version->defaultBuildConfig() | QtSupport::BaseQtVersion::DebugBuild),
754 QString(), QString(), false);
756 if (qt4Target->id() != Constants::S60_EMULATOR_TARGET_ID) {
757 //: Release build configuration. We recommend not translating it.
758 QString defaultReleaseName = tr("%1 Release").arg(version->displayName());
759 QString customReleaseName;
760 if (buildConfigurationName != version->displayName())
761 customReleaseName = tr("%1 Release").arg(buildConfigurationName);
763 bc = qt4Target->addQt4BuildConfiguration(defaultReleaseName, customReleaseName,
765 (version->defaultBuildConfig() & ~QtSupport::BaseQtVersion::DebugBuild),
766 QString(), QString(), false);
771 bool Qt4BuildConfigurationFactory::canClone(ProjectExplorer::Target *parent, ProjectExplorer::BuildConfiguration *source) const
773 if (!qobject_cast<Qt4BaseTarget *>(parent))
775 Qt4BuildConfiguration *qt4bc(qobject_cast<Qt4BuildConfiguration *>(source));
779 QtSupport::BaseQtVersion *version = qt4bc->qtVersion();
781 !version->supportsTargetId(parent->id()))
786 BuildConfiguration *Qt4BuildConfigurationFactory::clone(Target *parent, BuildConfiguration *source)
788 if (!canClone(parent, source))
790 Qt4BaseTarget *target = static_cast<Qt4BaseTarget *>(parent);
791 Qt4BuildConfiguration *oldbc(static_cast<Qt4BuildConfiguration *>(source));
792 return new Qt4BuildConfiguration(target, oldbc);
795 bool Qt4BuildConfigurationFactory::canRestore(Target *parent, const QVariantMap &map) const
797 QString id = ProjectExplorer::idFromMap(map);
798 if (!qobject_cast<Qt4BaseTarget *>(parent))
800 return id.startsWith(QLatin1String(QT4_BC_ID_PREFIX)) ||
801 id == QLatin1String(QT4_BC_ID);
804 BuildConfiguration *Qt4BuildConfigurationFactory::restore(Target *parent, const QVariantMap &map)
806 if (!canRestore(parent, map))
808 Qt4BaseTarget *target = static_cast<Qt4BaseTarget *>(parent);
809 Qt4BuildConfiguration *bc = new Qt4BuildConfiguration(target);
810 if (bc->fromMap(map))
816 void Qt4BuildConfiguration::importFromBuildDirectory()
818 QString directory = buildDirectory();
819 if (!directory.isEmpty()) {
820 QString mkfile = directory;
821 if (makefile().isEmpty())
822 mkfile.append("/Makefile");
824 mkfile.append(makefile());
826 QString qmakePath = QtSupport::QtVersionManager::findQMakeBinaryFromMakefile(mkfile);
827 if (!qmakePath.isEmpty()) {
828 QtSupport::QtVersionManager *vm = QtSupport::QtVersionManager::instance();
829 QtSupport::BaseQtVersion *version = vm->qtVersionForQMakeBinary(qmakePath);
831 version = QtSupport::QtVersionFactory::createQtVersionFromQMakePath(qmakePath);
832 vm->addVersion(version);
835 QPair<QtSupport::BaseQtVersion::QmakeBuildConfigs, QString> result =
836 QtSupport::QtVersionManager::scanMakeFile(mkfile, version->defaultBuildConfig());
837 QtSupport::BaseQtVersion::QmakeBuildConfigs qmakeBuildConfig = result.first;
839 QString additionalArguments = result.second;
840 QString parsedSpec = Qt4BuildConfiguration::extractSpecFromArguments(&additionalArguments, directory, version);
841 const bool enableQmlDebugger =
842 Qt4BuildConfiguration::removeQMLInspectorFromArguments(&additionalArguments);
844 // So we got all the information now apply it...
845 setQtVersion(version);
847 QMakeStep *qs = qmakeStep();
848 qs->setUserArguments(additionalArguments);
849 qs->setLinkQmlDebuggingLibrary(enableQmlDebugger);
850 if (!parsedSpec.isEmpty() && parsedSpec != QLatin1String("default") && qs->mkspec() != parsedSpec) {
851 Utils::QtcProcess::addArgs(&additionalArguments, (QStringList() << "-spec" << parsedSpec));
852 qs->setUserArguments(additionalArguments);
855 setQMakeBuildConfiguration(qmakeBuildConfig);
856 // Adjust command line arguments, this is ugly as hell
857 // If we are switching to BuildAll we want "release" in there and no "debug"
858 // or "debug" in there and no "release"
859 // If we are switching to not BuildAll we want neither "release" nor "debug" in there
860 bool debug = qmakeBuildConfig & QtSupport::BaseQtVersion::DebugBuild;
861 bool haveTag = !(qmakeBuildConfig & QtSupport::BaseQtVersion::BuildAll);
862 QString makeCmdArguments = makeStep()->userArguments();
863 Utils::QtcProcess::ArgIterator ait(&makeCmdArguments);
865 if (ait.value() == QLatin1String("debug")) {
866 if (!haveTag && debug)
870 } else if (ait.value() == QLatin1String("release")) {
871 if (!haveTag && !debug)
878 ait.appendArg(QLatin1String(debug ? "debug" : "release"));
879 makeStep()->setUserArguments(makeCmdArguments);
884 BuildConfiguration::BuildType Qt4BuildConfiguration::buildType() const
886 if (qmakeBuildConfiguration() & QtSupport::BaseQtVersion::DebugBuild)