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 qt-info@nokia.com.
31 **************************************************************************/
33 #include "qt4buildconfiguration.h"
35 #include "qt4project.h"
36 #include "qt4target.h"
37 #include "qt4projectmanagerconstants.h"
39 #include "qmakestep.h"
42 #include <utils/qtcassert.h>
43 #include <utils/qtcprocess.h>
45 #include <projectexplorer/buildsteplist.h>
46 #include <projectexplorer/projectexplorerconstants.h>
47 #include <projectexplorer/toolchainmanager.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 BUILD_CONFIGURATION_KEY("Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration");
64 const char * const QT_VERSION_ID_KEY("Qt4ProjectManager.Qt4BuildConfiguration.QtVersionId");
69 Qt4BuildConfiguration::Qt4BuildConfiguration(Qt4BaseTarget *target) :
70 BuildConfiguration(target, QLatin1String(QT4_BC_ID)),
74 m_qmakeBuildConfiguration(0),
80 Qt4BuildConfiguration::Qt4BuildConfiguration(Qt4BaseTarget *target, const QString &id) :
81 BuildConfiguration(target, id),
85 m_qmakeBuildConfiguration(0),
91 Qt4BuildConfiguration::Qt4BuildConfiguration(Qt4BaseTarget *target, Qt4BuildConfiguration *source) :
92 BuildConfiguration(target, source),
93 m_shadowBuild(source->m_shadowBuild),
95 m_buildDirectory(source->m_buildDirectory),
96 m_qtVersionId(source->m_qtVersionId),
97 m_qmakeBuildConfiguration(source->m_qmakeBuildConfiguration),
98 m_subNodeBuild(0) // temporary value, so not copied
104 Qt4BuildConfiguration::~Qt4BuildConfiguration()
108 QVariantMap Qt4BuildConfiguration::toMap() const
110 QVariantMap map(BuildConfiguration::toMap());
111 map.insert(QLatin1String(USE_SHADOW_BUILD_KEY), m_shadowBuild);
112 map.insert(QLatin1String(BUILD_DIRECTORY_KEY), m_buildDirectory);
113 map.insert(QLatin1String(QT_VERSION_ID_KEY), m_qtVersionId);
114 map.insert(QLatin1String(BUILD_CONFIGURATION_KEY), int(m_qmakeBuildConfiguration));
118 static inline QString msgBuildConfigNotApplicable(const QString &d, const QtVersion *qtVersion,
119 const Target *target)
121 return QString::fromLatin1("Warning: Buildconfiguration '%1' : Qt '%2' from %3 not supported by target '%4'").
122 arg(d, qtVersion->displayName(), qtVersion->qmakeCommand(), target->id());
125 #include "qt4basetargetfactory.h"
127 bool Qt4BuildConfiguration::fromMap(const QVariantMap &map)
129 if (!BuildConfiguration::fromMap(map))
132 m_shadowBuild = map.value(QLatin1String(USE_SHADOW_BUILD_KEY), true).toBool();
133 m_qtVersionId = map.value(QLatin1String(QT_VERSION_ID_KEY)).toInt();
134 ProjectExplorer::ToolChain *tc = toolChain();
135 m_qmakeBuildConfiguration = QtVersion::QmakeBuildConfigs(map.value(QLatin1String(BUILD_CONFIGURATION_KEY)).toInt());
136 m_buildDirectory = map.value(QLatin1String(BUILD_DIRECTORY_KEY), defaultShadowBuildDirectory()).toString();
138 m_lastEmmitedBuildDirectory = buildDirectory();
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 is supporting a desktop.
143 if (m_qtVersionId == 0) {
144 QList<QtVersion *> versions = QtVersionManager::instance()->versions();
145 foreach (QtVersion *v, versions) {
146 if (v->isValid() && v->supportsTargetId(QLatin1String(Constants::DESKTOP_TARGET_ID))) {
147 m_qtVersionId = v->uniqueId();
151 if (m_qtVersionId == 0)
152 m_qtVersionId = versions.at(0)->uniqueId();
155 QtVersion *version = qtVersion();
156 if (!map.contains(QLatin1String("Qt4ProjectManager.Qt4BuildConfiguration.NeedsV0Update"))) { // we are not upgrading from pre-targets!
157 if (version->isValid() && !version->supportedTargetIds().contains(target()->id())) {
158 qWarning("%s", qPrintable(msgBuildConfigNotApplicable(displayName(), version, target())));
162 if (!version->isValid() || !version->supportedTargetIds().contains(target()->id())) {
163 qWarning("%s", qPrintable(msgBuildConfigNotApplicable(displayName(), version, target())));
168 if (version->isValid()) {
170 tc = qt4Target()->preferredToolChain(this);
171 if (tc && qt4Target()->possibleToolChains(this).contains(tc))
173 m_shadowBuild = (m_shadowBuild && version->supportsShadowBuilds());
177 if (version->isValid()) {
178 qWarning("Warning: No tool chain available for '%s' from %s used in '%s'.",
179 qPrintable(version->displayName()), qPrintable(version->qmakeCommand()),
180 qPrintable(target()->id()));
182 qWarning("Warning: No tool chain available for invalid Qt version used in '%s'.",
183 qPrintable(target()->id()));
191 void Qt4BuildConfiguration::ctor()
193 connect(this, SIGNAL(environmentChanged()),
194 this, SLOT(emitBuildDirectoryChanged()));
195 connect(this, SIGNAL(environmentChanged()),
196 this, SLOT(emitProFileEvaluteNeeded()));
198 QtVersionManager *vm = QtVersionManager::instance();
199 connect(vm, SIGNAL(qtVersionsChanged(QList<int>)),
200 this, SLOT(qtVersionsChanged(QList<int>)));
203 void Qt4BuildConfiguration::emitBuildDirectoryChanged()
205 if (buildDirectory() != m_lastEmmitedBuildDirectory) {
206 m_lastEmmitedBuildDirectory = buildDirectory();
207 emit buildDirectoryChanged();
211 void Qt4BuildConfiguration::pickValidQtVersion()
213 QList<QtVersion *> versions = QtVersionManager::instance()->versionsForTargetId(qt4Target()->id());
214 if (!versions.isEmpty())
215 setQtVersion(versions.at(0));
217 setQtVersion(QtVersionManager::instance()->emptyVersion());
220 Qt4BaseTarget *Qt4BuildConfiguration::qt4Target() const
222 return static_cast<Qt4BaseTarget *>(target());
225 Utils::Environment Qt4BuildConfiguration::baseEnvironment() const
227 Utils::Environment env = BuildConfiguration::baseEnvironment();
228 qtVersion()->addToEnvironment(env);
230 ToolChain *tc = toolChain();
232 tc->addToEnvironment(env);
236 QString Qt4BuildConfiguration::defaultShadowBuildDirectory() const
238 Qt4BaseTargetFactory *factory = Qt4BaseTargetFactory::qt4BaseTargetFactoryForId(qt4Target()->id());
239 // todo displayName isn't ideal
240 return factory->shadowBuildDirectory(qt4Target()->qt4Project()->file()->fileName(), qt4Target()->id(), displayName());
243 /// returns the unexpanded build directory
244 QString Qt4BuildConfiguration::rawBuildDirectory() const
246 QString workingDirectory;
248 if (!m_buildDirectory.isEmpty())
249 workingDirectory = m_buildDirectory;
251 workingDirectory = defaultShadowBuildDirectory();
253 if (workingDirectory.isEmpty())
254 workingDirectory = target()->project()->projectDirectory();
255 return workingDirectory;
258 /// returns the build directory
259 QString Qt4BuildConfiguration::buildDirectory() const
261 return QDir::cleanPath(environment().expandVariables(rawBuildDirectory()));
264 /// If only a sub tree should be build this function returns which sub node
266 /// \see Qt4BuildConfiguration::setSubNodeBuild
267 Qt4ProjectManager::Internal::Qt4ProFileNode *Qt4BuildConfiguration::subNodeBuild() const
269 return m_subNodeBuild;
272 /// A sub node build on builds a sub node of the project
273 /// That is triggered by a right click in the project explorer tree
274 /// The sub node to be build is set via this function immediately before
275 /// calling BuildManager::buildProject( BuildConfiguration * )
276 /// and reset immediately afterwards
277 /// That is m_subNodesBuild is set only temporarly
278 void Qt4BuildConfiguration::setSubNodeBuild(Qt4ProjectManager::Internal::Qt4ProFileNode *node)
280 m_subNodeBuild = node;
283 /// returns whether this is a shadow build configuration or not
284 /// note, even if shadowBuild() returns true, it might be using the
285 /// source directory as the shadow build directory, thus it
286 /// still is a in-source build
287 bool Qt4BuildConfiguration::shadowBuild() const
289 return m_shadowBuild;
292 /// returns the shadow build directory if set
293 /// \note buildDirectory() is probably the function you want to call
294 QString Qt4BuildConfiguration::shadowBuildDirectory() const
296 if (m_buildDirectory.isEmpty())
297 return defaultShadowBuildDirectory();
298 return m_buildDirectory;
301 void Qt4BuildConfiguration::setShadowBuildAndDirectory(bool shadowBuild, const QString &buildDirectory)
303 QtVersion *version = qtVersion();
304 QString directoryToSet = buildDirectory;
305 bool toSet = (shadowBuild && version->isValid() && version->supportsShadowBuilds());
306 if (m_shadowBuild == toSet && m_buildDirectory == directoryToSet)
309 m_shadowBuild = toSet;
310 m_buildDirectory = directoryToSet;
312 emit environmentChanged();
313 emitBuildDirectoryChanged();
314 emit proFileEvaluateNeeded(this);
317 QString Qt4BuildConfiguration::makeCommand() const
319 ToolChain *tc = toolChain();
320 return tc ? tc->makeCommand() : "make";
323 static inline QString symbianMakeTarget(QtVersion::QmakeBuildConfigs buildConfig,
326 QString rc = (buildConfig & QtVersion::DebugBuild) ?
327 QLatin1String("debug-") : QLatin1String("release-");
332 QString Qt4BuildConfiguration::defaultMakeTarget() const
334 ToolChain *tc = toolChain();
335 if (!tc || target()->id() != Constants::S60_DEVICE_TARGET_ID)
337 const QtVersion::QmakeBuildConfigs buildConfig = qmakeBuildConfiguration();
339 return symbianMakeTarget(buildConfig, tc->defaultMakeTarget());
342 QString Qt4BuildConfiguration::makefile() const
344 return qt4Target()->qt4Project()->rootProjectNode()->makefile();
347 QtVersion *Qt4BuildConfiguration::qtVersion() const
349 QtVersionManager *vm = QtVersionManager::instance();
350 return vm->version(m_qtVersionId);
353 void Qt4BuildConfiguration::setQtVersion(QtVersion *version)
357 if (m_qtVersionId == version->uniqueId())
360 m_qtVersionId = version->uniqueId();
362 if (!qt4Target()->possibleToolChains(this).contains(toolChain()))
363 setToolChain(qt4Target()->preferredToolChain(this));
364 m_shadowBuild = m_shadowBuild && qtVersion()->supportsShadowBuilds();
366 emit proFileEvaluateNeeded(this);
367 emit qtVersionChanged();
368 emit environmentChanged();
369 emitBuildDirectoryChanged();
372 void Qt4BuildConfiguration::setToolChain(ProjectExplorer::ToolChain *tc)
374 Q_ASSERT(qtVersion());
375 if (tc != 0 && !qt4Target()->possibleToolChains(this).contains(tc))
378 BuildConfiguration::setToolChain(tc);
380 emit proFileEvaluateNeeded(this);
381 emit environmentChanged();
382 emitBuildDirectoryChanged();
385 QtVersion::QmakeBuildConfigs Qt4BuildConfiguration::qmakeBuildConfiguration() const
387 return m_qmakeBuildConfiguration;
390 void Qt4BuildConfiguration::setQMakeBuildConfiguration(QtVersion::QmakeBuildConfigs config)
392 if (m_qmakeBuildConfiguration == config)
394 m_qmakeBuildConfiguration = config;
396 emit proFileEvaluateNeeded(this);
397 emit qmakeBuildConfigurationChanged();
398 emitBuildDirectoryChanged();
401 void Qt4BuildConfiguration::emitProFileEvaluteNeeded()
403 emit proFileEvaluateNeeded(this);
406 void Qt4BuildConfiguration::emitQMakeBuildConfigurationChanged()
408 emit qmakeBuildConfigurationChanged();
411 void Qt4BuildConfiguration::emitBuildDirectoryInitialized()
413 emit buildDirectoryInitialized();
416 void Qt4BuildConfiguration::emitS60CreatesSmartInstallerChanged()
418 emit s60CreatesSmartInstallerChanged();
422 QStringList Qt4BuildConfiguration::configCommandLineArguments() const
425 QtVersion::QmakeBuildConfigs defaultBuildConfiguration = qtVersion()->defaultBuildConfig();
426 QtVersion::QmakeBuildConfigs userBuildConfiguration = m_qmakeBuildConfiguration;
427 if ((defaultBuildConfiguration & QtVersion::BuildAll) && !(userBuildConfiguration & QtVersion::BuildAll))
428 result << "CONFIG-=debug_and_release";
430 if (!(defaultBuildConfiguration & QtVersion::BuildAll) && (userBuildConfiguration & QtVersion::BuildAll))
431 result << "CONFIG+=debug_and_release";
432 if ((defaultBuildConfiguration & QtVersion::DebugBuild)
433 && !(userBuildConfiguration & QtVersion::DebugBuild)
434 && !(userBuildConfiguration & QtVersion::BuildAll))
435 result << "CONFIG+=release";
436 if (!(defaultBuildConfiguration & QtVersion::DebugBuild)
437 && (userBuildConfiguration & QtVersion::DebugBuild)
438 && !(userBuildConfiguration & QtVersion::BuildAll))
439 result << "CONFIG+=debug";
443 QMakeStep *Qt4BuildConfiguration::qmakeStep() const
446 BuildStepList *bsl = stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
448 for (int i = 0; i < bsl->count(); ++i)
449 if ((qs = qobject_cast<QMakeStep *>(bsl->at(i))) != 0)
454 MakeStep *Qt4BuildConfiguration::makeStep() const
457 BuildStepList *bsl = stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
459 for (int i = 0; i < bsl->count(); ++i)
460 if ((ms = qobject_cast<MakeStep *>(bsl->at(i))) != 0)
465 void Qt4BuildConfiguration::qtVersionsChanged(const QList<int> &changedVersions)
467 if (!changedVersions.contains(m_qtVersionId))
469 if (!qtVersion()->isValid())
470 pickValidQtVersion();
471 emit environmentChanged(); // Our qt version changed, that might have changed the environment
474 // returns true if both are equal
475 bool Qt4BuildConfiguration::compareToImportFrom(const QString &makefile)
477 QMakeStep *qs = qmakeStep();
478 if (QFileInfo(makefile).exists() && qs) {
479 QString qmakePath = QtVersionManager::findQMakeBinaryFromMakefile(makefile);
480 QtVersion *version = qtVersion();
481 if (version->qmakeCommand() == qmakePath) {
483 QPair<QtVersion::QmakeBuildConfigs, QString> result =
484 QtVersionManager::scanMakeFile(makefile, version->defaultBuildConfig());
485 if (qmakeBuildConfiguration() == result.first) {
486 // The qmake Build Configuration are the same,
487 // now compare arguments lists
488 // we have to compare without the spec/platform cmd argument
489 // and compare that on its own
490 QString workingDirectory = QFileInfo(makefile).absolutePath();
491 QString userArgs = qs->userArguments();
492 QStringList actualArgs;
493 QString actualSpec = extractSpecFromArguments(&userArgs, workingDirectory, version, &actualArgs);
494 if (actualSpec.isEmpty()) {
495 // Easy one: the user has chosen not to override the settings
496 actualSpec = version->mkspec();
498 actualArgs += qs->moreArguments();
500 QString qmakeArgs = result.second;
501 QStringList parsedArgs;
502 QString parsedSpec = extractSpecFromArguments(&qmakeArgs, workingDirectory, version, &parsedArgs);
505 qDebug()<<"Actual args:"<<actualArgs;
506 qDebug()<<"Parsed args:"<<parsedArgs;
507 qDebug()<<"Actual spec:"<<actualSpec;
508 qDebug()<<"Parsed spec:"<<parsedSpec;
511 // Comparing the sorted list is obviously wrong
512 // Though haven written a more complete version
513 // that managed had around 200 lines and yet faild
514 // to be actually foolproof at all, I think it's
515 // not feasible without actually taking the qmake
516 // command line parsing code
518 // Things, sorting gets wrong:
519 // parameters to positional parameters matter
520 // e.g. -o -spec is different from -spec -o
521 // -o 1 -spec 2 is diffrent from -spec 1 -o 2
522 // variable assignment order matters
523 // variable assignment vs -after
524 // -norecursive vs. recursive
527 if (actualArgs == parsedArgs) {
528 // Specs match exactly
529 if (actualSpec == parsedSpec)
531 // Actual spec is the default one
532 // qDebug()<<"AS vs VS"<<actualSpec<<version->mkspec();
533 if ((actualSpec == version->mkspec() || actualSpec == "default")
534 && (parsedSpec == version->mkspec() || parsedSpec == "default" || parsedSpec.isEmpty()))
538 qDebug()<<"different qmake buildconfigurations buildconfiguration:"<<qmakeBuildConfiguration()<<" Makefile:"<<result.first;
541 qDebug()<<"diffrent qt versions, buildconfiguration:"<<version->qmakeCommand()<<" Makefile:"<<qmakePath;
547 void Qt4BuildConfiguration::removeQMLInspectorFromArguments(QString *args)
549 for (Utils::QtcProcess::ArgIterator ait(args); ait.next(); )
550 if (ait.value().contains(QLatin1String(Constants::QMAKEVAR_QMLJSDEBUGGER_PATH)))
554 QString Qt4BuildConfiguration::extractSpecFromArguments(QString *args,
555 const QString &directory, const QtVersion *version,
556 QStringList *outArgs)
560 bool ignoreNext = false;
561 bool nextIsSpec = false;
562 for (Utils::QtcProcess::ArgIterator ait(args); ait.next(); ) {
566 } else if (nextIsSpec) {
568 parsedSpec = QDir::cleanPath(ait.value());
570 } else if (ait.value() == QLatin1String("-spec") || ait.value() == QLatin1String("-platform")) {
573 } else if (ait.value() == QLatin1String("-cache")) {
574 // We ignore -cache, because qmake contained a bug that it didn't
575 // mention the -cache in the Makefile.
576 // That means changing the -cache option in the additional arguments
577 // does not automatically rerun qmake. Alas, we could try more
578 // intelligent matching for -cache, but i guess people rarely
582 } else if (outArgs && ait.isSimple()) {
583 outArgs->append(ait.value());
587 if (parsedSpec.isEmpty())
590 QString baseMkspecDir = version->versionInfo().value("QMAKE_MKSPECS");
591 if (baseMkspecDir.isEmpty())
592 baseMkspecDir = version->versionInfo().value("QT_INSTALL_DATA") + "/mkspecs";
595 baseMkspecDir = baseMkspecDir.toLower();
596 parsedSpec = parsedSpec.toLower();
598 // if the path is relative it can be
599 // relative to the working directory (as found in the Makefiles)
600 // or relatively to the mkspec directory
601 // if it is the former we need to get the canonical form
602 // for the other one we don't need to do anything
603 if (QFileInfo(parsedSpec).isRelative()) {
604 if(QFileInfo(directory + QLatin1Char('/') + parsedSpec).exists()) {
605 parsedSpec = QDir::cleanPath(directory + QLatin1Char('/') + parsedSpec);
607 parsedSpec = parsedSpec.toLower();
610 parsedSpec = baseMkspecDir + QLatin1Char('/') + parsedSpec;
614 QFileInfo f2(parsedSpec);
615 while (f2.isSymLink()) {
616 parsedSpec = f2.symLinkTarget();
617 f2.setFile(parsedSpec);
620 if (parsedSpec.startsWith(baseMkspecDir)) {
621 parsedSpec = parsedSpec.mid(baseMkspecDir.length() + 1);
623 QString sourceMkSpecPath = version->sourcePath() + "/mkspecs";
624 if (parsedSpec.startsWith(sourceMkSpecPath)) {
625 parsedSpec = parsedSpec.mid(sourceMkSpecPath.length() + 1);
629 parsedSpec = parsedSpec.toLower();
634 ProjectExplorer::IOutputParser *Qt4BuildConfiguration::createOutputParser() const
636 ToolChain *tc = toolChain();
638 return toolChain()->outputParser();
642 bool Qt4BuildConfiguration::isEnabled() const
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 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 && vm->version(i.value().versionId)->toolChainAvailable(parent->id()))
699 results.append(i.key());
704 QString Qt4BuildConfigurationFactory::displayNameForId(const QString &id) const
706 if (!m_versions.contains(id))
708 return m_versions.value(id).displayName;
711 bool Qt4BuildConfigurationFactory::canCreate(ProjectExplorer::Target *parent, const QString &id) const
713 if (!qobject_cast<Qt4BaseTarget *>(parent))
715 if (!m_versions.contains(id))
717 const VersionInfo &info = m_versions.value(id);
718 QtVersion *version = QtVersionManager::instance()->version(info.versionId);
720 !version->supportsTargetId(parent->id()))
725 BuildConfiguration *Qt4BuildConfigurationFactory::create(ProjectExplorer::Target *parent, const QString &id)
727 if (!canCreate(parent, id))
730 const VersionInfo &info = m_versions.value(id);
731 QtVersion *version = QtVersionManager::instance()->version(info.versionId);
734 Qt4BaseTarget *qt4Target = static_cast<Qt4BaseTarget *>(parent);
737 QString buildConfigurationName = QInputDialog::getText(0,
738 tr("New Configuration"),
739 tr("New configuration name:"),
741 version->displayName(),
743 buildConfigurationName = buildConfigurationName.trimmed();
744 if (!ok || buildConfigurationName.isEmpty())
747 //: Debug build configuration. We recommend not translating it.
748 BuildConfiguration *bc = qt4Target->addQt4BuildConfiguration(tr("%1 Debug").arg(buildConfigurationName),
750 (version->defaultBuildConfig() | QtVersion::DebugBuild),
751 QString(), QString());
752 if (id != Constants::S60_EMULATOR_TARGET_ID) {
753 //: Release build configuration. We recommend not translating it.
754 bc = qt4Target->addQt4BuildConfiguration(tr("%1 Release").arg(buildConfigurationName),
756 (version->defaultBuildConfig() & ~QtVersion::DebugBuild),
757 QString(), QString());
762 bool Qt4BuildConfigurationFactory::canClone(ProjectExplorer::Target *parent, ProjectExplorer::BuildConfiguration *source) const
764 if (!qobject_cast<Qt4BaseTarget *>(parent))
766 Qt4BuildConfiguration *qt4bc(qobject_cast<Qt4BuildConfiguration *>(source));
770 QtVersion *version = qt4bc->qtVersion();
772 !version->supportsTargetId(parent->id()))
777 BuildConfiguration *Qt4BuildConfigurationFactory::clone(Target *parent, BuildConfiguration *source)
779 if (!canClone(parent, source))
781 Qt4BaseTarget *target = static_cast<Qt4BaseTarget *>(parent);
782 Qt4BuildConfiguration *oldbc(static_cast<Qt4BuildConfiguration *>(source));
783 return new Qt4BuildConfiguration(target, oldbc);
786 bool Qt4BuildConfigurationFactory::canRestore(Target *parent, const QVariantMap &map) const
788 QString id = ProjectExplorer::idFromMap(map);
789 if (!qobject_cast<Qt4BaseTarget *>(parent))
791 return id.startsWith(QLatin1String(QT4_BC_ID_PREFIX)) ||
792 id == QLatin1String(QT4_BC_ID);
795 BuildConfiguration *Qt4BuildConfigurationFactory::restore(Target *parent, const QVariantMap &map)
797 if (!canRestore(parent, map))
799 Qt4BaseTarget *target = static_cast<Qt4BaseTarget *>(parent);
800 Qt4BuildConfiguration *bc = new Qt4BuildConfiguration(target);
801 if (bc->fromMap(map))
807 void Qt4BuildConfiguration::importFromBuildDirectory()
809 QString directory = buildDirectory();
810 if (!directory.isEmpty()) {
811 QString mkfile = directory;
812 if (makefile().isEmpty())
813 mkfile.append("/Makefile");
815 mkfile.append(makefile());
817 QString qmakePath = QtVersionManager::findQMakeBinaryFromMakefile(mkfile);
818 if (!qmakePath.isEmpty()) {
819 QtVersionManager *vm = QtVersionManager::instance();
820 QtVersion *version = vm->qtVersionForQMakeBinary(qmakePath);
822 version = new QtVersion(qmakePath);
823 vm->addVersion(version);
826 QPair<QtVersion::QmakeBuildConfigs, QString> result =
827 QtVersionManager::scanMakeFile(directory, version->defaultBuildConfig());
828 QtVersion::QmakeBuildConfigs qmakeBuildConfig = result.first;
830 QString aa = result.second;
831 QString parsedSpec = Qt4BuildConfiguration::extractSpecFromArguments(&aa, directory, version);
832 QString versionSpec = version->mkspec();
833 QString additionalArguments;
834 if (parsedSpec.isEmpty() || parsedSpec == versionSpec || parsedSpec == "default") {
835 // using the default spec, don't modify additional arguments
837 additionalArguments = "-spec " + Utils::QtcProcess::quoteArg(parsedSpec);
839 Utils::QtcProcess::addArgs(&additionalArguments, aa);
841 Qt4BuildConfiguration::removeQMLInspectorFromArguments(&additionalArguments);
843 // So we got all the information now apply it...
844 setQtVersion(version);
846 qmakeStep()->setUserArguments(additionalArguments);
848 setQMakeBuildConfiguration(qmakeBuildConfig);
849 // Adjust command line arguments, this is ugly as hell
850 // If we are switching to BuildAll we want "release" in there and no "debug"
851 // or "debug" in there and no "release"
852 // If we are switching to not BuildAl we want neither "release" nor "debug" in there
853 bool debug = qmakeBuildConfig & QtVersion::DebugBuild;
854 bool haveTag = !(qmakeBuildConfig & QtVersion::BuildAll);
855 QString makeCmdArguments = makeStep()->userArguments();
856 Utils::QtcProcess::ArgIterator ait(&makeCmdArguments);
858 if (ait.value() == QLatin1String("debug")) {
859 if (!haveTag && debug)
863 } else if (ait.value() == QLatin1String("release")) {
864 if (!haveTag && !debug)
871 ait.appendArg(QLatin1String(debug ? "debug" : "release"));
872 makeStep()->setUserArguments(makeCmdArguments);
877 BuildConfiguration::BuildType Qt4BuildConfiguration::buildType() const
879 if (qmakeBuildConfiguration() & QtVersion::DebugBuild)