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 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)),
75 m_qmakeBuildConfiguration(0),
81 Qt4BuildConfiguration::Qt4BuildConfiguration(Qt4BaseTarget *target, const QString &id) :
82 BuildConfiguration(target, id),
86 m_qmakeBuildConfiguration(0),
92 Qt4BuildConfiguration::Qt4BuildConfiguration(Qt4BaseTarget *target, Qt4BuildConfiguration *source) :
93 BuildConfiguration(target, source),
94 m_shadowBuild(source->m_shadowBuild),
96 m_buildDirectory(source->m_buildDirectory),
97 m_qtVersionId(source->m_qtVersionId),
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), toolChain() ? toolChain()->id() : QLatin1String("<UNSET>"));
116 map.insert(QLatin1String(BUILD_CONFIGURATION_KEY), int(m_qmakeBuildConfiguration));
120 static inline QString msgBuildConfigNotApplicable(const QString &d, const QtVersion *qtVersion,
121 const Target *target)
123 return QString::fromLatin1("Warning: Buildconfiguration '%1' : Qt '%2' from %3 not supported by target '%4'").
124 arg(d, qtVersion->displayName(), qtVersion->qmakeCommand(), target->id());
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_buildDirectory = map.value(QLatin1String(BUILD_DIRECTORY_KEY), qt4Target()->defaultBuildDirectory()).toString();
134 m_qtVersionId = map.value(QLatin1String(QT_VERSION_ID_KEY)).toInt();
135 ProjectExplorer::ToolChain *tc = 0;
136 tc = ProjectExplorer::ToolChainManager::instance()->findToolChain(map.value(QLatin1String(TOOLCHAIN_KEY)).toString());
137 m_qmakeBuildConfiguration = QtVersion::QmakeBuildConfigs(map.value(QLatin1String(BUILD_CONFIGURATION_KEY)).toInt());
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 is supporting a desktop.
142 if (m_qtVersionId == 0) {
143 QList<QtVersion *> versions = QtVersionManager::instance()->versions();
144 foreach (QtVersion *v, versions) {
145 if (v->isValid() && v->supportsTargetId(QLatin1String(Constants::DESKTOP_TARGET_ID))) {
146 m_qtVersionId = v->uniqueId();
150 if (m_qtVersionId == 0)
151 m_qtVersionId = versions.at(0)->uniqueId();
154 QtVersion *version = qtVersion();
155 if (!map.contains(QLatin1String("Qt4ProjectManager.Qt4BuildConfiguration.NeedsV0Update"))) { // we are not upgrading from pre-targets!
156 if (version->isValid() && !version->supportedTargetIds().contains(target()->id())) {
157 qWarning("%s", qPrintable(msgBuildConfigNotApplicable(displayName(), version, target())));
161 if (!version->isValid() || !version->supportedTargetIds().contains(target()->id())) {
162 qWarning("%s", qPrintable(msgBuildConfigNotApplicable(displayName(), version, target())));
167 if (version->isValid()) {
169 tc = qt4Target()->preferredToolChain(this);
170 if (tc && qt4Target()->possibleToolChains(this).contains(tc))
172 m_shadowBuild = (m_shadowBuild && version->supportsShadowBuilds());
176 if (version->isValid()) {
177 qWarning("Warning: No tool chain available for '%s' from %s used in '%s'.",
178 qPrintable(version->displayName()), qPrintable(version->qmakeCommand()),
179 qPrintable(target()->id()));
181 qWarning("Warning: No tool chain available for invalid Qt version used in '%s'.",
182 qPrintable(target()->id()));
190 void Qt4BuildConfiguration::ctor()
192 m_buildDirectory = qt4Target()->defaultBuildDirectory();
193 if (m_buildDirectory == target()->project()->projectDirectory())
194 m_shadowBuild = false;
196 m_lastEmmitedBuildDirectory = buildDirectory();
198 connect(this, SIGNAL(environmentChanged()),
199 this, SLOT(emitBuildDirectoryChanged()));
201 QtVersionManager *vm = QtVersionManager::instance();
202 connect(vm, SIGNAL(qtVersionsChanged(QList<int>)),
203 this, SLOT(qtVersionsChanged(QList<int>)));
206 void Qt4BuildConfiguration::emitBuildDirectoryChanged()
208 if (buildDirectory() != m_lastEmmitedBuildDirectory) {
209 m_lastEmmitedBuildDirectory = buildDirectory();
210 emit buildDirectoryChanged();
214 void Qt4BuildConfiguration::pickValidQtVersion()
216 QList<QtVersion *> versions = QtVersionManager::instance()->versionsForTargetId(qt4Target()->id());
217 if (!versions.isEmpty())
218 setQtVersion(versions.at(0));
220 setQtVersion(QtVersionManager::instance()->emptyVersion());
223 Qt4BaseTarget *Qt4BuildConfiguration::qt4Target() const
225 return static_cast<Qt4BaseTarget *>(target());
228 Utils::Environment Qt4BuildConfiguration::baseEnvironment() const
230 Utils::Environment env = BuildConfiguration::baseEnvironment();
231 qtVersion()->addToEnvironment(env);
233 ToolChain *tc = toolChain();
235 tc->addToEnvironment(env);
239 /// returns the unexpanded build directory
240 QString Qt4BuildConfiguration::rawBuildDirectory() const
242 QString workingDirectory;
244 if (!m_buildDirectory.isEmpty())
245 workingDirectory = m_buildDirectory;
247 workingDirectory = qt4Target()->defaultBuildDirectory();
249 if (workingDirectory.isEmpty())
250 workingDirectory = target()->project()->projectDirectory();
251 return workingDirectory;
254 /// returns the build directory
255 QString Qt4BuildConfiguration::buildDirectory() const
257 return QDir::cleanPath(environment().expandVariables(rawBuildDirectory()));
260 /// If only a sub tree should be build this function returns which sub node
262 /// \see Qt4BuildConfiguration::setSubNodeBuild
263 Qt4ProjectManager::Internal::Qt4ProFileNode *Qt4BuildConfiguration::subNodeBuild() const
265 return m_subNodeBuild;
268 /// A sub node build on builds a sub node of the project
269 /// That is triggered by a right click in the project explorer tree
270 /// The sub node to be build is set via this function immediately before
271 /// calling BuildManager::buildProject( BuildConfiguration * )
272 /// and reset immediately afterwards
273 /// That is m_subNodesBuild is set only temporarly
274 void Qt4BuildConfiguration::setSubNodeBuild(Qt4ProjectManager::Internal::Qt4ProFileNode *node)
276 m_subNodeBuild = node;
279 /// returns whether this is a shadow build configuration or not
280 /// note, even if shadowBuild() returns true, it might be using the
281 /// source directory as the shadow build directory, thus it
282 /// still is a in-source build
283 bool Qt4BuildConfiguration::shadowBuild() const
285 return m_shadowBuild;
288 /// returns the shadow build directory if set
289 /// \note buildDirectory() is probably the function you want to call
290 QString Qt4BuildConfiguration::shadowBuildDirectory() const
292 if (m_buildDirectory.isEmpty())
293 return qt4Target()->defaultBuildDirectory();
294 return m_buildDirectory;
297 void Qt4BuildConfiguration::setShadowBuildAndDirectory(bool shadowBuild, const QString &buildDirectory)
299 QtVersion *version = qtVersion();
300 QString directoryToSet = buildDirectory;
301 bool toSet = (shadowBuild && version->isValid() && version->supportsShadowBuilds());
302 if (m_shadowBuild == toSet && m_buildDirectory == directoryToSet)
305 m_shadowBuild = toSet;
306 m_buildDirectory = directoryToSet;
308 emit environmentChanged();
309 emitBuildDirectoryChanged();
310 emit proFileEvaluateNeeded(this);
313 QString Qt4BuildConfiguration::makeCommand() const
315 ToolChain *tc = toolChain();
316 return tc ? tc->makeCommand() : "make";
319 static inline QString symbianMakeTarget(QtVersion::QmakeBuildConfigs buildConfig,
322 QString rc = (buildConfig & QtVersion::DebugBuild) ?
323 QLatin1String("debug-") : QLatin1String("release-");
328 QString Qt4BuildConfiguration::defaultMakeTarget() const
330 ToolChain *tc = toolChain();
331 if (!tc || target()->id() != Constants::S60_DEVICE_TARGET_ID)
333 const QtVersion::QmakeBuildConfigs buildConfig = qmakeBuildConfiguration();
335 return symbianMakeTarget(buildConfig, tc->defaultMakeTarget());
338 QString Qt4BuildConfiguration::makefile() const
340 return qt4Target()->qt4Project()->rootProjectNode()->makefile();
343 QtVersion *Qt4BuildConfiguration::qtVersion() const
345 QtVersionManager *vm = QtVersionManager::instance();
346 return vm->version(m_qtVersionId);
349 void Qt4BuildConfiguration::setQtVersion(QtVersion *version)
353 if (m_qtVersionId == version->uniqueId())
356 m_qtVersionId = version->uniqueId();
358 if (!qt4Target()->possibleToolChains(this).contains(toolChain()))
359 setToolChain(qt4Target()->preferredToolChain(this));
360 m_shadowBuild = m_shadowBuild && qtVersion()->supportsShadowBuilds();
362 emit proFileEvaluateNeeded(this);
363 emit qtVersionChanged();
364 emit environmentChanged();
365 emitBuildDirectoryChanged();
368 void Qt4BuildConfiguration::setToolChain(ProjectExplorer::ToolChain *tc)
370 Q_ASSERT(qtVersion());
371 if (tc != 0 && !qt4Target()->possibleToolChains(this).contains(tc))
374 BuildConfiguration::setToolChain(tc);
376 emit proFileEvaluateNeeded(this);
377 emit environmentChanged();
378 emitBuildDirectoryChanged();
381 QtVersion::QmakeBuildConfigs Qt4BuildConfiguration::qmakeBuildConfiguration() const
383 return m_qmakeBuildConfiguration;
386 void Qt4BuildConfiguration::setQMakeBuildConfiguration(QtVersion::QmakeBuildConfigs config)
388 if (m_qmakeBuildConfiguration == config)
390 m_qmakeBuildConfiguration = config;
392 emit proFileEvaluateNeeded(this);
393 emit qmakeBuildConfigurationChanged();
396 void Qt4BuildConfiguration::emitProFileEvaluteNeeded()
398 emit proFileEvaluateNeeded(this);
401 void Qt4BuildConfiguration::emitQMakeBuildConfigurationChanged()
403 emit qmakeBuildConfigurationChanged();
406 void Qt4BuildConfiguration::emitBuildDirectoryInitialized()
408 emit buildDirectoryInitialized();
411 void Qt4BuildConfiguration::emitS60CreatesSmartInstallerChanged()
413 emit s60CreatesSmartInstallerChanged();
417 QStringList Qt4BuildConfiguration::configCommandLineArguments() const
420 QtVersion::QmakeBuildConfigs defaultBuildConfiguration = qtVersion()->defaultBuildConfig();
421 QtVersion::QmakeBuildConfigs userBuildConfiguration = m_qmakeBuildConfiguration;
422 if ((defaultBuildConfiguration & QtVersion::BuildAll) && !(userBuildConfiguration & QtVersion::BuildAll))
423 result << "CONFIG-=debug_and_release";
425 if (!(defaultBuildConfiguration & QtVersion::BuildAll) && (userBuildConfiguration & QtVersion::BuildAll))
426 result << "CONFIG+=debug_and_release";
427 if ((defaultBuildConfiguration & QtVersion::DebugBuild)
428 && !(userBuildConfiguration & QtVersion::DebugBuild)
429 && !(userBuildConfiguration & QtVersion::BuildAll))
430 result << "CONFIG+=release";
431 if (!(defaultBuildConfiguration & QtVersion::DebugBuild)
432 && (userBuildConfiguration & QtVersion::DebugBuild)
433 && !(userBuildConfiguration & QtVersion::BuildAll))
434 result << "CONFIG+=debug";
438 QMakeStep *Qt4BuildConfiguration::qmakeStep() const
441 BuildStepList *bsl = stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
443 for (int i = 0; i < bsl->count(); ++i)
444 if ((qs = qobject_cast<QMakeStep *>(bsl->at(i))) != 0)
449 MakeStep *Qt4BuildConfiguration::makeStep() const
452 BuildStepList *bsl = stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
454 for (int i = 0; i < bsl->count(); ++i)
455 if ((ms = qobject_cast<MakeStep *>(bsl->at(i))) != 0)
460 void Qt4BuildConfiguration::qtVersionsChanged(const QList<int> &changedVersions)
462 if (!changedVersions.contains(m_qtVersionId) ||
463 qtVersion()->isValid())
466 pickValidQtVersion();
469 // returns true if both are equal
470 bool Qt4BuildConfiguration::compareToImportFrom(const QString &makefile)
472 QMakeStep *qs = qmakeStep();
473 if (QFileInfo(makefile).exists() && qs) {
474 QString qmakePath = QtVersionManager::findQMakeBinaryFromMakefile(makefile);
475 QtVersion *version = qtVersion();
476 if (version->qmakeCommand() == qmakePath) {
478 QPair<QtVersion::QmakeBuildConfigs, QString> result =
479 QtVersionManager::scanMakeFile(makefile, version->defaultBuildConfig());
480 if (qmakeBuildConfiguration() == result.first) {
481 // The qmake Build Configuration are the same,
482 // now compare arguments lists
483 // we have to compare without the spec/platform cmd argument
484 // and compare that on its own
485 QString workingDirectory = QFileInfo(makefile).absolutePath();
486 QString userArgs = qs->userArguments();
487 QStringList actualArgs;
488 QString actualSpec = extractSpecFromArguments(&userArgs, workingDirectory, version, &actualArgs);
489 if (actualSpec.isEmpty()) {
490 // Easy one: the user has chosen not to override the settings
491 actualSpec = version->mkspec();
493 actualArgs += qs->moreArguments();
495 QString qmakeArgs = result.second;
496 QStringList parsedArgs;
497 QString parsedSpec = extractSpecFromArguments(&qmakeArgs, workingDirectory, version, &parsedArgs);
500 qDebug()<<"Actual args:"<<actualArgs;
501 qDebug()<<"Parsed args:"<<parsedArgs;
502 qDebug()<<"Actual spec:"<<actualSpec;
503 qDebug()<<"Parsed spec:"<<parsedSpec;
506 // Comparing the sorted list is obviously wrong
507 // Though haven written a more complete version
508 // that managed had around 200 lines and yet faild
509 // to be actually foolproof at all, I think it's
510 // not feasible without actually taking the qmake
511 // command line parsing code
513 // Things, sorting gets wrong:
514 // parameters to positional parameters matter
515 // e.g. -o -spec is different from -spec -o
516 // -o 1 -spec 2 is diffrent from -spec 1 -o 2
517 // variable assignment order matters
518 // variable assignment vs -after
519 // -norecursive vs. recursive
522 if (actualArgs == parsedArgs) {
523 // Specs match exactly
524 if (actualSpec == parsedSpec)
526 // Actual spec is the default one
527 // qDebug()<<"AS vs VS"<<actualSpec<<version->mkspec();
528 if ((actualSpec == version->mkspec() || actualSpec == "default")
529 && (parsedSpec == version->mkspec() || parsedSpec == "default" || parsedSpec.isEmpty()))
533 qDebug()<<"different qmake buildconfigurations buildconfiguration:"<<qmakeBuildConfiguration()<<" Makefile:"<<result.first;
536 qDebug()<<"diffrent qt versions, buildconfiguration:"<<version->qmakeCommand()<<" Makefile:"<<qmakePath;
542 void Qt4BuildConfiguration::removeQMLInspectorFromArguments(QString *args)
544 for (Utils::QtcProcess::ArgIterator ait(args); ait.next(); )
545 if (ait.value().contains(QLatin1String(Constants::QMAKEVAR_QMLJSDEBUGGER_PATH)))
549 QString Qt4BuildConfiguration::extractSpecFromArguments(QString *args,
550 const QString &directory, const QtVersion *version,
551 QStringList *outArgs)
555 bool ignoreNext = false;
556 bool nextIsSpec = false;
557 for (Utils::QtcProcess::ArgIterator ait(args); ait.next(); ) {
561 } else if (nextIsSpec) {
563 parsedSpec = QDir::cleanPath(ait.value());
565 } else if (ait.value() == QLatin1String("-spec") || ait.value() == QLatin1String("-platform")) {
568 } else if (ait.value() == QLatin1String("-cache")) {
569 // We ignore -cache, because qmake contained a bug that it didn't
570 // mention the -cache in the Makefile.
571 // That means changing the -cache option in the additional arguments
572 // does not automatically rerun qmake. Alas, we could try more
573 // intelligent matching for -cache, but i guess people rarely
577 } else if (outArgs && ait.isSimple()) {
578 outArgs->append(ait.value());
582 if (parsedSpec.isEmpty())
585 QString baseMkspecDir = version->versionInfo().value("QMAKE_MKSPECS");
586 if (baseMkspecDir.isEmpty())
587 baseMkspecDir = version->versionInfo().value("QT_INSTALL_DATA") + "/mkspecs";
590 baseMkspecDir = baseMkspecDir.toLower();
591 parsedSpec = parsedSpec.toLower();
593 // if the path is relative it can be
594 // relative to the working directory (as found in the Makefiles)
595 // or relatively to the mkspec directory
596 // if it is the former we need to get the canonical form
597 // for the other one we don't need to do anything
598 if (QFileInfo(parsedSpec).isRelative()) {
599 if(QFileInfo(directory + QLatin1Char('/') + parsedSpec).exists()) {
600 parsedSpec = QDir::cleanPath(directory + QLatin1Char('/') + parsedSpec);
602 parsedSpec = parsedSpec.toLower();
605 parsedSpec = baseMkspecDir + QLatin1Char('/') + parsedSpec;
609 QFileInfo f2(parsedSpec);
610 while (f2.isSymLink()) {
611 parsedSpec = f2.symLinkTarget();
612 f2.setFile(parsedSpec);
615 if (parsedSpec.startsWith(baseMkspecDir)) {
616 parsedSpec = parsedSpec.mid(baseMkspecDir.length() + 1);
618 QString sourceMkSpecPath = version->sourcePath() + "/mkspecs";
619 if (parsedSpec.startsWith(sourceMkSpecPath)) {
620 parsedSpec = parsedSpec.mid(sourceMkSpecPath.length() + 1);
624 parsedSpec = parsedSpec.toLower();
629 ProjectExplorer::IOutputParser *Qt4BuildConfiguration::createOutputParser() const
631 ToolChain *tc = toolChain();
633 return toolChain()->outputParser();
637 bool Qt4BuildConfiguration::isEnabled() const
642 void Qt4BuildConfiguration::setEnabled(bool enabled)
644 if (m_isEnabled == enabled)
646 m_isEnabled = enabled;
647 emit enabledChanged();
651 \class Qt4BuildConfigurationFactory
654 Qt4BuildConfigurationFactory::Qt4BuildConfigurationFactory(QObject *parent) :
655 ProjectExplorer::IBuildConfigurationFactory(parent)
659 QtVersionManager *vm = QtVersionManager::instance();
660 connect(vm, SIGNAL(qtVersionsChanged(QList<int>)),
661 this, SLOT(update()));
664 Qt4BuildConfigurationFactory::~Qt4BuildConfigurationFactory()
668 void Qt4BuildConfigurationFactory::update()
671 QtVersionManager *vm = QtVersionManager::instance();
672 foreach (const QtVersion *version, vm->versions()) {
673 if (version->isValid()) {
674 QString key = QString::fromLatin1(QT4_BC_ID_PREFIX)
675 + QString::fromLatin1("Qt%1").arg(version->uniqueId());
676 VersionInfo info(tr("Using Qt Version \"%1\"").arg(version->displayName()), version->uniqueId());
677 m_versions.insert(key, info);
680 emit availableCreationIdsChanged();
683 QStringList Qt4BuildConfigurationFactory::availableCreationIds(ProjectExplorer::Target *parent) const
685 if (!qobject_cast<Qt4BaseTarget *>(parent))
686 return QStringList();
689 QtVersionManager *vm = QtVersionManager::instance();
690 for (QMap<QString, VersionInfo>::const_iterator i = m_versions.constBegin();
691 i != m_versions.constEnd(); ++i) {
692 if (vm->version(i.value().versionId)->supportsTargetId(parent->id()))
693 results.append(i.key());
698 QString Qt4BuildConfigurationFactory::displayNameForId(const QString &id) const
700 if (!m_versions.contains(id))
702 return m_versions.value(id).displayName;
705 bool Qt4BuildConfigurationFactory::canCreate(ProjectExplorer::Target *parent, const QString &id) const
707 if (!qobject_cast<Qt4BaseTarget *>(parent))
709 if (!m_versions.contains(id))
711 const VersionInfo &info = m_versions.value(id);
712 QtVersion *version = QtVersionManager::instance()->version(info.versionId);
714 !version->supportsTargetId(parent->id()))
719 BuildConfiguration *Qt4BuildConfigurationFactory::create(ProjectExplorer::Target *parent, const QString &id)
721 if (!canCreate(parent, id))
724 const VersionInfo &info = m_versions.value(id);
725 QtVersion *version = QtVersionManager::instance()->version(info.versionId);
728 Qt4BaseTarget *qt4Target = static_cast<Qt4BaseTarget *>(parent);
731 QString buildConfigurationName = QInputDialog::getText(0,
732 tr("New Configuration"),
733 tr("New configuration name:"),
735 version->displayName(),
737 buildConfigurationName = buildConfigurationName.trimmed();
738 if (!ok || buildConfigurationName.isEmpty())
741 //: Debug build configuration. We recommend not translating it.
742 qt4Target->addQt4BuildConfiguration(tr("%1 Debug").arg(buildConfigurationName),
744 (version->defaultBuildConfig() | QtVersion::DebugBuild),
745 QString(), QString());
746 BuildConfiguration *bc =
747 //: Release build configuration. We recommend not translating it.
748 qt4Target->addQt4BuildConfiguration(tr("%1 Release").arg(buildConfigurationName),
750 (version->defaultBuildConfig() & ~QtVersion::DebugBuild),
751 QString(), QString());
755 bool Qt4BuildConfigurationFactory::canClone(ProjectExplorer::Target *parent, ProjectExplorer::BuildConfiguration *source) const
757 if (!qobject_cast<Qt4BaseTarget *>(parent))
759 Qt4BuildConfiguration *qt4bc(qobject_cast<Qt4BuildConfiguration *>(source));
763 QtVersion *version = qt4bc->qtVersion();
765 !version->supportsTargetId(parent->id()))
770 BuildConfiguration *Qt4BuildConfigurationFactory::clone(Target *parent, BuildConfiguration *source)
772 if (!canClone(parent, source))
774 Qt4BaseTarget *target = static_cast<Qt4BaseTarget *>(parent);
775 Qt4BuildConfiguration *oldbc(static_cast<Qt4BuildConfiguration *>(source));
776 return new Qt4BuildConfiguration(target, oldbc);
779 bool Qt4BuildConfigurationFactory::canRestore(Target *parent, const QVariantMap &map) const
781 QString id = ProjectExplorer::idFromMap(map);
782 if (!qobject_cast<Qt4BaseTarget *>(parent))
784 return id.startsWith(QLatin1String(QT4_BC_ID_PREFIX)) ||
785 id == QLatin1String(QT4_BC_ID);
788 BuildConfiguration *Qt4BuildConfigurationFactory::restore(Target *parent, const QVariantMap &map)
790 if (!canRestore(parent, map))
792 Qt4BaseTarget *target = static_cast<Qt4BaseTarget *>(parent);
793 Qt4BuildConfiguration *bc = new Qt4BuildConfiguration(target);
794 if (bc->fromMap(map))
800 void Qt4BuildConfiguration::importFromBuildDirectory()
802 QString directory = buildDirectory();
803 if (!directory.isEmpty()) {
804 QString mkfile = directory;
805 if (makefile().isEmpty())
806 mkfile.append("/Makefile");
808 mkfile.append(makefile());
810 QString qmakePath = QtVersionManager::findQMakeBinaryFromMakefile(mkfile);
811 if (!qmakePath.isEmpty()) {
812 QtVersionManager *vm = QtVersionManager::instance();
813 QtVersion *version = vm->qtVersionForQMakeBinary(qmakePath);
815 version = new QtVersion(qmakePath);
816 vm->addVersion(version);
819 QPair<QtVersion::QmakeBuildConfigs, QString> result =
820 QtVersionManager::scanMakeFile(directory, version->defaultBuildConfig());
821 QtVersion::QmakeBuildConfigs qmakeBuildConfig = result.first;
823 QString aa = result.second;
824 QString parsedSpec = Qt4BuildConfiguration::extractSpecFromArguments(&aa, directory, version);
825 QString versionSpec = version->mkspec();
826 QString additionalArguments;
827 if (parsedSpec.isEmpty() || parsedSpec == versionSpec || parsedSpec == "default") {
828 // using the default spec, don't modify additional arguments
830 additionalArguments = "-spec " + Utils::QtcProcess::quoteArg(parsedSpec);
832 Utils::QtcProcess::addArgs(&additionalArguments, aa);
834 Qt4BuildConfiguration::removeQMLInspectorFromArguments(&additionalArguments);
836 // So we got all the information now apply it...
837 setQtVersion(version);
839 qmakeStep()->setUserArguments(additionalArguments);
841 setQMakeBuildConfiguration(qmakeBuildConfig);
842 // Adjust command line arguments, this is ugly as hell
843 // If we are switching to BuildAll we want "release" in there and no "debug"
844 // or "debug" in there and no "release"
845 // If we are switching to not BuildAl we want neither "release" nor "debug" in there
846 bool debug = qmakeBuildConfig & QtVersion::DebugBuild;
847 bool haveTag = !(qmakeBuildConfig & QtVersion::BuildAll);
848 QString makeCmdArguments = makeStep()->userArguments();
849 Utils::QtcProcess::ArgIterator ait(&makeCmdArguments);
851 if (ait.value() == QLatin1String("debug")) {
852 if (!haveTag && debug)
856 } else if (ait.value() == QLatin1String("release")) {
857 if (!haveTag && !debug)
864 ait.appendArg(QLatin1String(debug ? "debug" : "release"));
865 makeStep()->setUserArguments(makeCmdArguments);
870 BuildConfiguration::BuildType Qt4BuildConfiguration::buildType() const
872 if (qmakeBuildConfiguration() & QtVersion::DebugBuild)