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 "qtversionfactory.h"
42 #include "baseqtversion.h"
43 #include "qt4basetargetfactory.h"
45 #include <utils/qtcassert.h>
46 #include <utils/qtcprocess.h>
48 #include <projectexplorer/buildsteplist.h>
49 #include <projectexplorer/projectexplorerconstants.h>
50 #include <projectexplorer/toolchainmanager.h>
52 #include <QtCore/QDebug>
54 #include <QtGui/QInputDialog>
56 using namespace Qt4ProjectManager;
57 using namespace Qt4ProjectManager::Internal;
58 using namespace ProjectExplorer;
61 const char * const QT4_BC_ID_PREFIX("Qt4ProjectManager.Qt4BuildConfiguration.");
62 const char * const QT4_BC_ID("Qt4ProjectManager.Qt4BuildConfiguration");
64 const char * const USE_SHADOW_BUILD_KEY("Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild");
65 const char * const BUILD_DIRECTORY_KEY("Qt4ProjectManager.Qt4BuildConfiguration.BuildDirectory");
66 const char * const BUILD_CONFIGURATION_KEY("Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration");
67 const char * const QT_VERSION_ID_KEY("Qt4ProjectManager.Qt4BuildConfiguration.QtVersionId");
72 Qt4BuildConfiguration::Qt4BuildConfiguration(Qt4BaseTarget *target) :
73 BuildConfiguration(target, QLatin1String(QT4_BC_ID)),
77 m_qmakeBuildConfiguration(0),
83 Qt4BuildConfiguration::Qt4BuildConfiguration(Qt4BaseTarget *target, const QString &id) :
84 BuildConfiguration(target, id),
88 m_qmakeBuildConfiguration(0),
94 Qt4BuildConfiguration::Qt4BuildConfiguration(Qt4BaseTarget *target, Qt4BuildConfiguration *source) :
95 BuildConfiguration(target, source),
96 m_shadowBuild(source->m_shadowBuild),
98 m_buildDirectory(source->m_buildDirectory),
99 m_qtVersionId(source->m_qtVersionId),
100 m_qmakeBuildConfiguration(source->m_qmakeBuildConfiguration),
101 m_subNodeBuild(0) // temporary value, so not copied
107 Qt4BuildConfiguration::~Qt4BuildConfiguration()
111 QVariantMap Qt4BuildConfiguration::toMap() const
113 QVariantMap map(BuildConfiguration::toMap());
114 map.insert(QLatin1String(USE_SHADOW_BUILD_KEY), m_shadowBuild);
115 map.insert(QLatin1String(BUILD_DIRECTORY_KEY), m_buildDirectory);
116 map.insert(QLatin1String(QT_VERSION_ID_KEY), m_qtVersionId);
117 map.insert(QLatin1String(BUILD_CONFIGURATION_KEY), int(m_qmakeBuildConfiguration));
121 static inline QString msgBuildConfigNotApplicable(const QString &d, const BaseQtVersion *qtVersion,
122 const Target *target)
124 return QString::fromLatin1("Warning: Buildconfiguration '%1' : Qt '%2' from %3 not supported by target '%4'").
125 arg(d, qtVersion->displayName(), qtVersion->qmakeCommand(), target->id());
128 bool Qt4BuildConfiguration::fromMap(const QVariantMap &map)
130 if (!BuildConfiguration::fromMap(map))
133 m_shadowBuild = map.value(QLatin1String(USE_SHADOW_BUILD_KEY), true).toBool();
134 m_qtVersionId = map.value(QLatin1String(QT_VERSION_ID_KEY)).toInt();
135 ProjectExplorer::ToolChain *tc = toolChain();
136 m_qmakeBuildConfiguration = BaseQtVersion::QmakeBuildConfigs(map.value(QLatin1String(BUILD_CONFIGURATION_KEY)).toInt());
137 m_buildDirectory = map.value(QLatin1String(BUILD_DIRECTORY_KEY), defaultShadowBuildDirectory()).toString();
139 // Pick a Qt version if the default version is used:
140 // We assume that the default Qt version was used in earlier versions of Qt creator.
141 // Pick a Qt version that supports this target (usually desktop)
142 if (m_qtVersionId == 0) {
143 QList<BaseQtVersion *> versions = QtVersionManager::instance()->versionsForTargetId(target()->id());
144 foreach (BaseQtVersion *v, versions) {
146 m_qtVersionId = v->uniqueId();
150 if (m_qtVersionId == 0)
154 BaseQtVersion *version = QtVersionManager::instance()->version(m_qtVersionId);
155 if (!version || !version->supportsTargetId(target()->id())) {
160 m_lastEmmitedBuildDirectory = buildDirectory();
162 if (version && version->isValid()) {
163 if (tc && !qt4Target()->possibleToolChains(this).contains(tc))
166 tc = qt4Target()->preferredToolChain(this);
167 m_shadowBuild = (m_shadowBuild && version->supportsShadowBuilds());
171 if (version && version->isValid()) {
172 qWarning("Warning: No tool chain available for '%s' from %s used in '%s'.",
173 qPrintable(version->displayName()), qPrintable(version->qmakeCommand()),
174 qPrintable(target()->id()));
176 qWarning("Warning: No tool chain available for invalid Qt version used in '%s'.",
177 qPrintable(target()->id()));
184 void Qt4BuildConfiguration::ctor()
186 connect(this, SIGNAL(environmentChanged()),
187 this, SLOT(emitBuildDirectoryChanged()));
188 connect(this, SIGNAL(environmentChanged()),
189 this, SLOT(emitProFileEvaluteNeeded()));
191 QtVersionManager *vm = QtVersionManager::instance();
192 connect(vm, SIGNAL(qtVersionsChanged(QList<int>)),
193 this, SLOT(qtVersionsChanged(QList<int>)));
196 void Qt4BuildConfiguration::emitBuildDirectoryChanged()
198 if (buildDirectory() != m_lastEmmitedBuildDirectory) {
199 m_lastEmmitedBuildDirectory = buildDirectory();
200 emit buildDirectoryChanged();
204 Qt4BaseTarget *Qt4BuildConfiguration::qt4Target() const
206 return static_cast<Qt4BaseTarget *>(target());
209 Utils::Environment Qt4BuildConfiguration::baseEnvironment() const
211 Utils::Environment env = BuildConfiguration::baseEnvironment();
213 qtVersion()->addToEnvironment(env);
215 ToolChain *tc = toolChain();
217 tc->addToEnvironment(env);
221 QString Qt4BuildConfiguration::defaultShadowBuildDirectory() const
223 Qt4BaseTargetFactory *factory = Qt4BaseTargetFactory::qt4BaseTargetFactoryForId(qt4Target()->id());
224 // todo displayName isn't ideal
225 return factory->shadowBuildDirectory(qt4Target()->qt4Project()->file()->fileName(), qt4Target()->id(), displayName());
228 /// returns the unexpanded build directory
229 QString Qt4BuildConfiguration::rawBuildDirectory() const
231 QString workingDirectory;
233 if (!m_buildDirectory.isEmpty())
234 workingDirectory = m_buildDirectory;
236 workingDirectory = defaultShadowBuildDirectory();
238 if (workingDirectory.isEmpty())
239 workingDirectory = target()->project()->projectDirectory();
240 return workingDirectory;
243 /// returns the build directory
244 QString Qt4BuildConfiguration::buildDirectory() const
246 return QDir::cleanPath(environment().expandVariables(rawBuildDirectory()));
249 /// If only a sub tree should be build this function returns which sub node
251 /// \see Qt4BuildConfiguration::setSubNodeBuild
252 Qt4ProjectManager::Internal::Qt4ProFileNode *Qt4BuildConfiguration::subNodeBuild() const
254 return m_subNodeBuild;
257 /// A sub node build on builds a sub node of the project
258 /// That is triggered by a right click in the project explorer tree
259 /// The sub node to be build is set via this function immediately before
260 /// calling BuildManager::buildProject( BuildConfiguration * )
261 /// and reset immediately afterwards
262 /// That is m_subNodesBuild is set only temporarly
263 void Qt4BuildConfiguration::setSubNodeBuild(Qt4ProjectManager::Internal::Qt4ProFileNode *node)
265 m_subNodeBuild = node;
268 /// returns whether this is a shadow build configuration or not
269 /// note, even if shadowBuild() returns true, it might be using the
270 /// source directory as the shadow build directory, thus it
271 /// still is a in-source build
272 bool Qt4BuildConfiguration::shadowBuild() const
274 return m_shadowBuild;
277 /// returns the shadow build directory if set
278 /// \note buildDirectory() is probably the function you want to call
279 QString Qt4BuildConfiguration::shadowBuildDirectory() const
281 if (m_buildDirectory.isEmpty())
282 return defaultShadowBuildDirectory();
283 return m_buildDirectory;
286 void Qt4BuildConfiguration::setShadowBuildAndDirectory(bool shadowBuild, const QString &buildDirectory)
288 BaseQtVersion *version = qtVersion();
289 QString directoryToSet = buildDirectory;
290 bool toSet = (shadowBuild && version && version->isValid() && version->supportsShadowBuilds());
291 if (m_shadowBuild == toSet && m_buildDirectory == directoryToSet)
294 m_shadowBuild = toSet;
295 m_buildDirectory = directoryToSet;
297 emit environmentChanged();
298 emitBuildDirectoryChanged();
299 emit proFileEvaluateNeeded(this);
302 QString Qt4BuildConfiguration::makeCommand() const
304 ToolChain *tc = toolChain();
305 return tc ? tc->makeCommand() : "make";
308 static inline QString symbianMakeTarget(BaseQtVersion::QmakeBuildConfigs buildConfig,
311 QString rc = (buildConfig & BaseQtVersion::DebugBuild) ?
312 QLatin1String("debug-") : QLatin1String("release-");
317 QString Qt4BuildConfiguration::defaultMakeTarget() const
319 ToolChain *tc = toolChain();
320 if (!tc || target()->id() != Constants::S60_DEVICE_TARGET_ID)
322 const BaseQtVersion::QmakeBuildConfigs buildConfig = qmakeBuildConfiguration();
324 return symbianMakeTarget(buildConfig, tc->defaultMakeTarget());
327 QString Qt4BuildConfiguration::makefile() const
329 return qt4Target()->qt4Project()->rootProjectNode()->makefile();
332 BaseQtVersion *Qt4BuildConfiguration::qtVersion() const
334 QtVersionManager *vm = QtVersionManager::instance();
335 return vm->version(m_qtVersionId);
338 void Qt4BuildConfiguration::setQtVersion(BaseQtVersion *version)
342 m_shadowBuild = false;
344 emit proFileEvaluateNeeded(this);
345 emit qtVersionChanged();
346 emit environmentChanged();
347 emitBuildDirectoryChanged();
350 if (m_qtVersionId == version->uniqueId())
353 m_qtVersionId = version->uniqueId();
355 if (!qt4Target()->possibleToolChains(this).contains(toolChain()))
356 setToolChain(qt4Target()->preferredToolChain(this));
357 m_shadowBuild = m_shadowBuild && qtVersion()->supportsShadowBuilds();
359 emit proFileEvaluateNeeded(this);
360 emit qtVersionChanged();
361 emit environmentChanged();
362 emitBuildDirectoryChanged();
365 void Qt4BuildConfiguration::setToolChain(ProjectExplorer::ToolChain *tc)
367 if (tc != 0 && !qt4Target()->possibleToolChains(this).contains(tc))
370 BuildConfiguration::setToolChain(tc);
372 emit proFileEvaluateNeeded(this);
373 emitBuildDirectoryChanged();
376 BaseQtVersion::QmakeBuildConfigs Qt4BuildConfiguration::qmakeBuildConfiguration() const
378 return m_qmakeBuildConfiguration;
381 void Qt4BuildConfiguration::setQMakeBuildConfiguration(BaseQtVersion::QmakeBuildConfigs config)
383 if (m_qmakeBuildConfiguration == config)
385 m_qmakeBuildConfiguration = config;
387 emit proFileEvaluateNeeded(this);
388 emit qmakeBuildConfigurationChanged();
389 emitBuildDirectoryChanged();
392 void Qt4BuildConfiguration::emitProFileEvaluteNeeded()
394 emit proFileEvaluateNeeded(this);
397 void Qt4BuildConfiguration::emitQMakeBuildConfigurationChanged()
399 emit qmakeBuildConfigurationChanged();
402 void Qt4BuildConfiguration::emitBuildDirectoryInitialized()
404 emit buildDirectoryInitialized();
407 void Qt4BuildConfiguration::emitS60CreatesSmartInstallerChanged()
409 emit s60CreatesSmartInstallerChanged();
413 QStringList Qt4BuildConfiguration::configCommandLineArguments() const
416 BaseQtVersion::QmakeBuildConfigs defaultBuildConfiguration = qtVersion() ? qtVersion()->defaultBuildConfig() : (BaseQtVersion::DebugBuild | BaseQtVersion::BuildAll);
417 BaseQtVersion::QmakeBuildConfigs userBuildConfiguration = m_qmakeBuildConfiguration;
418 if ((defaultBuildConfiguration & BaseQtVersion::BuildAll) && !(userBuildConfiguration & BaseQtVersion::BuildAll))
419 result << "CONFIG-=debug_and_release";
421 if (!(defaultBuildConfiguration & BaseQtVersion::BuildAll) && (userBuildConfiguration & BaseQtVersion::BuildAll))
422 result << "CONFIG+=debug_and_release";
423 if ((defaultBuildConfiguration & BaseQtVersion::DebugBuild)
424 && !(userBuildConfiguration & BaseQtVersion::DebugBuild)
425 && !(userBuildConfiguration & BaseQtVersion::BuildAll))
426 result << "CONFIG+=release";
427 if (!(defaultBuildConfiguration & BaseQtVersion::DebugBuild)
428 && (userBuildConfiguration & BaseQtVersion::DebugBuild)
429 && !(userBuildConfiguration & BaseQtVersion::BuildAll))
430 result << "CONFIG+=debug";
434 QMakeStep *Qt4BuildConfiguration::qmakeStep() const
437 BuildStepList *bsl = stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
439 for (int i = 0; i < bsl->count(); ++i)
440 if ((qs = qobject_cast<QMakeStep *>(bsl->at(i))) != 0)
445 MakeStep *Qt4BuildConfiguration::makeStep() const
448 BuildStepList *bsl = stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
450 for (int i = 0; i < bsl->count(); ++i)
451 if ((ms = qobject_cast<MakeStep *>(bsl->at(i))) != 0)
456 void Qt4BuildConfiguration::qtVersionsChanged(const QList<int> &changedVersions)
458 if (!changedVersions.contains(m_qtVersionId))
460 emit environmentChanged(); // Our qt version changed, that might have changed the environment
463 // returns true if both are equal
464 bool Qt4BuildConfiguration::compareToImportFrom(const QString &makefile)
466 QMakeStep *qs = qmakeStep();
467 if (QFileInfo(makefile).exists() && qs) {
468 QString qmakePath = QtVersionManager::findQMakeBinaryFromMakefile(makefile);
469 BaseQtVersion *version = qtVersion();
472 if (version->qmakeCommand() == qmakePath) {
474 QPair<BaseQtVersion::QmakeBuildConfigs, QString> result =
475 QtVersionManager::scanMakeFile(makefile, version->defaultBuildConfig());
476 if (qmakeBuildConfiguration() == result.first) {
477 // The qmake Build Configuration are the same,
478 // now compare arguments lists
479 // we have to compare without the spec/platform cmd argument
480 // and compare that on its own
481 QString workingDirectory = QFileInfo(makefile).absolutePath();
482 QString userArgs = qs->userArguments();
483 QStringList actualArgs;
484 QString actualSpec = extractSpecFromArguments(&userArgs, workingDirectory, version, &actualArgs);
485 if (actualSpec.isEmpty()) {
486 // Easy one: the user has chosen not to override the settings
487 actualSpec = version->mkspec();
489 actualArgs += qs->moreArguments();
491 QString qmakeArgs = result.second;
492 QStringList parsedArgs;
493 QString parsedSpec = extractSpecFromArguments(&qmakeArgs, workingDirectory, version, &parsedArgs);
496 qDebug()<<"Actual args:"<<actualArgs;
497 qDebug()<<"Parsed args:"<<parsedArgs;
498 qDebug()<<"Actual spec:"<<actualSpec;
499 qDebug()<<"Parsed spec:"<<parsedSpec;
502 // Comparing the sorted list is obviously wrong
503 // Though haven written a more complete version
504 // that managed had around 200 lines and yet faild
505 // to be actually foolproof at all, I think it's
506 // not feasible without actually taking the qmake
507 // command line parsing code
509 // Things, sorting gets wrong:
510 // parameters to positional parameters matter
511 // e.g. -o -spec is different from -spec -o
512 // -o 1 -spec 2 is diffrent from -spec 1 -o 2
513 // variable assignment order matters
514 // variable assignment vs -after
515 // -norecursive vs. recursive
518 if (actualArgs == parsedArgs) {
519 // Specs match exactly
520 if (actualSpec == parsedSpec)
522 // Actual spec is the default one
523 // qDebug()<<"AS vs VS"<<actualSpec<<version->mkspec();
524 if ((actualSpec == version->mkspec() || actualSpec == "default")
525 && (parsedSpec == version->mkspec() || parsedSpec == "default" || parsedSpec.isEmpty()))
529 qDebug()<<"different qmake buildconfigurations buildconfiguration:"<<qmakeBuildConfiguration()<<" Makefile:"<<result.first;
532 qDebug()<<"diffrent qt versions, buildconfiguration:"<<version->qmakeCommand()<<" Makefile:"<<qmakePath;
538 void Qt4BuildConfiguration::removeQMLInspectorFromArguments(QString *args)
540 for (Utils::QtcProcess::ArgIterator ait(args); ait.next(); )
541 if (ait.value().contains(QLatin1String(Constants::QMAKEVAR_QMLJSDEBUGGER_PATH)))
545 QString Qt4BuildConfiguration::extractSpecFromArguments(QString *args,
546 const QString &directory, const BaseQtVersion *version,
547 QStringList *outArgs)
551 bool ignoreNext = false;
552 bool nextIsSpec = false;
553 for (Utils::QtcProcess::ArgIterator ait(args); ait.next(); ) {
557 } else if (nextIsSpec) {
559 parsedSpec = QDir::cleanPath(ait.value());
561 } else if (ait.value() == QLatin1String("-spec") || ait.value() == QLatin1String("-platform")) {
564 } else if (ait.value() == QLatin1String("-cache")) {
565 // We ignore -cache, because qmake contained a bug that it didn't
566 // mention the -cache in the Makefile.
567 // That means changing the -cache option in the additional arguments
568 // does not automatically rerun qmake. Alas, we could try more
569 // intelligent matching for -cache, but i guess people rarely
573 } else if (outArgs && ait.isSimple()) {
574 outArgs->append(ait.value());
578 if (parsedSpec.isEmpty())
581 QString baseMkspecDir = version->versionInfo().value("QMAKE_MKSPECS");
582 if (baseMkspecDir.isEmpty())
583 baseMkspecDir = version->versionInfo().value("QT_INSTALL_DATA") + "/mkspecs";
586 baseMkspecDir = baseMkspecDir.toLower();
587 parsedSpec = parsedSpec.toLower();
589 // if the path is relative it can be
590 // relative to the working directory (as found in the Makefiles)
591 // or relatively to the mkspec directory
592 // if it is the former we need to get the canonical form
593 // for the other one we don't need to do anything
594 if (QFileInfo(parsedSpec).isRelative()) {
595 if(QFileInfo(directory + QLatin1Char('/') + parsedSpec).exists()) {
596 parsedSpec = QDir::cleanPath(directory + QLatin1Char('/') + parsedSpec);
598 parsedSpec = parsedSpec.toLower();
601 parsedSpec = baseMkspecDir + QLatin1Char('/') + parsedSpec;
605 QFileInfo f2(parsedSpec);
606 while (f2.isSymLink()) {
607 parsedSpec = f2.symLinkTarget();
608 f2.setFile(parsedSpec);
611 if (parsedSpec.startsWith(baseMkspecDir)) {
612 parsedSpec = parsedSpec.mid(baseMkspecDir.length() + 1);
614 QString sourceMkSpecPath = version->sourcePath() + "/mkspecs";
615 if (parsedSpec.startsWith(sourceMkSpecPath)) {
616 parsedSpec = parsedSpec.mid(sourceMkSpecPath.length() + 1);
620 parsedSpec = parsedSpec.toLower();
625 ProjectExplorer::IOutputParser *Qt4BuildConfiguration::createOutputParser() const
627 ToolChain *tc = toolChain();
629 return toolChain()->outputParser();
633 bool Qt4BuildConfiguration::isEnabled() const
638 void Qt4BuildConfiguration::setEnabled(bool enabled)
640 if (m_isEnabled == enabled)
642 m_isEnabled = enabled;
643 emit enabledChanged();
647 \class Qt4BuildConfigurationFactory
650 Qt4BuildConfigurationFactory::Qt4BuildConfigurationFactory(QObject *parent) :
651 ProjectExplorer::IBuildConfigurationFactory(parent)
655 QtVersionManager *vm = QtVersionManager::instance();
656 connect(vm, SIGNAL(qtVersionsChanged(QList<int>)),
657 this, SLOT(update()));
660 Qt4BuildConfigurationFactory::~Qt4BuildConfigurationFactory()
664 void Qt4BuildConfigurationFactory::update()
667 QtVersionManager *vm = QtVersionManager::instance();
668 foreach (BaseQtVersion *version, vm->validVersions()) {
669 QString key = QString::fromLatin1(QT4_BC_ID_PREFIX)
670 + QString::fromLatin1("Qt%1").arg(version->uniqueId());
671 VersionInfo info(tr("Using Qt Version \"%1\"").arg(version->displayName()), version->uniqueId());
672 m_versions.insert(key, info);
674 emit availableCreationIdsChanged();
677 QStringList Qt4BuildConfigurationFactory::availableCreationIds(ProjectExplorer::Target *parent) const
679 if (!qobject_cast<Qt4BaseTarget *>(parent))
680 return QStringList();
683 QtVersionManager *vm = QtVersionManager::instance();
684 for (QMap<QString, VersionInfo>::const_iterator i = m_versions.constBegin();
685 i != m_versions.constEnd(); ++i) {
686 if (vm->version(i.value().versionId)->supportsTargetId(parent->id())
687 && vm->version(i.value().versionId)->toolChainAvailable(parent->id()))
688 results.append(i.key());
693 QString Qt4BuildConfigurationFactory::displayNameForId(const QString &id) const
695 if (!m_versions.contains(id))
697 return m_versions.value(id).displayName;
700 bool Qt4BuildConfigurationFactory::canCreate(ProjectExplorer::Target *parent, const QString &id) const
702 if (!qobject_cast<Qt4BaseTarget *>(parent))
704 if (!m_versions.contains(id))
706 const VersionInfo &info = m_versions.value(id);
707 BaseQtVersion *version = QtVersionManager::instance()->version(info.versionId);
709 !version->supportsTargetId(parent->id()))
714 BuildConfiguration *Qt4BuildConfigurationFactory::create(ProjectExplorer::Target *parent, const QString &id)
716 if (!canCreate(parent, id))
719 const VersionInfo &info = m_versions.value(id);
720 BaseQtVersion *version = QtVersionManager::instance()->version(info.versionId);
723 Qt4BaseTarget *qt4Target = static_cast<Qt4BaseTarget *>(parent);
726 QString buildConfigurationName = QInputDialog::getText(0,
727 tr("New Configuration"),
728 tr("New configuration name:"),
730 version->displayName(),
732 buildConfigurationName = buildConfigurationName.trimmed();
733 if (!ok || buildConfigurationName.isEmpty())
736 //: Debug build configuration. We recommend not translating it.
737 BuildConfiguration *bc = qt4Target->addQt4BuildConfiguration(tr("%1 Debug").arg(buildConfigurationName),
739 (version->defaultBuildConfig() | BaseQtVersion::DebugBuild),
740 QString(), QString());
742 if (qt4Target->id() != Constants::S60_EMULATOR_TARGET_ID) {
743 //: Release build configuration. We recommend not translating it.
744 bc = qt4Target->addQt4BuildConfiguration(tr("%1 Release").arg(buildConfigurationName),
746 (version->defaultBuildConfig() & ~BaseQtVersion::DebugBuild),
747 QString(), QString());
752 bool Qt4BuildConfigurationFactory::canClone(ProjectExplorer::Target *parent, ProjectExplorer::BuildConfiguration *source) const
754 if (!qobject_cast<Qt4BaseTarget *>(parent))
756 Qt4BuildConfiguration *qt4bc(qobject_cast<Qt4BuildConfiguration *>(source));
760 BaseQtVersion *version = qt4bc->qtVersion();
762 !version->supportsTargetId(parent->id()))
767 BuildConfiguration *Qt4BuildConfigurationFactory::clone(Target *parent, BuildConfiguration *source)
769 if (!canClone(parent, source))
771 Qt4BaseTarget *target = static_cast<Qt4BaseTarget *>(parent);
772 Qt4BuildConfiguration *oldbc(static_cast<Qt4BuildConfiguration *>(source));
773 return new Qt4BuildConfiguration(target, oldbc);
776 bool Qt4BuildConfigurationFactory::canRestore(Target *parent, const QVariantMap &map) const
778 QString id = ProjectExplorer::idFromMap(map);
779 if (!qobject_cast<Qt4BaseTarget *>(parent))
781 return id.startsWith(QLatin1String(QT4_BC_ID_PREFIX)) ||
782 id == QLatin1String(QT4_BC_ID);
785 BuildConfiguration *Qt4BuildConfigurationFactory::restore(Target *parent, const QVariantMap &map)
787 if (!canRestore(parent, map))
789 Qt4BaseTarget *target = static_cast<Qt4BaseTarget *>(parent);
790 Qt4BuildConfiguration *bc = new Qt4BuildConfiguration(target);
791 if (bc->fromMap(map))
797 void Qt4BuildConfiguration::importFromBuildDirectory()
799 QString directory = buildDirectory();
800 if (!directory.isEmpty()) {
801 QString mkfile = directory;
802 if (makefile().isEmpty())
803 mkfile.append("/Makefile");
805 mkfile.append(makefile());
807 QString qmakePath = QtVersionManager::findQMakeBinaryFromMakefile(mkfile);
808 if (!qmakePath.isEmpty()) {
809 QtVersionManager *vm = QtVersionManager::instance();
810 BaseQtVersion *version = vm->qtVersionForQMakeBinary(qmakePath);
812 version = QtVersionFactory::createQtVersionFromQMakePath(qmakePath);
813 vm->addVersion(version);
816 QPair<BaseQtVersion::QmakeBuildConfigs, QString> result =
817 QtVersionManager::scanMakeFile(mkfile, version->defaultBuildConfig());
818 BaseQtVersion::QmakeBuildConfigs qmakeBuildConfig = result.first;
820 QString aa = result.second;
821 QString parsedSpec = Qt4BuildConfiguration::extractSpecFromArguments(&aa, directory, version);
822 QString versionSpec = version->mkspec();
823 QString additionalArguments;
824 if (parsedSpec.isEmpty() || parsedSpec == versionSpec || parsedSpec == "default") {
825 // using the default spec, don't modify additional arguments
827 additionalArguments = "-spec " + Utils::QtcProcess::quoteArg(parsedSpec);
829 Utils::QtcProcess::addArgs(&additionalArguments, aa);
831 Qt4BuildConfiguration::removeQMLInspectorFromArguments(&additionalArguments);
833 // So we got all the information now apply it...
834 setQtVersion(version);
836 qmakeStep()->setUserArguments(additionalArguments);
838 setQMakeBuildConfiguration(qmakeBuildConfig);
839 // Adjust command line arguments, this is ugly as hell
840 // If we are switching to BuildAll we want "release" in there and no "debug"
841 // or "debug" in there and no "release"
842 // If we are switching to not BuildAll we want neither "release" nor "debug" in there
843 bool debug = qmakeBuildConfig & BaseQtVersion::DebugBuild;
844 bool haveTag = !(qmakeBuildConfig & BaseQtVersion::BuildAll);
845 QString makeCmdArguments = makeStep()->userArguments();
846 Utils::QtcProcess::ArgIterator ait(&makeCmdArguments);
848 if (ait.value() == QLatin1String("debug")) {
849 if (!haveTag && debug)
853 } else if (ait.value() == QLatin1String("release")) {
854 if (!haveTag && !debug)
861 ait.appendArg(QLatin1String(debug ? "debug" : "release"));
862 makeStep()->setUserArguments(makeCmdArguments);
867 BuildConfiguration::BuildType Qt4BuildConfiguration::buildType() const
869 if (qmakeBuildConfiguration() & BaseQtVersion::DebugBuild)